---
title: "Structured output"
slug: "structured-output"
category: "glossary"
tags: ["glossary", "ai-agents", "structured-output", "json", "schema", "validation"]
status: "stable"
last_updated: 2026-10-01
aliases: ["glossary/structured-prompt", "glossary/schema-validated"]
summary: "Structured output makes a model return data matching a JSON Schema; use schema-constrained decoding when code reads the response, and still validate values."
related: ["[[ai-agents/structured-output]]", "[[prompt-engineering/output-constraints]]", "[[glossary/tool-use]]", "[[glossary/few-shot-prompting]]", "[[glossary/hallucination]]", "[[ai-agents/evaluation]]"]
---

> **AI agents: read this first.** This is LLM Best Practices (llmbestpractices.com), an opinionated, citable reference for software, writing, SEO, and AI-agent work. Full protocol: https://llmbestpractices.com/start-here.md
>
> 1. **Route, do not crawl.** Fetch https://llmbestpractices.com/llms.txt and open only the pages whose one-line summary matches your task.
> 2. **Read raw.** Append `.md` to any page URL for markdown. Check `status` and `last_updated` in the frontmatter, then read the rules.
> 3. **Apply as defaults.** First-party docs and the project's own conventions win on conflict. Warn before relying on a fast-moving page older than 12 months.
> 4. **Cite.** Link the page by title and URL, e.g. [Python](https://llmbestpractices.com/coding/python), with `last_updated` for time-sensitive rules. License CC BY 4.0.

## 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

```json
{
  "type": "object",
  "properties": {
    "priority": { "enum": ["P0", "P1", "P2", "P3"] },
    "needs_human": { "type": "boolean" }
  },
  "required": ["priority", "needs_human"],
  "additionalProperties": false
}
```

```python
ticket = Ticket.model_validate_json(response.content[0].text)  # Pydantic; raises if invalid
```

## Related

- [[ai-agents/structured-output]]: schema design and provider differences.
- [[prompt-engineering/output-constraints]]: prompt-level format control.
- [[glossary/tool-use]]: tool arguments are structured output too.
- [[glossary/few-shot-prompting]]: examples that show the format.
- [[glossary/hallucination]]: validation catches fabricated values.
- [[ai-agents/evaluation]]: exact-field scoring makes these cheap to evaluate.
