Overview
Structured output makes a model return data that matches a schema, usually JSON Schema, so code can parse it without regex extraction. There are three levels. A prompt that asks for a format (a “structured prompt”) is weakest; the model can still deviate. JSON mode guarantees valid JSON but not your schema, and OpenAI recommends structured outputs instead. Schema-constrained decoding guarantees the schema: Claude uses output_config: {format: {...}} (the older top-level output_format is deprecated) and strict: true on a tool definition for schema-valid tool input; OpenAI uses text.format with type: "json_schema" and strict: true. Open-weights runtimes get the same guarantee from grammar-constrained decoding (llama.cpp grammars, Outlines). Use the strongest level whenever a program reads the response.
Validate anyway. A valid schema does not make the values right. Check business rules the schema cannot express (start_date < end_date, quantity > 0) with Pydantic or Zod where the response enters your code, and on failure retry once or log, never silently fill a default. Keep schemas small, with few required fields.
On Claude 4.6 and later models, assistant-message prefill returns a 400, and so does forced tool_choice on Fable 5.1, Opus 5.5, and Sonnet 5.5; use structured outputs instead. Citations cannot be combined with output_config.format.
Example
{
"type": "object",
"properties": {
"priority": { "enum": ["P0", "P1", "P2", "P3"] },
"needs_human": { "type": "boolean" }
},
"required": ["priority", "needs_human"],
"additionalProperties": false
}ticket = Ticket.model_validate_json(response.content[0].text) # Pydantic; raises if invalidRelated
- structured-output: schema design and provider differences.
- output-constraints: prompt-level format control.
- tool-use: tool arguments are structured output too.
- few-shot-prompting: examples that show the format.
- hallucination: validation catches fabricated values.
- evaluation: exact-field scoring makes these cheap to evaluate.