When you need Claude to return structured data (not prose), use the tool use pattern to guarantee valid JSON output.
The Technique
Define a “tool” that’s really just your output schema. Force Claude to use it:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tool_choice={"type": "tool", "name": "extract_data"},
tools=[{
"name": "extract_data",
"description": "Extract structured data from the text",
"input_schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"topics": {"type": "array", "items": {"type": "string"}}
},
"required": ["name", "email", "sentiment", "topics"]
}
}],
messages=[{
"role": "user",
"content": "Extract info from this email: 'Hi, I'm Jane (jane@co.com). Love the new dashboard!'"
}]
)
# The response is always valid JSON matching your schema
data = response.content[0].input
Why This Beats “Respond in JSON”
- Guaranteed valid JSON: no markdown wrapping, no extra text
- Schema-validated: Claude must match your types and required fields
- Enum enforcement: restrict values to a known set
- No parsing failures: the response is already structured
When to Use
- Data extraction pipelines
- Classification tasks
- API response generation
- Any time you’d otherwise regex/parse Claude’s output