What is structured output?
7 min read
·┌──────────────────────────────────────────────────────────┐ │ ═══════════════════════════════════════════════════ │ │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ ──────────────────────────────────────────────────── │ │ ██████████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ █████████████████████████████████░░░░░░░░░░░░░░░░░░ │ │ ██████████████████████████████████████░░░░░░░░░░░░░ │ │ ████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ ──────────────────────────────────────────────────── │ │ ███████████████████████████████████████░░░░░░░░░░░░ │ └──────────────────────────────────────────────────────────┘
Structured output is the ability to get AI models to return data in a specific, predictable format rather than freeform text. Instead of hoping the model responds with something you can parse, you define exactly the shape of the response you need, and the model guarantees compliance.
Why Freeform Text Is Not Always Enough
When you ask a model to "extract the name, date, and amount from this invoice," it might respond in a dozen different formats. Sometimes it uses bullet points, sometimes a paragraph, sometimes a table. If you are building an application that needs to process that data programmatically, this inconsistency is a problem.
Structured output solves this by letting you specify a schema, and the model returns valid data that matches it every time.
JSON Mode vs Structured Output with Schemas
There are two levels of structured output support:
[JSON mode] guarantees the model returns valid JSON, but it does not enforce any particular structure. You might get {"name": "John"} or {"result": {"full_name": "John"}}. The JSON is valid, but the shape is unpredictable.
[Schema-enforced structured output] goes further. You provide a JSON Schema, and the model's output is constrained to match it exactly. If your schema says the response needs a name string and an amount number, that is exactly what you get.
The difference matters enormously in production applications. JSON mode is useful for simple cases. Schema enforcement is what you want for reliable pipelines.
How It Works Under the Hood
Providers implement structured output by constraining the model's token generation process. At each step, instead of choosing from all possible next tokens, the model can only select tokens that keep the output valid according to the schema. This is called constrained decoding or grammar-based sampling.
This means the model never generates invalid output. It is not a "try and validate" approach. The constraints are enforced during generation, so every response is guaranteed to match your schema.
Schema Definition Approaches
[JSON Schema] is the universal format. You define types, required fields, enums, arrays, nested objects, and validation constraints. All major providers accept JSON Schema definitions.
[Pydantic] (Python) lets you define schemas as Python classes. Libraries like the OpenAI Python SDK and Instructor can convert Pydantic models to JSON Schema automatically. This is the most popular approach in the Python ecosystem.
[Zod] (TypeScript/JavaScript) offers the same convenience for the JS ecosystem. Define your schema with Zod, and libraries convert it to JSON Schema for you. This gives you both runtime validation and type safety.
[TypeBox, Yup, and others] also work. Anything that can produce a JSON Schema is compatible.
Provider Support
[OpenAI] offers the most mature structured output support. Their response_format parameter with json_schema type enforces strict schema compliance in GPT-4o and later models. They also support a simpler json_object mode.
[Anthropic] supports structured output through tool use. You define a tool with the desired output schema, and Claude returns the data in that shape. Anthropic also supports direct JSON output with careful prompting.
[Google] supports structured output in Gemini models through their response_schema parameter, with support for JSON Schema definitions.
[Mistral] supports JSON mode and structured output in their API, following a similar pattern to OpenAI.
[Cohere] provides structured generation capabilities in their Command models, including JSON output mode.
[Open source models] can produce structured output through libraries like Outlines, Guidance, or LMQL, which implement constrained decoding at the inference level. This works with any model, regardless of whether the provider natively supports it.
Use Cases
[Data extraction]: Pull structured data from unstructured text. Extract names, dates, addresses, and amounts from invoices, contracts, or emails into a consistent format.
[Form filling]: Convert natural language descriptions into form field values. A user says "I need a flight from New York to London next Friday, business class" and you get back a structured booking object.
[API responses]: Use AI to generate responses that match your API schema directly, ready to return to clients without transformation.
[Content classification]: Categorize text into predefined categories with confidence scores, returned in a consistent format for downstream processing.
[Configuration generation]: Have the model produce valid configuration files, database queries, or structured documents based on natural language requirements.
Best Practices
[Keep schemas simple]: The more complex the schema, the harder it is for the model to fill it correctly. Break complex outputs into smaller, focused schemas when possible.
[Use descriptions in your schema]: Add description fields to properties. These guide the model on what each field should contain. A field named priority with description "1 for urgent, 2 for normal, 3 for low" gets better results than priority alone.
[Provide enums for constrained values]: If a field should only contain certain values, use an enum. This eliminates an entire category of errors.
[Set reasonable defaults]: For optional fields, define sensible defaults so the model does not have to guess.
[Test with edge cases]: Try inputs that are ambiguous, incomplete, or unusual. See how the model handles them and adjust your schema or prompt accordingly.
[Validate even with schema enforcement]: While schema enforcement guarantees structural validity, the values themselves can still be wrong. A number field will always contain a number, but it might be the wrong number.
Relationship to Function Calling
Structured output and function calling are closely related. Function calling uses schemas to define function parameters, and the model returns structured data that matches those schemas. In Anthropic's API, structured output is actually implemented through tool use. You can think of structured output as function calling without the execution step, where the "function" is just "return data in this format."
Understanding both concepts together gives you a complete toolkit for getting reliable, programmatic output from language models.