4.2 Structured Output with Tool Use
Structured Output คืออะไร
Structured Output คือเทคนิคบังคับให้ Claude return ข้อมูลในรูปแบบ JSON ที่เรากำหนด — โดยใช้ tool_use mechanism ให้ Claude “เรียก tool” ที่จริงๆ แล้วเป็นแค่ schema สำหรับ output ไม่ได้ execute อะไร pattern นี้ guarantee ว่า output จะ match schema ที่ต้องการ
The Pattern
import anthropic
client = anthropic.Anthropic()
# Define "tool" that's actually an output schema
tools = [{
"name": "structured_output",
"description": "Output the analysis results in structured format",
"input_schema": {
"type": "object",
"properties": {
"sentiment": {
"type": "string",
"enum": ["positive", "negative", "neutral"]
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"key_topics": {
"type": "array",
"items": {"type": "string"}
},
"summary": {
"type": "string",
"maxLength": 200
}
},
"required": ["sentiment", "confidence", "key_topics", "summary"]
}
}]
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
tool_choice={"type": "tool", "name": "structured_output"},
messages=[{"role": "user", "content": f"Analyze this review: {review_text}"}]
)
# Extract structured data
result = response.content[0].input # JSON object matching schema
print(result["sentiment"]) # "positive"
print(result["confidence"]) # 0.92
Key: tool_choice Forces Output
tool_choice: {"type": "tool", "name": "structured_output"} บังคับให้ Claude ต้อง “call” tool นี้ — ซึ่งหมายความว่า output จะ match schema เสมอ ไม่มีทาง return free-text
Schema Design Tips
# ดี — specific types, enums, constraints
{
"severity": {"type": "string", "enum": ["low", "medium", "high", "critical"]},
"score": {"type": "integer", "minimum": 1, "maximum": 10},
"tags": {"type": "array", "items": {"type": "string"}, "maxItems": 5}
}
# ไม่ดี — too loose
{
"severity": {"type": "string"}, # Claude อาจ return อะไรก็ได้
"score": {"type": "number"}, # อาจเป็น float, negative, etc.
"tags": {"type": "array"} # items เป็นอะไรก็ได้
}
Validation and Retry
def get_structured_output(prompt, schema, max_retries=3):
for attempt in range(max_retries):
response = client.messages.create(
tools=[{"name": "output", "input_schema": schema, "description": "..."}],
tool_choice={"type": "tool", "name": "output"},
messages=[{"role": "user", "content": prompt}]
)
result = response.content[0].input
# Additional validation beyond schema
if validate_business_rules(result):
return result
# Retry with feedback
prompt += f"\nPrevious output was invalid: {get_validation_error(result)}. Please fix."
raise ValueError("Failed to get valid output after retries")
Exam Tips
tool_choice: {"type": "tool", "name": "X"}= force structured output via tool call- Schema validation happens at API level — Claude ต้อง match schema
- ใช้
enumเพื่อ constrain string values - ใช้
requiredเพื่อ guarantee fields exist - ข้อสอบอาจถามว่า tool_choice ค่าไหนใช้สำหรับ structured output — ตอบ:
{"type": "tool", "name": "tool_name"} - Pattern นี้ไม่ได้ execute tool จริง — แค่ใช้ mechanism เพื่อ force JSON output