Can Another Program Use Botie’s Answer?
A technician can read a paragraph, but an application needs agreed fields. Check the response structure without confusing a valid record with a correct diagnosis.
13 sections · 4 questions · 1 coding challenge
The arrow keys move between sections too.
Programs Needed a Shared Description of Valid Data
BOTIE
A generated answer has the same interface problem. We will build a small explicit validator and keep its result separate from an asset lookup. This is a teaching subset of validation, not an implementation of the full JSON Schema standard.
Sources for this history
The Answer Looks Sensible. Which Part Is the Asset ID?
Botie replies, “P-2 probably needs its seal checked.” A technician can understand the sentence. A program that sorts inspection suggestions now has to guess where the asset ID ends and the recommendation begins. Another response might use an entirely different sentence.
We can ask for named fields and validate them before the next component uses them. This solves a problem about the shape of the answer. Whether a seal inspection is justified still depends on the evidence.
The browser runs ordinary Python against invented records. No provider is contacted, and no language model is trained or sampled.
Step 1 of 2
Follow one answer through separate checks
A record can pass one check and fail the next.
| Response | Exact fields and text values? | Asset in registry? |
|---|---|---|
| {"asset":"P-2","diagnosis":"seal wear"} | Yes | Yes |
| {"asset":"P-9","diagnosis":"seal wear"} | Yes | No |
| {"asset":"P-2","diagnosis":7} | No | Yes |
{"asset":"P-2","diagnosis":"seal wear"}
- Exact fields and text values?
- Yes
- Asset in registry?
- Yes
{"asset":"P-9","diagnosis":"seal wear"}
- Exact fields and text values?
- Yes
- Asset in registry?
- No
{"asset":"P-2","diagnosis":7}
- Exact fields and text values?
- No
- Asset in registry?
- Yes
Step 2 of 2
An answer becomes a candidate record
Each stage has a different failure to report.
- 1
Parse
Can this text be read as JSON? - 2
Validate
Does it match our response contract? - 3
Check evidence
Does the source support the claim? - 4
Review
May this suggestion proceed?
Keep shape checks separate from evidence
Separate branches expose which requirement failed. A valid diagnosis field can still contain an unsupported statement.
Which check rejects this response?
Try a known asset, an unknown asset, and a response whose diagnosis has the wrong type. The two output flags answer different questions.
BOTIE
[schema_valid, asset_known]
- 0true
- 1true
Follow the operations
1. Candidate response record
{ "asset": "P-2", "diagnosis": "seal wear" }2. Required field names
- 0asset
- 1diagnosis
3. Check exact field names
true
4. Read a record field
P-2
5. Check nonempty text
true
6. Read a record field
seal wear
7. Check nonempty text
true
8. Require both checks
true
9. Require both checks
true
10. Known asset IDs
- 0P-2
- 1P-3
11. Check membership
true
12. Keep two results in order
- 0true
- 1true
13. Result
- 0true
- 1true
This is a small hand-built validator for supplied records. It does not parse model text or check clinical, mechanical, or factual correctness.
1. Agree on the fields before generating them
For this exercise, a response is an object with exactly two fields: asset and diagnosis. Each must contain nonempty text. That is a deliberately small interface. In a real maintenance assistant we might also require source IDs, an uncertainty status, and the document version used.
An object maps names to values. In Python, a dictionary is the structure we will use for that mapping. Names avoid relying on word order or position in a sentence. They also let a validator point to a particular missing or malformed value.
An empty diagnosis is rejected here. Another application could permit null for an explicitly unknown diagnosis, but it must define what null means.
2. Parsing and validation answer different questions
Parsing converts a JSON string into a Python value. A valid JSON string could describe a list, a number, or an object with unexpected fields. The parser does not know which of these our application requires.
Validation checks the parsed value against our contract. Does it have exactly the expected keys? Is each value text? Does the text contain something other than whitespace? We keep these checks explicit so a reader can see what they establish. Some libraries convert values while validating; strict validation may be preferable when a number should not silently become an identifier.
Malformed JSON is a parsing error. A diagnosis containing a number is a schema error. Report the distinction when it helps someone repair the response.
A parsed value can still have the wrong type
json.loads returns a dictionary here, but the diagnosis value is an integer. Inspecting the value type reveals the problem.
import json
reply = json.loads('{"asset":"P-2","diagnosis":7}')
print(type(reply).__name__)
print(isinstance(reply["diagnosis"], str))dict
FalseThe parser succeeded. The application still needs to reject this value under the stated text-only contract.
3. Build the contract from independent checks
Our exact-key check rejects a missing field and an unexpected field. The two text checks reject numbers, nulls, and blank strings. Join those checks with logical and: all must pass.
We intentionally do not coerce a diagnosis of 7 into the string “7”. That would hide a response that did not follow the requested meaning. Keeping the checks separate also makes the workshop easier to inspect: disconnect the text branch and the numeric diagnosis case exposes the missing validation.
Required keys = {asset, diagnosis}
Schema valid = exact keys AND nonempty asset text AND nonempty diagnosis textThe resulting flag describes this contract only. It does not promise compliance with a larger schema that we never checked.
Check yourself
Questions on Parts 1 to 3
Question 1 of 2
Which stage finds the problem after this record is parsed?
Use the information below.
The required response is exactly {asset: nonempty text, diagnosis: nonempty text}. The candidate is {asset: "P-2", diagnosis: 7}.4. A valid string can describe the wrong pump
Suppose asset is “P-9” and diagnosis is “seal wear”. Both values are text, and the keys are correct. If the registry contains only P-2 and P-3, the asset lookup should fail. That is an application-level check using external knowledge.
Even a registered P-2 may have a healthy seal. The source might discuss a different symptom or describe a general possibility rather than a finding. To check factual support, compare the claim with the cited evidence and the scope of the question. The schema cannot do that for us.
The workshop returns schema_valid and asset_known separately. That makes it possible to see a structurally valid response about an unavailable asset.
5. Handle refusal and incomplete generation explicitly
A provider may refuse a request or stop before a complete answer is available. A network error may return no model output at all. These cases should not be passed into the diagnosis parser as though they were ordinary candidate records.
When a schema check fails, a bounded retry can tell the model which field needs repair. Keep the original error and response for permitted debugging. A retry is another model request with cost and latency; it is not evidence that the eventual answer is factual. If the retry limit is reached, return a clear failure state.
Provider features for constrained generation differ. Check their supported schema subset and failure modes instead of assuming every JSON Schema keyword is enforced.
6. Change a contract without surprising its callers
Imagine adding urgency next month. An old caller expecting exactly two keys may reject the new record. A new caller may require urgency and reject old saved answers. Version the interface or arrange a compatibility period deliberately.
Use test records from both versions when changing the validator. Include values at the boundary, such as an empty string, a missing field, and an unfamiliar asset. These cases often explain an integration failure more clearly than a long successful example.
The following Python function returns both check results and leaves the caller to decide what to show. It performs no scheduling action.
Check yourself
Questions on Parts 1 to 6
Question 1 of 2
Which check is still failing?
Use the information below.
A response has the right fields, cites M2, and names a registered asset. M2 says nothing about seal wear.Try it with Botie
Build with Botie
Write and run Python