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.
Occasionally outputs markdown or prose. Needs try/except.
Model required to call the tool. Schema-enforced. Recommended.
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 logicNever 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.