Output You Can Trust to Parse
You wire a model into the support queue. Read the email, give back the priority as low, medium or high, a category, and the action items, all as JSON. It works. It works for a week. Then one reply comes back with a cheerful sentence sitting in front of the opening brace, and the next one calls the priority Urgent, which is not one of your three words. Something downstream throws at two in the morning. So you add a retry, then a rule that strips the friendly part, then a fallback that guesses. You are now maintaining a parser for a machine that was supposed to be talking to machines.
The paint cannot land outside the cut
Underneath, generation is a long run of small choices. The model picks one token — a word, a fragment, a comma — then looks at everything so far and picks the next. Nothing in that loop knows what a valid JSON object is. It knows what tends to follow what, which is exactly why a well-behaved format holds for a week and then stops.
Constrained decoding changes the choosing, not the model. You hand the runtime a grammar, a regular expression or a schema, and at every step it takes off the menu any token that could not lead to a valid output. Tape a stencil to a wall and spray: your hand can shake as much as it wants, and the paint that lands is inside the shape somebody cut. Broken output stops being unlikely and becomes unreachable. If the field admits one of three labels, there is no fourth word available to be picked.
What a stencil will not do is spell for you. The shape is guaranteed; the word you sprayed can still be wrong. A model that reads a furious customer as low priority will say low in perfectly valid JSON. Format and judgement are separate problems, and only one of them has been solved here.
Downstream code stops guessing what arrived
Declaring the type is the other half. Rather than asking for JSON in a sentence, you say what you expect: an integer, a closed set of labels, an object with named fields. The email comes back as a ticket with a priority, a category and its action items, and the router chooses a flow by reading a field instead of hunting through prose. That is the difference between output a person reads and output a program composes with. Declare a free-form string and you have kept the stencil while cutting a hole the size of the wall.
It changes what you are willing to leave alone. When the shape is merely likely, somebody has to stand at the end of the pipeline as the parser of last resort, and that somebody is usually a person. When the shape cannot vary, the branch runs unattended and the only thing left to review is the decision it encodes.
The same contract runs the other way, on the calls going out. A tool declares its properties, its types, its required fields, and strict mode has the provider enforce that the model’s call matches exactly: the location arrives as a string, or the call does not arrive. The client stops writing defensive code for arguments that can no longer show up. One caution at that boundary: an argument that fits the schema is not an argument you have authorised.
Check the contract before the agent does
A guarantee nobody has looked at is still a hope. Before trusting a server you connect it to an inspector — a web client, a command-line tool, a terminal interface — list what it exposes, and send calls with input you chose yourself. You see the real shape of the response and, more usefully, the shape of its errors, with no improvisation in the middle. Debugging the interface and debugging the behaviour become two jobs instead of one confusing one. The habit that costs people is checking only the happy path through a running agent: it went fine once, so it must be fine. That same inspection runs unattended, which means the contract gets checked on every change rather than on the morning it breaks.
None of this makes the model more careful. The stencil, the declared type, the enforced schema and the test call all sit outside it, and they are what turns a good habit into a property. A format you hope for is a format you have to check every time. A format that cannot come out wrong is a format you can build on.