Asking a model nicely to return JSON fails in predictable ways. The common outputs are a missing closing brace, an extra field the model invented, a string where you wanted a number, a trailing comma, or JSON followed by a chatty explanation (Brenndoerfer on constrained decoding). Those are not model bugs. Each token is sampled from a distribution, and nothing in an unconstrained sampler knows that a closing brace is due three tokens from now.
The fix is to change the sampling, not the wording of the prompt. That is what "structured outputs" means in a modern API: the provider compiles your JSON Schema into a constraint and masks any token that would break it, so invalid continuations get probability zero (ZeroEntropy's constrained decoding explainer). The model's relative preferences among legal tokens are preserved, but illegal tokens simply cannot be emitted.
This has an important consequence for schema design. Once the format is enforced for you, your job stops being "write a prompt that begs for JSON" and becomes "write a schema that encodes the right decision." The OpenAI structured outputs guide puts the benefit plainly: no need to validate or retry incorrectly formatted responses, and model refusals become programmatically detectable instead of hiding inside prose.
The catch is that schema enforcement is not universal. Vellum's comparison of the major providers notes that support for standalone structured outputs varies, and some providers only offer schema-constrained output through function calling rather than a final-response format (Vellum on function calling vs structured outputs). If you run open-weight models, vLLM exposes the same idea through guided_json, guided_choice, guided_regex and guided_grammar parameters that restrict generation to a schema, a choice set, a regex or a context-free grammar (HPE on structured outputs in vLLM). Your schema design should survive all of these paths.



