Answers · Putting a model into service
Why does the model return JSON wrapped in extra text when I asked for JSON?
In shortA request for JSON does not force the model to return only JSON, so you need to validate the reply and repair it once rather than assume it will parse.
It wraps the JSON because a request for a shape is text in the prompt, not a constraint on the next token; the model can still emit a sentence before the opening brace or a code fence around it. The reliable cure is a strict validator and exactly one repair attempt that hands back the broken reply with the specific complaint, not a firmer request for cleanliness.
A request is not a constraint
An instruction such as 'Reply with exactly this shape and nothing else' narrows the distribution of possible replies, but it does not set the probability of a wrapper to zero. Models are trained on conversations where an answer is introduced, so 'Here is the JSON you asked for:' is a plausible continuation even when the instruction says not to introduce it. A code fence is another wrapper of the same kind. The specification should still be given, and it should be a named shape with one filled example, because the example settles details that a field description leaves open: whether a missing identifier is null or an empty string, whether numbers are quoted, and whether the summary is a sentence or a phrase. But the example is doing two jobs, and only one of them is specification. It also makes the desired output more likely, which is not the same as making it certain.
What one retry has to fix
Let be the share of answers that arrive broken and the share you are willing to leave broken. A repair pass has to fix of them. At and , , so : one retry has to recover eighty per cent of the broken replies. That is the regime where a single retry with the specific complaint is worth building. At the same tolerance gives and , so the retry would have to recover ninety six per cent. No ordinary retry does that, and the answer is to simplify the shape rather than to ask again more firmly. Complexity matters because every field and every optional branch is another way to be wrong. In the illustrative curves used for this calculation, a flat record breaks at about and a nested shape with optional fields at about . At fields the flat rate is , or 2.4 per cent, and the nested rate is times , which is , or 4.992 per cent. At the flat rate is , or 4.8 per cent, and the nested rate is times , which is , or 15.168 per cent. The gap is the finding: the same information arranged with optional nested parts fails much more often. If a nested shape is genuinely needed, the usual repair is two calls, each asking for a flat part, rather than one call asking more insistently for the nested whole.
| way to handle it | recovers the answer | costs another call | risks a wrong answer |
|---|---|---|---|
| ask again with no explanation | yes | yes | no |
| ask again with the specific complaint | yes | yes | no |
| parse loosely and guess the missing field | yes | no | yes |
| fail the request and record it | no | no | no |
The natural guess is that a firmer instruction, or a regular expression that strips everything outside the first brace and the last, is enough. The firmer instruction is not useless, but it changes the break rate rather than eliminating it, and the arithmetic above is about what remains. The loose parse is the dangerous one. If the reply has no urgency field and the parser fills in three, or if it finds the word billing somewhere in a rambling sentence and calls that the category, the program has converted a visible failure into an invisible wrong answer. That is worse than a failed request because it looks like success and enters the rest of the system as data. A wrapper can be removed safely only when the removal is part of a strict parse that still checks the fields and the allowed values. If the parse has to guess, it has stopped validating and started inventing.
Where it stops, and what it does not check
The mechanism stops being enough when is high enough that approaches one. At the repair would need to fix ninety six per cent of failures, which is beyond a single retry; the right move is a simpler shape, or two flat calls, not a longer complaint. It also stops being a content check. A reply can be perfectly formed and still be wrong: the category can be one of the allowed words and be the wrong category, the urgency can be a whole number from one to five and be badly judged, and an identifier can match the expected pattern exactly while referring to an order that does not exist. Any field that refers to something real has to be checked against the real records before it is used. Validating the shape catches a missing field and a value outside the allowed set; checking fields against the records catches an identifier that does not exist; a sample read by a person is what catches a plausible but wrong category. Those are separate checks with separate costs, and the structural check gives the most false comfort on the identifier case because the shape is exactly right.
Worth keeping
- A shape request reduces the chance of broken output but does not remove it.
- One retry with the specific complaint is the repair; a loose parser that guesses missing fields turns a visible failure into a hidden wrong answer.
- Validating the shape is not validating the content: a well formed identifier can still refer to an order that does not exist.
Where this goes next
This question is one step of Writing What the Model Reads, a course that works through its subject from the beginning. The page that teaches this part of it is Asking for a Shape, and it reads the whole way through whether or not you have an account.
What an account changes is the practice: problems standing under every idea, marked with a reason rather than a tick, in a copy of the course that is yours.
Read that pageThe whole courseOther questions people ask about this
- How do I make the model answer from the documents I give it instead of its own memory?Fence the documents as labelled reference material, put them before the question, tell the model to prefer them over memory, and require a passage number for each claim.
- What does the model actually see when I send a prompt?It sees one assembled string: your typed prompt is a small clause near the end of a document that code stitched together from instructions, examples, retrieved passages and earlier turns.
- How can I tell if a prompt change actually helped or if I just got a lucky answer?Compare two versions on the same written set of cases, before and after, and call a change real only when it beats the wobble of that set.
- How do I stop a retrieved document from being read as an instruction?You cannot stop it completely, but fencing each passage in a labelled block, with a line saying it is information to use and not instruction to follow, makes the model far less likely to obey it.
- Why do the numbers look good while users keep complaining?Because the score measures a fixed set of cases with a fixed rule, and the users are living through behaviour that the set and the rule never covered.
- Why does the memory used by a model keep growing as the conversation gets longer?The model's weights do not grow. It keeps a cache of keys and values for every earlier token, so memory rises with conversation length and with how many conversations run at once.