Claude API
结构化输出
保证 Claude 输出严格符合 JSON Schema — Pydantic/Zod 集成与 Strict 工具模式
概述
结构化输出确保 Claude 的响应严格遵循指定的 JSON Schema,消除解析错误和类型不匹配。
Python + Pydantic
import anthropic
from pydantic import BaseModel
class ContactInfo(BaseModel):
name: str
email: str
company: str
plan_interest: str
demo_requested: bool
client = anthropic.Anthropic()
response = client.messages.parse(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{
"role": "user",
"content": "提取联系人信息:张三,zhang@example.com,在字节工作,对高级方案感兴趣,需要演示"
}],
output_format=ContactInfo,
)
# 类型安全的访问
contact = response.parsed_output
print(f"姓名: {contact.name}")
print(f"邮箱: {contact.email}")
print(f"公司: {contact.company}")
print(f"需要演示: {contact.demo_requested}")TypeScript + Zod
import Anthropic from "@anthropic-ai/sdk";
import { z } from "zod";
const ContactSchema = z.object({
name: z.string(),
email: z.string().email(),
company: z.string(),
plan_interest: z.string(),
demo_requested: z.boolean(),
});
const client = new Anthropic();
const response = await client.messages.parse({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{
role: "user",
content: "提取联系人信息:张三,zhang@example.com,字节跳动,高级方案,需要演示",
}],
output_format: ContactSchema,
});
const contact = response.parsed;
console.log(`姓名: ${contact.name}`);嵌套结构提取
from pydantic import BaseModel
from typing import List
class Product(BaseModel):
name: str
price: float
quantity: int
class Invoice(BaseModel):
invoice_number: str
customer_name: str
total_amount: float
items: List[Product]
is_paid: bool
response = client.messages.parse(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{
"role": "user",
"content": """提取发票数据:
发票号 #12345
客户:李四
商品:
- 笔记本电脑:¥8999 x 1
- 鼠标:¥199 x 2
- 键盘:¥599 x 1
总计:¥9996
状态:已付款"""
}],
output_format=Invoice,
)
invoice = response.parsed_output
print(f"发票: {invoice.invoice_number}")
for item in invoice.items:
print(f" - {item.name}: ¥{item.price} x {item.quantity}")分类任务
from typing import Literal
class EmailClassification(BaseModel):
category: Literal["spam", "promotional", "important", "general"]
confidence: float
reasoning: str
emails = [
"恭喜你中了100万!点击领取!",
"明天下午2点在B会议室开会",
"全场8折优惠,使用码 SAVE20",
]
for email in emails:
response = client.messages.parse(
model="claude-opus-4-6",
max_tokens=256,
messages=[{
"role": "user",
"content": f"分类这封邮件: {email}",
}],
output_format=EmailClassification,
)
result = response.parsed_output
print(f"邮件: {email[:30]}...")
print(f"分类: {result.category}(置信度: {result.confidence})")
print(f"原因: {result.reasoning}\n")Strict 工具模式
保证工具输入严格符合 Schema:
tools = [
{
"name": "get_weather",
"description": "获取天气",
"strict": True, # 启用严格模式
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市名"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"],
"additionalProperties": False # 禁止额外字段
}
}
]
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "上海天气怎么样?"}]
)
# 工具输入保证符合 Schema,无需额外验证
for block in response.content:
if block.type == "tool_use":
print(f"工具: {block.name}")
print(f"输入(保证有效): {block.input}")最佳实践
- 类型安全:用 Pydantic(Python)或 Zod(TypeScript)定义 Schema
- 字段描述:帮助 Claude 理解每个字段应该包含什么
- Enum 分类:预定义选项使用
enum - 嵌套结构:通过 BaseModel 组合支持复杂层级
- Strict 工具:关键 Agent 工作流中使用,确保下游系统不会收到非法输入