Amazon Bedrock 为 Anthropic Claude 模型上线结构化输出
Structured outputs for Anthropic Claude models on Amazon Bedrock
Amazon Bedrock 为所有可用的 Anthropic Claude 模型上线结构化输出,覆盖 bedrock-runtime 与 bedrock-mantle 两个端点,可直接返回符合 JSON Schema 的响应。
原文说明结构化输出改为在生成时约束解码,并给出 schema 书写与缓存、拒绝与截断处理的注意事项。
Amazon Bedrock 现已在提供模型的 bedrock-runtime 和 bedrock-mantle 端点上,为所有 Anthropic Claude 模型支持结构化输出。
无论你是通过 Boto3 和 bedrock-runtime API 调用 Claude,还是通过 Messages API 和 bedrock-mantle 端点调用,现在都可以收到符合所定义结构的、符合 schema 的 JSON 响应。你不再需要自定义解析、重试逻辑或后处理。
实际应用
借助 Amazon Bedrock 上 Claude 的结构化输出,你可以在各行业中自动化执行可靠且符合 schema 的任务。示例包括从财务收益报告和合规文档中提取每个必需字段、将临床记录解析为电子健康记录(EHR),以及用一致且经过验证的结果丰富产品目录。你还可以分析合同中的关键条款、各方和義務,或为智能支持工单路由提供支持,使意图、情感和实体始终与应用程序的数据模型相匹配。
Amazon Bedrock 上结构化输出带来的变化
结构化输出使用约束解码,在 token 生成过程中强制执行你的 JSON schema,而不是在生成之后。模型不会生成违反你 schema 的 token。这将输出格式从概率性变为确定性。
两个 Amazon Bedrock 端点现均提供两种互补机制:
| 功能 | 用途 | 使用场景 |
| JSON Schema 输出格式 | 控制模型的响应结构 | 数据提取、报告生成、API 响应 |
| 严格工具使用 | 根据 schema 验证工具参数 | Agentic 工作流、函数调用、多步骤自动化 |
这对你意味着什么
每个响应都是有效的 JSON,因此你不会再遇到 JSON.parse() 错误或解析异常。响应也是类型安全的:字段类型被强制执行,必需字段始终存在。由于输出始终符合你的 schema,你不需要重试来处理 schema 违规,从而使集成更加可靠。结构化输出还将响应限制为仅包含 schema 定义的字段,这减少了输出 token 数量,并可降低高容量工作负载的推理成本。这些特性使结构化输出达到生产就绪状态,因此你可以大规模部署,而无需额外的 schema 验证代码。
支持的模型和可用性
结构化输出可与批量推理配合使用,因此你可以异步处理大量请求,同时仍收到符合 schema 的输出。在 bedrock-runtime 端点上,它还可与跨区域推理配合使用,因此你可以在 AWS 区域间使用它,而无需额外设置。如果你需要实时响应,可以将结构化响应作为类型化事件进行流式传输。
工作原理
当你使用 JSON schema 发出请求时,幕后会发生以下情况:
- Schema 验证 – Amazon Bedrock 根据支持的 JSON Schema Draft 2020-12 子集验证你的 JSON schema。
- 语法编译 – 对于新 schema,Amazon Bedrock 会编译语法工件(第一个请求可能耗时稍长)。
- 缓存 – 编译后的语法会缓存 24 小时,使后续请求更快。
- 约束生成 – 模型生成产生符合你 schema 的有效 JSON 的 token。
性能考量
在性能方面,使用新 schema 的首次请求可能耗时更长,因为 Amazon Bedrock 会在生成开始前编译语法工件。在首次编译之后,使用相同 schema 的后续请求开销极小,因为编译好的语法会被缓存。该缓存仅作用于你的账户,自首次访问起持续 24 小时。更改 JSON schema 的结构会使缓存失效并触发重新编译,而仅更改 name 或 description 字段则不会影响已缓存的语法。
快速入门:使用 InvokeModel API(bedrock-runtime)实现结构化输出
InvokeModel API 接受 Anthropic 原生请求体,因此 schema 以 JSON 对象而非 JSON 字符串的形式放在 output_config.format 中。以下示例展示了如何使用 boto3 配合 Anthropic Claude 模型从客户邮件中提取结构化潜在客户数据:
Python
import boto3
import json
REGION = "us-east-1" # Choose your preferred region
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name=REGION)
# Define the JSON schema for structured output
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "description": "Customer name"},
"email": {"type": "string", "description": "Customer email address"},
"plan_interest": {"type": "string", "description": "Product plan of interest"},
"demo_requested": {"type": "boolean", "description": "Whether a demo was requested"}
},
"required": ["name", "email", "plan_interest", "demo_requested"],
"additionalProperties": False
}
# Make a request with structured outputs via the InvokeModel API
# (reusing the schema defined for the Converse example)
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) is interested in our Enterprise plan "
"and wants to schedule a demo for next Tuesday at 2pm."
)}
],
"output_config": {"format": {"type": "json_schema", "schema": schema}}
})
)
body = json.loads(response["body"].read())
# Check the stop reason before parsing
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("Response truncated: increase max_tokens and retry.")JSON
{
"name": "Paulo Santos",
"email": "paulo@example.com",
"plan_interest": "Enterprise",
"demo_requested": true
}响应符合你的 schema,无需额外验证。
如需更多 API 用法示例(包括 Messages API),请参阅随附的 示例笔记本。
面向智能体工作流的严格工具使用
Amazon Bedrock Mantle 专为具有服务端工具、后台推理和有状态对话的智能体应用而设计。借助 bedrock-mantle 端点上的严格工具使用,你现在可以保证工具参数与你的输入 schema 完全匹配。以下示例展示了如何定义启用了严格 schema 强制执行的工具:
Import json
from anthropic import AnthropicBedrockMantle
# Reusing the client created in the Messages API example
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
}
}
]
)
#Tool inputs conform to the 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" # Choose your preferred region
bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name=REGION)
# Classification schema: enums restrict output to a fixed set of labels
schema = {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account", "sales", "other"],
"description": "Primary ticket category"
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "urgent"],
"description": "Urgency based on business impact"
},
"sentiment": {
"type": "string",
"enum": ["positive", "neutral", "negative"],
"description": "Customer sentiment"
},
"escalate": {"type": "boolean", "description": "Whether a human should review immediately"},
"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!"
)
# Make a request with structured outputs via the InvokeModel API
response = bedrock_runtime.invoke_model(
modelId="global.anthropic.claude-haiku-5-5",
body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 512,
"system": "You are a support ticket classifier. Classify the ticket accurately.",
"messages": [
{"role": "user", "content": f"Classify this support ticket:\n\n{ticket}"}
],
"output_config": {"format": {"type": "json_schema", "schema": schema}}
})
)
body = json.loads(response["body"].read())
# Check the stop reason before parsing
if body["stop_reason"] == "end_turn":
result_text = next(b["text"] for b in body["content"] if b["type"] == "text")
result = json.loads(result_text)
print(json.dumps(result, indent=2))
# Route the ticket based on the guaranteed-valid labels
if result["escalate"]:
print(f"Escalating to on-call: {result['category']} / {result['priority']}")
elif body["stop_reason"] == "max_tokens":
print("Response truncated: increase max_tokens and retry.")要求与最佳实践
要在 Amazon Bedrock 上有效使用结构化输出,请遵循以下准则:
- 在所有对象上设置 additionalProperties: false:这是结构化输出正常工作所必需的。否则你的 schema 将不被接受。
- 使用描述性的字段名和描述:模型会使用属性名和描述来理解要提取哪些数据。像
customer_email这样清晰的名称比field1这样的泛化名称效果更好。 - 对受限值使用 enum:当字段只有有限的有效值时,使用
enum来约束选项。 - 从基础开始,再逐步增加复杂度:从最少必需字段开始,逐步增加复杂度。基础 schema 编译更快、更易调试,并且能让请求负载保持精简,因为 schema 会计入 Converse API 的负载大小。
- 复用 schema 以受益于缓存:将应用设计为在多个请求间复用 schema。24 小时语法缓存可提升重复查询的性能。
- 检查每个响应中的停止原因:有两种情况可能产生不符合要求的响应:拒绝(模型出于安全原因拒绝)和 token 限制(在完成之前达到
max_tokens)。在代码中处理这两种情况。 - 部署前用真实数据测试:用具有生产代表性的输入验证你的 schema。真实数据中的边缘情况常常会暴露 schema 设计问题。
有关更多最佳实践和 schema 设计建议,请参阅 Amazon Bedrock 用户指南中的结构化输出。
支持的 JSON Schema 功能
- 所有基本类型:
object、array、string、integer、number、boolean、null。 enum(仅限字符串、数字、布尔值或 null)。const、anyOf、allOf(有限制)。$ref、$def和definitions(仅内部引用)。- 字符串格式:
date-time、time、date、duration、email、hostname、uri、ipv4、ipv6、uuid。 - 数组
minItems(仅限值 0 和 1)。
不支持
这些关键字会被 API 接受,但在生成过程中不会强制执行。包含它们的请求会返回成功响应,而模型仍可能返回违反这些关键字的取值。应在应用中验证这些约束,而不是依赖 schema 来强制执行它们。
- 递归 schema。
- 外部
$ref引用。 - 数值约束(
minimum、maximum、multipleOf)。 - 字符串约束(
minLength、maxLength)。 additionalProperties设置为 false 以外的任何值。
结论
Amazon Bedrock 上 Anthropic Claude 模型的结构化输出提供了生产级 AI 应用所需的可靠性。它现已在 bedrock-runtime 和 bedrock-mantle 两个端点上可用。通过结合 JSON Schema 输出格式和严格工具使用,你可以构建无需额外验证的数据管道。你还可以创建可靠的智能体工作流和生产级 AI 应用,而无需自定义解析或重试逻辑。
Amazon Bedrock 上 Claude 的结构化输出现已正式可用。如需了解更多信息,请参阅 Amazon Bedrock 文档并探索我们的示例笔记本。
经过验证、符合 schema 的 JSON 能改善贵组织的哪些工作流?欢迎在评论中分享你的反馈和问题。
关于作者
Anshika Saxena
Anshika 是 AWS 的生成式 AI 数据科学家,专注于 Amazon Bedrock。她通过指导企业客户在 Amazon Bedrock 上构建和实施解决方案,帮助他们加速生成式 AI 和智能体 AI 的采用。她还与 ISV 和初创公司合作,帮助他们在 Amazon Bedrock 上使用 Anthropic 的最新服务。
Dani Mitchell
Dani 是 AWS 生成式 AI 高级专家解决方案架构师,负责 Amazon Bedrock 上 Anthropic 的市场推广工作。他帮助全球企业利用 Amazon Bedrock 上 Anthropic 的模型和功能设计并部署生成式 AI 解决方案,以构建可扩展、生产就绪的应用。
Alfredo Castillo
Alfredo 是 AWS 的生成式 AI 高级专家解决方案架构师,专注于 Anthropic 模型在 Amazon Bedrock 上的市场推广。他与金融服务客户合作,在分布式系统中设计和扩展生成式 AI 解决方案,并将生成式 AI 实验转化为生产工作负载。工作之外,他热衷于家庭和耐力运动。
Aamna Najmi
Aamna 是生成式 AI 高级专家解决方案架构师,专注于 Anthropic 模型,以及在 Amazon Bedrock 上大规模运维和治理生成式 AI 系统。她帮助 ISV 解决挑战、拥抱创新,并借助 Amazon Bedrock 创造新的业务机会。
Sofian Hamiti
Sofian 是一位技术领导者,拥有超过 12 年的构建 AI 解决方案经验,并领导高绩效团队以最大化客户成果。他热衷于赋能多元化人才,以推动全球影响力并实现他们的职业抱负。
Ayan Ray
Ayan 是 AWS 的首席合作伙伴解决方案架构师兼 AI 技术负责人,担任 AWS 全球 Anthropic 技术负责人。他工作在云架构与人工智能的交汇处,帮助组织在 AWS 上采用和扩展 Anthropic 的技术。
来源:AWS Machine Learning Blog · aws.amazon.com