FromZero2AI
CoursesPlaygroundBlog
Support on Ko-fi
Structured Outputs & AI API Design • Module A: Structured GenerationLesson 1: JSON Mode, Instructor & Pydantic Integration
Next

Lesson 1: JSON Mode, Instructor & Pydantic Integration

Force LLMs to output valid, schema-validated JSON every time using Anthropic's tool-use JSON mode and the Instructor library. Define Pydantic models as your output schema and get type-safe responses.

Built with AI for beginners. Free forever.

Support on Ko-fi•About•Blog•Privacy Policy•Terms of Service

Production AI systems rarely work with raw text. They extract structured data, return typed API responses, and populate databases. Structured outputs enforce a schema at the LLM boundary so the rest of your system can rely on typed, validated data.

Reliability Comparison

Native JSON
~95%

Occasionally outputs markdown or prose. Needs try/except.

Tool Use + Pydantic
~99.5%

Model required to call the tool. Schema-enforced. Recommended.

Instructor
~99.9%

Auto-retries on validation failure. Best for production.

Native JSON Mode: Ask the model to output JSON directly. Simplest approach — but requires manual parsing and no schema validation.

import anthropic
import json

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-haiku-4-5-20251001",
    max_tokens=500,
    messages=[{
        "role": "user",
        "content": """Extract the following fields from this product description and return as JSON:
{
  "name": string,
  "price_usd": number,
  "in_stock": boolean,
  "tags": string[]
}

Product: "The XB-500 Pro wireless headphones are $79.99 and currently available.
Great for gaming and music. Wireless, noise-cancelling."

Return only valid JSON, no explanation.""",
    }],
)

try:
    data = json.loads(response.content[0].text)
    print(data)
    # {'name': 'XB-500 Pro', 'price_usd': 79.99, 'in_stock': True, 'tags': ['wireless', 'gaming']}
except json.JSONDecodeError as e:
    print(f"Model didn't return valid JSON: {e}")
    # This happens ~5% of the time — requires retry logic

Schema Design Rules

Use enums over free strings"positive" | "negative" | "neutral" beats str — prevents hallucinated values like "very positive".
Add Field(description=...) to every fieldThe description goes into the tool schema — the model reads it. Vague descriptions → wrong values.
Set max_items on list fieldsUnconstrained lists can have 0 or 100 items. Bound them to what your downstream code can handle.
Use ge= / le= on numeric fieldsA sentiment score of 99.7 is probably wrong. Pydantic will catch it and trigger a retry.

Never trust raw LLM JSON in production without validation.Even when JSON mode is active, models can return numbers as strings, omit optional fields, or hallucinate extra fields. Always run Pydantic validation — treat the model output as external input, same as user data.

Lesson 2 covers streaming APIs — how to return structured output incrementally so users see partial results while the full response is still generating.