📢 转载信息
原文作者:Jeffrey Zeng and Jonathan Evans
今天,我们宣布 Amazon Bedrock 上的 结构化输出 功能正式上线——这是一项通过受限解码,确保基础模型生成符合 Schema 的 JSON 响应的能力,从根本上改变了您获取数据的方式。
这代表了 AI 应用开发中的一个范式转变。您不再需要验证 JSON 响应并为失败编写回退逻辑,而是可以直接使用数据进行构建。借助结构化输出,您可以构建信任模型输出的零验证数据管道,构建可以自信地调用外部函数的智能体系统,以及构建简化应用架构而无需重试逻辑。
在本文中,我们将探讨传统 JSON 生成面临的挑战以及结构化输出如何解决这些问题。我们将介绍两个核心机制——JSON Schema 输出格式 和 严格工具使用,以及实现细节、最佳实践和实用的代码示例。无论您是构建数据提取管道、智能体工作流,还是 AI 驱动的 API,您都将学会如何使用结构化输出来创建可靠的、可投入生产的应用。我们的配套 Jupyter notebook 为此处涵盖的每个功能提供了动手实践示例。
传统 JSON 生成的问题
多年来,从语言模型中获取结构化数据意味着需要精心设计提示词,期望最好的结果,并构建复杂的错误处理系统。即使经过仔细的提示,开发者也经常遇到以下问题:
- 解析失败:无效的 JSON 语法,导致
json.loads()调用中断 - 缺少字段:响应中缺少必需的数据点
- 类型不匹配:预期是整数的地方返回了字符串,从而破坏了下游处理
- Schema 违反:响应在技术上可以解析,但与您的数据模型不匹配
在生产系统中,这些失败会累积。一个格式错误的响应可能会级联影响整个管道,需要重试,从而增加延迟和成本。对于模型调用工具的智能体工作流,无效的参数可能会完全破坏函数调用。
考虑一个需要 passengers: int 的预订系统。如果没有 Schema 强制执行,模型可能会返回 passengers: "two" 或 passengers: "2"——这在语法上是有效的 JSON,但在语义上对于您的函数签名来说是错误的。
结构化输出带来的变化
Amazon Bedrock 上的结构化输出不是增量改进,而是从概率性到确定性的输出格式的根本转变。通过受限解码,Amazon Bedrock 将模型响应限制为符合您指定的 JSON Schema。
有两种互补的机制可用:
| 功能 | 目的 | 用例 |
|---|---|---|
| JSON Schema 输出格式 | 控制模型的响应格式 | 数据提取、报告生成、API 响应 |
| 严格工具使用 | 验证工具参数 | 智能体工作流、函数调用、多步骤自动化 |
这些功能可以独立或一起使用,让您精确控制模型的输出内容及其函数调用方式。
结构化输出带来的优势:
- 始终有效:不再有
JSON.parse()错误或解析异常 - 类型安全:字段类型得到强制执行,并且必需的字段始终存在
- 可靠:无需因 Schema 违反而重试
- 生产就绪:可以以企业规模的信心进行部署
结构化输出的工作原理
结构化输出使用带有已编译语法工件的受限采样。当您发出请求时,会发生以下情况:
- Schema 验证:Amazon Bedrock 会根据支持的 JSON Schema Draft 2020-12 子集验证您的 JSON Schema
- 语法编译:对于新的 Schema,Amazon Bedrock 会编译一个语法(首次请求可能需要更长时间)
- 缓存:编译后的语法会缓存 24 小时,使后续请求更快
- 受限生成:模型生成能产生与您的 Schema 匹配的有效 JSON 的 Token
性能考量:
- 首次请求延迟:初始编译可能会增加新 Schema 的延迟
- 缓存性能:使用相同 Schema 的后续请求开销极小
- 缓存范围:语法在每个账户中缓存 24 小时,从首次访问开始计时
更改 JSON Schema 结构或工具的输入 Schema 会使缓存失效,但仅更改 name 或 description 字段则不会。
开始使用结构化输出
以下示例演示了如何使用 Converse API 配合结构化输出:
import boto3
import json
# 初始化 Bedrock Runtime 客户端
bedrock_runtime = boto3.client( service_name='bedrock-runtime', region_name='us-east-1' # 选择您偏好的区域
)
# 定义您的 JSON Schema
extraction_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
}
# 使用结构化输出发起请求
response = bedrock_runtime.converse( modelId="us.anthropic.claude-opus-4-5-20251101-v1:0", messages=[ { "role": "user", "content": [ { "text": "从这封邮件中提取关键信息:John Smith (john@example.com) 对企业版方案感兴趣,并希望预约下周二下午 2 点的演示。" } ] } ], inferenceConfig={ "maxTokens": 1024 }, outputConfig={ "textFormat": { "type": "json_schema", "structure": { "jsonSchema": { "schema": json.dumps(extraction_schema), "name": "lead_extraction", "description": "从客户电子邮件中提取潜在客户信息" } } } }
)
# 解析符合 Schema 的 JSON 响应
result = json.loads(response["output"]["message"]["content"][0]["text"])
print(json.dumps(result, indent=2))
输出:
{ "name": "John Smith", "email": "john@example.com", "plan_interest": "Enterprise", "demo_requested": true
}
该响应符合您的 Schema——无需额外的验证。
要求和最佳实践
为有效使用结构化输出,请遵循以下准则:
- 在所有对象上设置
additionalProperties: false。 这是结构化输出正常工作所必需的。如果没有此设置,您的 Schema 将不被接受。
{ "type": "object", "properties": { "name": {"type": "string"} }, "required": ["name"], "additionalProperties": false
}
- 使用描述性的字段名称和描述。 模型使用属性名称和描述来理解要提取哪些数据。像
customer_email这样清晰的名称优于像field1这样的通用名称。 - 对受限值使用
enum。 当某个字段具有有限的有效值集时,使用enum来限制选项。这可以提高准确性并产生有效值。 - 从基础开始,然后增加复杂性。 从最少必需的字段开始,并逐步增加复杂性。基本 Schema 编译更快,更容易维护。
- 重用 Schema 以利用缓存。 构建应用程序以跨请求重用 Schema。24 小时的语法缓存显著提高了重复查询的性能。
- 检查每个响应中的
stopReason。 两种情况可能产生不符合预期的响应:拒绝(当模型因安全原因拒绝时)和达到 Token 限制(当在完成前达到max_tokens时)。请在代码中处理这两种情况。 - 部署前使用真实数据进行测试。 使用生产代表性输入来验证您的 Schema。真实数据中的边缘情况通常会暴露出 Schema 设计问题。
支持的 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)
不支持的特性:
- 递归 Schema
- 外部
$ref引用 - 数字约束(
minimum,maximum,multipleOf) - 字符串约束(
minLength,maxLength) additionalProperties设置为false以外的任何值
用于智能体工作流的严格工具使用
在构建模型调用工具的应用时,在工具定义中设置 strict: true,以确保工具参数完全匹配您的输入 Schema:
import boto3
import json
bedrock_runtime = boto3.client('bedrock-runtime', region_name='us-east-1')
response = bedrock_runtime.converse( modelId="us.anthropic.claude-opus-4-5-20251101-v1:0", messages=[ { "role": "user", "content": [{"text": "旧金山的天气怎么样?"}] } ], inferenceConfig={"maxTokens": 1024}, toolConfig={ "tools": [ { "toolSpec": { "name": "get_weather", "description": "获取指定天气信息", "strict": True, # 启用严格模式 "inputSchema": { "json": { "type": "object", "properties": { "location": { "type": "string", "description": "城市和州,例如:旧金山, CA" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位" } }, "required": ["location", "unit"], "additionalProperties": False } } } } ] }
)
# 工具输入符合 Schema
for content_block in response["output"]["message"]["content"]: if "toolUse" in content_block: tool_input = content_block["toolUse"]["input"]
print(f"工具: {content_block['toolUse']['name']}")
print(f"输入: {json.dumps(tool_input, indent=2)}")
当设置 strict: true 时,结构化输出会限制输出,以确保:
location字段始终是字符串unit字段始终是celsius或fahrenheit- 输入中不会出现意外的字段
跨行业的实际应用
该 Notebook 演示了跨行业的用例:
- 金融服务:从收益报告、贷款申请和合规文件中提取结构化数据。借助结构化输出,每个必需的字段都存在且类型正确,可用于下游处理。
- 医疗保健:将临床记录解析为结构化、符合 Schema 的记录。提取患者信息、诊断和治疗计划为验证后的 JSON,用于 EHR 集成。
- 电子商务:构建可靠的产品目录丰富管道。从产品描述中提取规格、类别和属性,结果一致可靠。
- 法律:分析合同并以结构化格式提取关键条款、当事方、日期和义务,适用于合同管理系统。
- 客户服务:构建智能化的工单路由和响应系统,其中提取的意图、情感和实体与应用程序的数据模型相匹配。
选择正确的方法
我们的测试揭示了何时使用每种功能的明确模式:
当您需要以下情况时,请使用 JSON Schema 输出格式:
- 需要模型响应采用特定结构时
- 构建数据提取管道时
- 生成适用于 API 的响应时
- 创建结构化报告或摘要时
当您需要以下情况时,请使用严格工具使用:
- 构建调用外部函数的智能体系统时
- 实施带有工具链的多步骤工作流时
- 为函数调用要求验证的参数类型时
- 将 AI 连接到数据库、API 或外部服务时
当您需要以下情况时,请同时使用两者:
- 构建需要验证的工具调用和结构化最终响应的复杂智能体时
- 创建中间工具结果输入到结构化输出的系统时
- 实施需要端到端 Schema 合规的企业工作流时
API 对比:Converse 与 InvokeModel
Converse API 和 InvokeModel API 都支持结构化输出,但参数格式略有不同:
| 方面 | Converse API | InvokeModel (Anthropic Claude) | InvokeModel (开源模型) |
|---|---|---|---|
| Schema 位置 | outputConfig.textFormat |
output_config.format |
response_format |
| 工具严格标志 | toolSpec.strict |
tools[].strict |
tools[].function.strict |
| Schema 格式 | jsonSchema.schema 中的 JSON 字符串 |
schema 中的 JSON 对象 |
json_schema.schema 中的 JSON 对象 |
| 最适用于 | 对话工作流 | 单轮推理 (Claude) | 单轮推理 (开源模型) |
注意:InvokeModel API 根据模型类型使用不同的请求字段名称。对于 Anthropic Claude 模型,使用 output_config.format 进行 JSON Schema 输出。对于开源模型,则使用 response_format。
对于多轮对话,请选择 Converse API;当您需要直接的模型访问并使用提供商特定的请求格式时,请选择 InvokeModel API。
支持的模型和可用性
结构化输出在所有商业 AWS 区域对 选定的 Amazon Bedrock 模型提供商 普遍可用:
- Anthropic
- DeepSeek
- MiniMax
- Mistral AI
- Moonshot AI
- NVIDIA
- OpenAI
- Qwen
该功能与以下方面无缝协作:
- 跨区域推理:在不同 AWS 区域中使用结构化输出,无需额外设置
- 批量推理:使用符合 Schema 的输出来处理大量数据
- 流式传输:使用
ConverseStream或InvokeModelWithResponseStream流式传输结构化响应
结论
在本文中,您了解了 Amazon Bedrock 上的结构化输出如何通过验证的、符合 Schema 的响应来减少 AI 生成 JSON 的不确定性。通过使用 JSON Schema 输出格式和严格工具使用,您可以构建可靠的数据提取管道、强大的智能体工作流和可投入生产的 AI 应用程序——无需自定义解析或验证逻辑。无论您是从文档中提取数据、构建智能自动化,还是创建 AI 驱动的 API,结构化输出都能提供您的应用程序所需的可靠性。
结构化输出现已在 Amazon Bedrock 上普遍可用。要使用 Converse API 进行结构化输出,请更新到最新的 AWS SDK。要了解更多信息,请参阅 Amazon Bedrock 文档 并探索我们的 示例 Notebook。
验证的、符合 Schema 的 JSON 可以在您的组织中解锁哪些工作流程?Notebook 提供了您需要了解的一切。
关于作者
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区