Learn AI · Foundations
Structured Outputs Explained
Structured outputs make models return valid JSON every time — no more parsing failures, no more 'almost JSON.' Here's how they work and when to use them.
Key takeaways
- 1Structured output mode forces the model to emit valid JSON matching your schema.
- 2Three implementations: OpenAI response_format, Anthropic tool use, Gemini schema parameter.
- 3The schema is also a prompt — describe each field clearly.
- 4Strict mode = guaranteed valid JSON. Use it for production data pipelines.
- 5Wrap output schema as a tool definition for cross-provider portability.
The problem they solve
You ask the model: "Extract the invoice details as JSON: { vendor, total, due_date, line_items[] }."
Without structured output, you get one of:
- Valid JSON ✅
- JSON wrapped in markdown ✨
json ... - JSON with trailing commas
- JSON missing required fields
- "Sure! Here's the data: ..." then JSON
- Pure prose, no JSON in sight
Now you write parsing code, regex extraction, retry loops, error handling. All to do something the model could've just done correctly.
Structured outputs eliminate this.
How it works
The model emits one token at a time. Structured output mode constrains the next-token distribution to only tokens that keep the output valid JSON matching your schema. The model literally cannot return malformed output.
Three flavors:
- OpenAI:
response_format: { type: "json_schema", json_schema: {...} }— strict mode guarantees validity. - Anthropic: define a tool with the schema, force tool use. Tool input is your structured output.
- Gemini:
generation_config.response_schemaparameter.
A real example
// Schema
{
"type": "object",
"properties": {
"sentiment": {
"type": "string",
"enum": ["positive", "neutral", "negative"]
},
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"key_phrases": {
"type": "array",
"items": { "type": "string" },
"maxItems": 5
}
},
"required": ["sentiment", "confidence"]
}
The model is forced to return exactly this shape. No prose, no markdown wrappers, no missing fields.
Schema as prompt
Field descriptions in the schema are part of the prompt. The model reads them. Good descriptions improve quality:
"sentiment": {
"type": "string",
"enum": ["positive", "neutral", "negative"],
"description": "Overall emotional tone of the message. Mixed = whichever side is stronger."
}
Treat schemas like you treat prompts.
When to use it
Always, when you need structured data. Specifically:
- Extracting fields from text (invoices, emails, support tickets)
- Classification with multiple outputs
- Multi-step agent state
- Anything you'd previously parse with regex
When not to use it:
- Free-form writing
- Code generation (use code blocks, not JSON-wrapped strings)
- Pure conversational chat
Common mistakes
- Schemas too deep — flat schemas are more reliable than nested ones.
- Required vs optional confusion — be explicit about what's optional.
- Reusing the same schema name with different shapes — providers cache. Version your schemas.
- Forgetting enum values — open string fields invite hallucination.
The cross-provider trick
Wrap your schema as a tool definition:
{
"name": "extract_invoice",
"description": "Extract structured fields from an invoice.",
"input_schema": { ... }
}
Then force the model to call this tool. The tool input is your structured output. This shape works on Claude, GPT, Gemini, and any open-weights model with tool support — same code, all providers.
Structured outputs are the single highest-ROI prompt engineering upgrade in production. If you're parsing model responses by hand, switch.
Common misconceptions
The wrong-but-common takes worth correcting.
Myth
I can just ask for JSON in the prompt.
Reality
Sometimes works, often doesn't. Models forget braces, add prose, hallucinate fields. Structured output mode eliminates this.
Myth
Structured output makes the model dumber.
Reality
Quality is essentially the same. The constraint is on format, not reasoning.
Myth
I need different code for each provider.
Reality
If you wrap your schema as a tool/function definition, the same shape works across OpenAI, Anthropic, Gemini, and open-weights with tool support.
Real-world use cases
Data extraction
Pull structured fields (dates, amounts, entities) from unstructured text reliably.
Classification with explanations
Return both a label and a justification in one call.
Multi-field forms
Have the model fill multi-field structured records — invoices, contacts, bug reports.
API response assembly
Generate API-ready response objects from a natural-language description.
Frequently asked questions
Related on AIKnowHub
Concept
Evals Explained
Evals are the unit tests of AI systems. Without them you're flying blind. Here's how to build a useful eval set without going overboard.
Concept
Function Calling Explained
Function calling is how LLMs trigger your code. Here's how it actually works under the hood, and how to design tools that the model uses correctly.
Concept
Prompt Engineering Basics
The actual techniques that move the needle — role priming, structured output, few-shot examples, and why specificity always wins.
Interview
Your LLM keeps returning invalid JSON for structured outputs. How do you fix it systematically?
Tests production reliability — structured outputs power agents, evals, and integrations; failures can't be hand-waved.
Tool Guide
Langfuse Guide
The definitive guide to Langfuse for LLM observability — traces, prompt versions, evals, cost tracking, self-host setup, and when to pick it over Braintrust or Phoenix.
Workflow
Build an AI Docs Chatbot
A RAG-powered chatbot that answers questions from your documentation with citations — the kind every SaaS site needs in 2026.