Amazon Bedrock 上 Anthropic Claude 模型的结构化输出
Amazon Bedrock 现在为所有 Anthropic Claude 模型提供结构化输出支持,覆盖模型可用的 bedrock-runtime 和 bedrock-mantle 两个端点。无论你是通过 Boto3 和 bedrock-runtime API 调用 Claude,还是通过 Messages API 和 bedrock-mantle 端点调用,现在都能拿到符合预定义结构的 JSON 响应。自定义解析、重试逻辑、后处理这些活儿,统统不用再写了。
实际应用场景
有了 Amazon Bedrock 上 Claude 的结构化输出,你可以在各个行业里自动化那些要求可靠、符合 schema 的任务。比如从财务收益报告和合规文档中提取所有必填字段,把临床笔记解析成电子健康记录(EHR),或者给产品目录补充一致且经过校验的信息。你也可以用它分析合同中的关键条款、签约方和义务,还能支撑智能客服工单路由——让意图、情绪和实体始终匹配应用的数据模型。
Amazon Bedrock 上的结构化输出有什么不同
结构化输出用的是约束解码(constrained decoding),在生成 token 的过程中就强制落实你的 JSON schema,而不是等生成完再检查。模型不会吐出违反 schema 的 token。这就把输出格式从概率性变成了确定性。
现在两个 Amazon Bedrock 端点上都提供两种互补机制:
| 功能 | 用途 | 适用场景 |
|---|---|---|
| JSON Schema 输出格式 | 控制模型的响应结构 | 数据提取、报告生成、API 响应 |
| 严格工具使用(Strict tool use) | 按 schema 校验工具参数 | 智能体工作流、函数调用、多步骤自动化 |
对你意味着什么
每个响应都是合法的 JSON,不会再遇到 JSON.parse() 报错或解析异常。响应也是类型安全的:字段类型被强制约束,必填字段一定存在。因为输出始终符合你的 schema,不需要靠重试来处理 schema 违规,集成的可靠性也就更高了。
结构化输出还会把响应限制在 schema 定义的字段内,从而减少输出的 token 数量,对高并发场景来说能降低推理成本。这些特性让结构化输出足以用于生产环境,你可以放心大规模部署,不必再额外写 schema 校验代码。
支持的模型与可用性
结构化输出可与批量推理(batch inference)配合使用,让你异步处理大量请求,同时仍能拿到符合 schema 的结果。在 bedrock-runtime 端点上,它还支持跨区域推理(cross-Region inference),无需额外配置即可跨 AWS 区域使用。如果需要实时响应,也可以把结构化响应以类型化事件(typed events)的方式流式返回。
工作原理
当你带着 JSON schema 发起请求时,背后会经历以下几个步骤:
- Schema 校验:Amazon Bedrock 会按照支持的 JSON Schema Draft 2020-12 子集校验你的 JSON schema。
- 语法编译:对于新 schema,Amazon Bedrock 会编译一份语法产物(grammar artifact),因此首次请求可能稍慢一些。
- 缓存:编译好的语法会缓存 24 小时,后续请求因此更快。
- 约束生成:模型生成的 token 会产出符合你 schema 的合法 JSON。
性能注意事项
从性能上看,使用新 schema 的首次请求可能耗时更长,因为 Amazon Bedrock 要先编译语法产物,然后才开始生成。完成首次编译后,使用同一 schema 的后续请求开销极小,因为编译好的语法已被缓存。该缓存按你的账户隔离,从首次访问起保留 24 小时。修改 JSON schema 的结构会让缓存失效并触发重新编译;如果只改 name 或 description 字段,缓存中的语法则保持不变。
入门:用 InvokeModel API 使用结构化输出(bedrock-runtime)
InvokeModel API 接收 Anthropic 原生请求体,因此 schema 要放在 output_config.format 里,并且是 JSON 对象而非 JSON 字符串。
下面的示例展示如何用 boto3 配合 Anthropic Claude 模型,从客户邮件中提取结构化的销售线索数据:
import boto3
import json
REGION = "us-east-1" # 选择你偏好的区域
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name=REGION)
# 定义结构化输出的 JSON schema
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "description": "客户姓名"},
"email": {"type": "string", "description": "客户邮箱地址"},
"plan_interest": {"type": "string", "description": "感兴趣的产品方案"},
"demo_requested": {"type": "boolean", "description": "是否请求了演示"}
},
"required": ["name", "email", "plan_interest", "demo_requested"],
"additionalProperties": False
}
# 通过 InvokeModel API 发起结构化输出请求
#(复用为 Converse 示例定义的 schema)
response = bedrock_runtime.invoke_model(
modelId="global.anthropic.claude-sonnet-5-5",
body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 512,
"messages": [
{"role": "user", "content": (
"Paulo Santos (paulo@example.com) 对我们的 Enterprise 方案感兴趣,"
"想预约下周二下午 2 点的演示。"
)}
],
"output_config": {"format": {"type": "json_schema", "schema": schema}}
})
)
body = json.loads(response["body"].read())
# 解析前先检查停止原因
if body["stop_reason"] == "end_turn":
result_text = next(b["text"] for b in body["content"] if b["type"] == "text")
print(json.dumps(json.loads(result_text), indent=2))
elif body["stop_reason"] == "max_tokens":
print("响应被截断:请增大 max_tokens 后重试。") JSON {
"name": "Paulo Santos",
"email": "paulo@example.com",
"plan_interest": "Enterprise",
"demo_requested": true
} 响应会符合你定义的 schema,不需要再做额外校验。更多 API 用法示例(包括 Messages API)可以看配套的示例 notebook。
智能体工作流中的严格工具调用
Amazon Bedrock Mantle 面向智能体应用设计,支持服务端工具、后台推理和有状态会话。在 bedrock-mantle 端点上启用严格工具调用后,可以保证工具参数与输入 schema 完全一致。下面的例子演示如何定义一个强制遵守 schema 的工具:
import json
from anthropic import AnthropicBedrockMantle
# 复用 Messages API 示例中创建的客户端
client = AnthropicBedrockMantle(aws_region="us-east-1")
message = client.messages.create(
model="anthropic.claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "What's the weather like in San Francisco?"}],
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a specified location",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g., San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["location", "unit"],
"additionalProperties": False
}
}
]
)
# 工具输入会符合 schema
for block in message.content:
if block.type == "tool_use":
print(f"Tool: {block.name}")
print(f"Input: {json.dumps(block.input, indent=2)}")
设置 strict: true 会把模型的工具输入严格约束到你的 schema:location 字段永远是字符串,unit 字段只能是 celsius 或 fahrenheit。模型无法添加 schema 之外的字段,因此工具输入只包含 schema 规定的内容。这对 Amazon Bedrock Mantle 上的智能体场景尤其有用——模型需要借助网页搜索、代码解释器等服务端工具,编排多步骤工作流。
Claude 结构化输出的典型场景
在三种常见场景中,结构化输出最能降低错误处理的复杂度:
- 数据提取:从发票、合同、邮件和转录文本中提取字段,输出始终符合 schema 的 JSON,可直接导入数据库或客户关系管理(CRM)系统。
- 可靠的智能体工具调用:生成时按 schema 校验工具参数,多步骤智能体工作流不会因输入格式错误而失败。
- 大规模分类:按意图、优先级和情感对工单、线索或内容分类,用于路由、审核和评估。
Claude Haiku 5.5 能可靠处理快速、重复的工作负载,例如摘要、压缩、数据库查询和分类请求。下面的例子展示如何用 Invoke API 和 Haiku 5.5 对传入数据分类并路由:
import boto3
import json
REGION = "us-east-1" # 选择你偏好的区域
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name=REGION)
# 分类 schema:enum 把输出限制在固定标签集合内
schema = {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account", "sales", "other"],
"description": "主要工单类别"
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "urgent"],
"description": "基于业务影响的紧急程度"
},
"sentiment": {
"type": "string",
"enum": ["positive", "neutral", "negative"],
"description": "客户情感"
},
"escalate": {"type": "boolean", "description": "是否需要人工立即复核"},
"reason": {"type": "string", "description": "One-sentence justification for the classification"}
},
"required": ["category", "priority", "sentiment", "escalate", "reason"],
"additionalProperties": False
}
ticket = (
"Our production API calls have been failing with 500 errors since this morning. "
"We're losing orders every minute. This is the second outage this month!"
)