20%

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