JSON Schema and Structured Output
Phase 10 · Document 02 · Agents and Tools Prev: 01 — Tool Calling · Up: Phase 10 Index
Table of Contents
- Why This Matters
- Core Concept
- Mental Model
- Hitchhiker's Guide
- Warmup Readings
- Deep Readings and External References
- Key Terms
- Important Facts
- Observations from Real Systems
- Common Misconceptions
- Engineering Decision Framework
- Hands-On Lab
- Verification Questions
- Takeaways
- Artifact Checklist
1. Why This Matters
Agents and automation need the model to emit machine-readable, schema-conformant output — tool arguments, extracted fields, classifications, plans — not prose. Structured output (and its language, JSON Schema) is what makes a model's output parseable and reliable enough to feed into code. It underpins tool calling (01) — tool arguments are schema-constrained JSON — and every data-extraction/automation pipeline. The crucial, hard-won lesson a senior engineer must internalize: constrained output guarantees the shape, never the correctness. A model can return perfectly valid JSON with wrong values. Confusing "valid JSON" with "correct answer" causes silent, confident data corruption — so structured output must always be paired with validation and often evaluation (Phase 5.07, 09).
2. Core Concept
Plain-English primer: tell the model the exact shape, and enforce it
By default a model emits free text; parsing that reliably is fragile. Structured output makes the model produce output conforming to a schema you specify — almost always JSON Schema, the standard for describing JSON shape (types, required fields, enums, nesting, constraints).
{ "type": "object",
"properties": {
"sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"] },
"score": { "type": "number", "minimum": 0, "maximum": 1 },
"entities": { "type": "array", "items": { "type": "string" } }
},
"required": ["sentiment", "score"],
"additionalProperties": false }
JSON Schema is the same language used for tool parameters (01) — a tool call is just structured output where the "schema" is the tool's parameters. Master JSON Schema once and you've mastered both.
Three levels of "structured" (weak → strong guarantee)
- Prompted JSON — you ask for JSON in the prompt ("respond as JSON with fields …"). Easy, but the model can still emit invalid JSON, extra prose, or wrong fields. Always validate + retry.
- JSON mode — the provider guarantees syntactically valid JSON (it won't return broken JSON), but not that it matches your schema. Better, still validate the shape.
- Constrained decoding / Structured Outputs (strict schema) — the provider constrains the model's token sampling to your exact JSON Schema (OpenAI Structured Outputs, Anthropic tool-use schemas, Gemini response schemas, or open-source grammar-constrained decoders like Outlines/
llama.cppGBNF/XGrammar). Output is guaranteed to conform to the schema — valid JSON and the right fields/types/enums.
How constrained decoding works (the mechanism)
Recall generation samples one token at a time from a distribution (what-happens §1.C). Constrained decoding compiles your schema into a grammar/state machine and, at each step, masks out tokens that would violate the schema before sampling — so the only tokens the model can emit keep the output valid. The result provably matches the schema's structure. It's the same idea behind grammar-constrained decoding (GBNF, XGrammar) and library tools (Outlines, Instructor). This guarantees shape, not meaning.
The crucial limit: constrained ≠ correct
This is the senior insight: a guaranteed-valid schema tells you the JSON is well-formed, not that the values are right. The model can return {"sentiment":"positive","score":0.9} for a clearly negative review — valid, conformant, and wrong. Constraining the grammar can even mask a model that "wanted" to refuse or hedge, forcing a confident-but-wrong value. So:
- Validate shape (schema) — necessary, cheap, do it always.
- Validate values (business rules: ranges, referential integrity, plausibility) — catch impossible/contradictory values your schema can't express.
- Evaluate correctness (golden set / judge) — the only way to know values are right (09, Phase 9.09).
Designing good schemas for accuracy
The schema shapes not just validity but quality:
- Enums over free strings for categories (the model can't drift).
- Constraints (
minimum/maximum,pattern,format) catch impossible values. additionalProperties: false+requiredto forbid stray/missing fields.- Field descriptions — the model reads them; describe what each field means (like tool descriptions, 01).
- Flat-ish, named fields beat deeply nested or positional structures.
- Reasoning-then-structure: if you need the model to think, give it a
reasoningfield before the answer fields (or do a reasoning pass first) — constraining too early can hurt quality on hard tasks.
Where it's used
- Tool arguments (01) — the most common structured output.
- Data extraction — invoices, resumes, entities → typed records.
- Classification / routing — enum labels for pipelines.
- Plans / agent state — structured steps the executor consumes (03).
- Citations — claim→source as structured JSON (Phase 9.08).
3. Mental Model
JSON SCHEMA = the contract (types · enum · required · min/max · additionalProperties:false · descriptions)
same language as TOOL PARAMETERS [01]
THREE LEVELS (weak→strong):
prompted JSON (ask) → JSON mode (valid JSON, any shape) → CONSTRAINED DECODING (your exact schema)
constrained = compile schema → grammar/state-machine → MASK invalid tokens each step → guaranteed shape
★ CONSTRAINED ≠ CORRECT: valid JSON can hold WRONG values (confident + conformant + wrong)
→ validate SHAPE (schema) + validate VALUES (business rules) + EVALUATE correctness [09]
design for accuracy: enums · constraints · descriptions · reasoning-field-before-answer
Mnemonic: JSON Schema is the contract; constrained decoding enforces the shape by masking invalid tokens — but shape ≠ correctness, so always validate values and evaluate.
4. Hitchhiker's Guide
What to look for first: do you need a guaranteed shape? If yes, use constrained/Structured Outputs (strict schema), not prompted JSON. Then add value validation — because shape ≠ correctness.
What to ignore at first: hand-rolling grammars and exotic schema features. Use the provider's strict-schema mode (or a library like Instructor/Outlines) with a clean schema.
What misleads beginners:
- "Valid JSON = correct answer." The core trap — constrained output can be confidently wrong; validate values and evaluate (09).
- Prompted JSON in production. It returns invalid JSON/extra prose often enough to break pipelines — use strict mode + retry.
- Over-constraining hard tasks. Forcing structure too early can hurt reasoning; allow a reasoning step/field first.
- Vague field semantics. Missing descriptions → the model fills fields wrong (same as vague tool schemas, 01).
- No
additionalProperties:false/required. Lets stray or missing fields through.
How experts reason: they pick the strongest guarantee available (constrained Structured Outputs), design enum/constrained/described schemas, validate shape and values, and evaluate value-correctness on a golden set — never trusting conformance as correctness. For hard tasks they let the model reason first, then emit the structured answer.
What matters in production: schema-conformance rate (→ ~100% with constrained decoding), value-accuracy (the real metric, measured by eval), parse/validation failure handling, and not letting constrained output mask refusals/uncertainty.
How to debug/verify: if downstream breaks, check (1) is output schema-valid (use strict mode)? (2) are values correct (eval against gold)? (3) did over-constraining hurt quality (try reasoning-first)? Log conformance and value-accuracy separately.
Questions to ask: does the provider offer strict-schema constrained output? do I validate values, not just shape? do I evaluate value-accuracy? could constraining be masking a refusal/low-confidence case?
What silently gets expensive/unreliable: trusting valid JSON as correct (silent data corruption), prompted-JSON parse failures, over-constrained reasoning (worse answers), and unvalidated values flowing downstream.
5. Warmup Readings
| Title | Why to read it | What to extract | Difficulty | Time |
|---|---|---|---|---|
| 01 — Tool Calling | Tool args are structured output | schemas drive calls | Beginner | 20 min |
| Phase 5.07 — Structured-Output Models | Constrained ≠ correct | shape vs values | Beginner | 20 min |
| what-happens §1.C — forward pass | Token sampling (what constraining masks) | logits → token | Beginner | 10 min |
| JSON Schema basics | The schema language | types/enum/required | Beginner | 20 min |
6. Deep Readings and External References
| Title | URL | Why it matters | Read first | Lab connection |
|---|---|---|---|---|
| OpenAI Structured Outputs | https://platform.openai.com/docs/guides/structured-outputs | Strict-schema guarantee | json_schema, strict | This lab |
| Anthropic tool use (schemas) | https://docs.anthropic.com/en/docs/build-with-claude/tool-use | Schema-constrained args | input_schema | Tool args |
| Outlines | https://github.com/dottxt-ai/outlines | Open grammar-constrained decoding | regex/JSON/grammar | Self-host constrain |
| Instructor | https://github.com/instructor-ai/instructor | Pydantic-validated structured output | response_model | Validation lab |
| JSON Schema spec | https://json-schema.org/ | The contract language | core + validation | Schema design |
7. Key Terms
| Term | Simple meaning | Technical meaning | Why it matters | Where it appears | How to use it |
|---|---|---|---|---|---|
| Structured output | Machine-readable answer | Schema-conformant output | Parseable/automatable | agents/extraction | Use strict mode |
| JSON Schema | Shape contract | Types/required/enum/constraints | The language | tools/output | Design carefully |
| Prompted JSON | Ask for JSON | Prompt-only, no guarantee | Fragile | weak level | Validate + retry |
| JSON mode | Valid-JSON guarantee | Syntactic validity only | Better, not enough | provider | Still validate shape |
| Constrained decoding | Schema-enforced | Mask invalid tokens via grammar | Guaranteed shape | Structured Outputs | Strongest guarantee |
| Constrained ≠ correct | Shape not meaning | Valid JSON, wrong values | The core trap | everywhere | Validate values + eval |
| Value validation | Check the values | Business rules/ranges | Catch impossible vals | post-parse | Always |
additionalProperties | Forbid extras | Disallow unknown fields | Strictness | schema | Set false |
8. Important Facts
- JSON Schema is the contract for structured output — and the same language as tool parameters (01).
- Three levels: prompted JSON (no guarantee) < JSON mode (valid JSON, any shape) < constrained decoding (your exact schema, guaranteed).
- Constrained decoding masks schema-violating tokens each step, so output provably matches the schema's shape (what-happens §1.C).
- Constrained ≠ correct — valid, conformant JSON can hold wrong values; this is the central pitfall (Phase 5.07).
- Always validate shape (schema) AND values (business rules); evaluate value-accuracy on a golden set (09).
- Schema design drives quality: enums, constraints,
additionalProperties:false/required, and field descriptions. - Over-constraining hard tasks can hurt quality — let the model reason first, then emit structure.
- Tools: OpenAI Structured Outputs, Anthropic tool schemas, Gemini response schemas; open-source Outlines/Instructor/GBNF/XGrammar.
9. Observations from Real Systems
- Tool calling is the most common structured output — every agent relies on schema-constrained arguments (01).
- OpenAI Structured Outputs / Anthropic tool schemas give ~100% conformance — teams moved off fragile prompted-JSON for reliability (Phase 5.07).
- The classic incident: a pipeline trusts valid JSON and silently ingests wrong values for weeks — caught only by value validation/eval (09).
- Instructor (Pydantic) and Outlines (grammars) are popular for validated/constrained output in self-hosted and API stacks.
- Reasoning-then-structure (a
reasoningfield or a two-pass approach) is a common fix when strict schemas hurt hard-task accuracy.
10. Common Misconceptions
| Misconception | Reality |
|---|---|
| "Valid JSON means correct" | Shape ≠ values; validate values + evaluate |
| "Prompted JSON is fine" | Fragile; use strict/constrained + retry |
| "JSON mode = my schema" | JSON mode = valid JSON, any shape; constrain for your schema |
| "Constrain everything tightly always" | Over-constraining can hurt reasoning; reason first |
| "Descriptions don't matter in schemas" | The model reads them to fill fields |
| "Structured output is just for tools" | Also extraction, classification, plans, citations |
11. Engineering Decision Framework
NEED MACHINE-READABLE OUTPUT?
1. STRENGTH: need a guaranteed shape? → CONSTRAINED/Structured Outputs (strict schema).
quick/low-stakes? → prompted JSON + validate + retry (weakest).
2. SCHEMA DESIGN: enums for categories · constraints (min/max/pattern) · additionalProperties:false +
required · clear field DESCRIPTIONS · flat-ish.
3. HARD TASK? allow REASONING first (reasoning field / pre-pass) before constraining the answer.
4. VALIDATE SHAPE (schema) — always; on failure, retry/repair.
5. VALIDATE VALUES (business rules: ranges, referential integrity, plausibility).
6. EVALUATE value-accuracy on a golden set — conformance ≠ correctness. [09]
| Use case | Approach |
|---|---|
| Tool arguments | Provider tool schema (constrained) [01] |
| Data extraction | Strict JSON Schema + value validation |
| Classification/routing | Enum schema (constrained) |
| Agent plan/state | Structured plan schema [03] |
| Hard reasoning + structure | Reason first, then constrained answer |
12. Hands-On Lab
Goal
Prove constrained ≠ correct: get guaranteed-valid output, then show valid-but-wrong values, and add value validation + eval.
Prerequisites
pip install openai pydantic(orinstructor/outlines); a small extraction/classification task with a few known-answer examples.
Steps
- Prompted JSON (baseline): ask for JSON in the prompt; over 20 runs, measure how often it returns invalid/unparseable JSON or extra prose.
- Constrained Structured Outputs: define a strict JSON Schema (enums, constraints,
additionalProperties:false, descriptions) and use the provider's Structured Outputs / strict mode (or Instructor/Outlines). Re-measure conformance — expect ~100% valid. - The core lesson: on a clearly-labeled set (e.g., obviously-negative reviews), measure value-accuracy of the constrained output. Show that conformance is ~100% but value-accuracy is lower — valid JSON, sometimes wrong values.
- Value validation: add business-rule checks (e.g.,
scoreconsistent withsentiment, enum within allowed set, referential checks); flag impossible/contradictory records the schema couldn't catch. - Reasoning-first: add a
reasoningfield before the answer (or a pre-pass); re-measure value-accuracy on hard cases — expect improvement vs constraining immediately. - Eval: compute conformance rate and value-accuracy separately on the golden set (09).
Expected output
A table separating conformance (~100% with constrained) from value-accuracy (lower), demonstrating constrained ≠ correct, plus value-validation catches and a reasoning-first improvement.
Debugging tips
- Conformance < 100% with "strict" → not actually using constrained mode, or schema not strict.
- Value-accuracy low → it's a model/prompt/reasoning problem, not a schema one; constraining won't fix values.
Extension task
Implement the same schema with Instructor (Pydantic) and Outlines (grammar); compare ergonomics and self-hosted vs API constrained decoding.
Production extension
Wire structured output into a tool/extraction pipeline with shape + value validation gates and a value-accuracy eval in CI (09, Phase 12).
What to measure
Prompted-JSON failure rate; constrained conformance (~100%); value-accuracy (the real metric); value-validation catches; reasoning-first uplift.
Deliverables
- A conformance vs value-accuracy comparison (the constrained ≠ correct lesson).
- A strict JSON Schema + value-validation rules.
- A reasoning-first improvement on hard cases.
13. Verification Questions
Basic
- What is JSON Schema, and how does it relate to tool parameters?
- Name the three levels of structured output, weakest to strongest.
- How does constrained decoding guarantee the shape?
Applied 4. Explain "constrained ≠ correct" with an example, and what to add because of it. 5. Why might over-constraining a hard task hurt accuracy, and what's the fix?
Debugging 6. A pipeline ingested wrong values for weeks despite valid JSON. What was missing? 7. Structured output conformance isn't 100% in "strict" mode. What do you check?
System design 8. Design an extraction pipeline with constrained output + shape + value validation + eval.
Startup / product 9. Why is "valid JSON" a dangerous proxy for "correct," and how does that affect trust in an automation product?
14. Takeaways
- JSON Schema is the contract for structured output and tool arguments alike (01).
- Prefer constrained/Structured Outputs (guaranteed shape) over prompted JSON.
- Constrained ≠ correct — valid JSON can hold wrong values; this is the central pitfall.
- Always validate shape AND values; evaluate value-accuracy on a golden set (09).
- Design schemas for quality (enums/constraints/descriptions) and reason first on hard tasks before constraining.
15. Artifact Checklist
-
A strict JSON Schema (enums, constraints,
additionalProperties:false, descriptions). - A conformance vs value-accuracy comparison (constrained ≠ correct).
- Shape + value validation gates.
- A reasoning-first variant for hard tasks.
- A value-accuracy eval wired toward CI (09).
Up: Phase 10 Index · Next: 03 — Planner-Executor