Amazon Bedrock 为 Anthropic Claude 模型上线结构化输出
Structured outputs for Anthropic Claude models on Amazon Bedrock
Amazon Bedrock 为所有 Anthropic Claude 模型上线结构化输出,覆盖 bedrock-runtime 与 bedrock-mantle 两个端点,可直接返回符合 JSON Schema 的响应。该功能使用约束解码在 token 生成阶段强制 schema,输出格式从概率性变为确定性,并提供 JSON Schema 输出格式与 strict tool use 两种机制,后者用于保证工具参数严格匹配输入 schema。官方称响应类型安全、必填字段始终存在,无需重试处理 schema 违规,且只输出 schema 定义的字段,可减少输出 token 数并降低高并发场景的推理成本。新 schema 首次请求需编译语法产物,编译结果按账号缓存 24 小时,仅修改字段名或描述不会使缓存失效。该功能支持批量推理,在 bedrock-runtime 上还支持跨区域推理,并支持以类型化事件流式返回。
原文说明了约束解码如何把输出格式从概率性变为确定性,并给出缓存与成本上的具体影响。
Amazon Bedrock 现已在所有 Anthropic Claude 模型上支持结构化输出,覆盖模型可用的 bedrock-runtime 和 bedrock-mantle 端点。
无论您是通过 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 验证工具参数 | 代理工作流、函数调用、多步骤自动化 |
这对您意味着什么
每个响应都是有效的 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 对象的形式放在 output_config.format 中,而不是 JSON 字符串。以下示例展示了如何使用 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),请参阅附带的示例 notebook。
面向智能体工作流的严格工具使用
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 高级专家解决方案架构师,负责 Anthropic on Amazon Bedrock 的市场推广工作。他帮助全球企业利用 Anthropic 在 Amazon Bedrock 上的模型和能力设计并部署生成式 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