📢 转载信息
原文作者:Clement Perrot, Remi Louf, and Max Elfrink
本文由 Remi Louf(Dottxt 首席执行官兼技术创始人)与我们合作撰写。
AI 应用中的结构化输出指的是符合预定义、经过验证且通常是严格输入的格式的人工智能生成响应。这可以包括输出的 schema(模式),或者特定字段应如何映射的方式。结构化输出对于需要一致性、验证以及与下游系统无缝集成的应用至关重要。例如,银行贷款审批系统必须生成具有严格字段验证的 JSON 输出,医疗保健系统需要验证患者数据格式并执行药物剂量约束,而电子商务系统则需要标准化的发票生成以供其会计系统使用。
本文探讨了在 .txt 的 Outlines 框架作为一种实用方法,如何在 Amazon SageMaker 中使用 AWS Marketplace 实现结构化输出。
结构化输出:用例和业务价值
结构化输出将生成式 AI 从临时文本生成提升为可靠的业务基础设施,能够在高风险、重集成的环境中实现精确的数据交换、自动决策和端到端工作流。通过强制执行 schema 和可预测的格式,它们解锁了那些对准确性、可追溯性和互操作性有不可或缺要求的应用场景,从财务报告和医疗运营到电子商务物流和企业工作流自动化。本节将探讨结构化输出创造最大价值的领域,以及它们如何直接转化为错误减少、运营风险降低和可衡量的投资回报率(ROI)。
什么是结构化输出?
结构化输出类别结合了多种类型的要求,涉及模型应如何产生符合特定约束机制的输出。以下是约束机制的示例。
- 基于 Schema 的约束:JSON Schema 和 XML Schema 定义了具有类型要求、必需字段、属性约束和嵌套层次结构的对象结构。模型会生成完全符合这些规范的输出,有助于确保诸如
transaction_id(字符串)、amount(浮点数)和timestamp(日期时间)等字段存在且输入正确。 - 枚举约束(Enumeration constraints):枚举表达式将输出限制为预定义的分类值。分类任务使用
enum强制模型从固定选项中进行选择——例如将乐器分类为打击乐、弦乐、木管、铜管或键盘——从而消除了任意类别的生成。 - 基于模式的约束(Pattern-based constraints):正则表达式验证特定格式,如电子邮件地址、电话号码、日期或自定义标识符。Regex 模式确保输出无需事后处理验证即可匹配所需结构。
- 基于语法的约束(Grammar-based constraints):上下文无关文法(CFG)和 EBNF 表示法定义了生成代码、SQL 查询、配置文件或特定领域语言的句法规则。约束解码框架在Token 生成时强制执行这些规则。
- 语义验证:除了句法约束外,大型语言模型(LLM)还可以根据自然语言标准验证输出——帮助确保内容是专业的、适合家庭的或具有建设性的——以解决基于规则的验证无法捕捉的主观要求。
受益于结构化输出的关键组件
在现代应用中,AI 模型与非 AI 类型的处理和业务系统集成。这些集成和连接点需要一致性、类型安全和机器可读性,因为输出中的解析歧义或格式偏差会破坏工作流。以下是我们在 LLM 与基础设施组件之间看到关键互操作性的一些常见架构模式:
- API 集成和数据管道:提取、转换和加载(ETL)流程和 REST API 要求严格的格式合规性。模型输出中的错误可能会导致解析错误,损害直接数据库插入或无缝转换逻辑。
- 工具调用和函数执行:智能体工作流依赖于 LLM 模型使用正确类型的参数调用函数的 ক্ষমতা,从而实现多步骤自动化,其中每个智能体都消耗经过验证的输入。
- 文档提取和数据捕获:解析发票、合同或医疗记录要求模型在语义上识别所需的实体,并以可以真正自动化数据录入的格式返回它们,包括提取供应商名称、金额和日期到预定义模式中,以及特定的分类选项等。
- 实时决策系统:需要亚 50 毫秒决策的系统,如欺诈检测和交易处理,无法承受输出结构中的冗长或重试。生成可靠且符合要求的风险评分、分类标志和决策元数据意味着下游系统可以立即消耗数据。
业务应用:结构化输出提供最大价值的领域
在高风险、重集成的领域中,结构化输出将生成模型从灵活的文本引擎转变为可靠的业务基础设施,提供可预测性、可审计性和端到端自动化。
- 金融服务和交易处理:在金融机构中,结构化输出有助于报告、审计和监管合规性的精确性和一致性。交易数据、风险评估和投资组合分析必须遵循预定义模式,以支持实时对账、反洗钱(AML)审查和监管申报。结构化输出有助于支付系统、风险引擎和审计工具之间的无缝交换——在保持高风险金融操作中充分的可追溯性和数据完整性的同时,减少人工监督。
- 医疗保健和临床运营:监管合规要求严格验证——对生命体征、药物剂量和实验室结果进行范围检查有助于防止关键错误。从医疗文档中进行结构化提取,可以实现自动编码、计费准确性和 HIPAA 合规性的审计跟踪创建。
- 企业工作流自动化:传统系统需要机器可读的数据,而无需自定义解析逻辑。客户支持交互产生的结构化输出会生成带有情感得分、待办事项和路由元数据的案例摘要,这些可以直接集成到客户关系管理(CRM)系统中。
- 电子商务和物流:地址验证、付款验证和订单属性一致性可以减少交付失败和欺诈性交易。结构化输出协调多方工作流,其中承运商、仓库和支付处理器需要标准化格式。
- 监管合规和审计准备:面临严格监管的行业受益于带有不可变审计跟踪的结构化内容管理。组件级存储库会跟踪每一次更改及其元数据(谁、何时、为何、审批人),以便审计员可以通过直接系统访问而不是手动文档审查来验证合规性。
共同的主线是操作复杂性、集成要求和风险敏感性。结构化输出将 AI 从文本生成转变为可靠的业务基础设施,在其中可预测性、可审计性和系统互操作性通过减少错误、加快处理速度和实现无缝自动化,驱动可衡量的 ROI。
在 AWS 上引入 .txt Outlines 以生成结构化输出
可以通过多种方式实现结构化输出。大多数框架的核心都侧重于验证,以识别输出是否遵守所请求的规则和要求。如果输出不符合要求,框架将请求新的输出,并不断迭代,直到模型达到所需的输出结构。
Outlines 提供了一种称为生成时验证(generation-time validation)的高级方法,这意味着验证发生在模型生成 Token 的同时,将验证转移到生成过程的早期阶段,而不是在完成后再验证。虽然它没有与 Amazon Bedrock 集成,但了解 Outlines 可以为信息提供有关前沿结构化输出技术如何为混合实施策略提供信息。
Outlines 由 .txt 团队开发,是一个 Python 库,旨在为语言模型输出带来确定性的结构和可靠性——解决了在生产应用中部署 LLM 的一个关键挑战。与传统的自由格式生成不同,开发人员可以使用 Outlines 在生成过程中强制执行严格的输出格式和约束,而不仅仅是在事后验证。这种方法使得 LLM 能够用于需要准确性、可预测性和与下游系统集成的任务。
Outlines 的工作原理
Outlines 通过三种主要机制强制执行约束:
- 语法编译(Grammar compilation):将 Schema 转换为指导模型选择的 Token 掩码。
- 前缀树(Prefix trees):在束搜索(beam search)期间剪除无效路径,以保持有效的结构。
- 采样控制(Sampling control):在生成过程中使用有限自动机进行有效 Token 选择。
在生成过程中,Outlines 遵循精确的工作流程:
- 语言模型处理输入序列并产生 Token Logits。
- Outlines Logits 处理器将非法 Token 的概率设置为 0%。
- 仅从合法 Token 集中根据定义的结构采样一个 Token。
- 此过程重复直到生成完成,有助于确保输出符合所需格式。
例如,对于像 ^\d*(\.\d+)?$ 这样的十进制数模式,Outlines 会将其转换为一个自动机,该自动机只允许生成有效的数字序列。如果已经生成了 748,系统就知道下一个合法 Token 只能是另一个数字、一个小数点或序列结束 Token。
性能优势
在生成过程中强制执行结构化输出为生产环境的可靠性和性能带来了显著优势。它有助于提高输出结构的有效性,并可以显著提高性能:
- 零推理开销:结构化生成技术在推理过程中几乎不增加计算成本。
- 快 5 倍的生成速度:根据 .txt Engineering 的“聚态(coalescence)”方法,结构化生成可以比标准生成快得多。
- 计算资源减少:约束通过消除无效路径简化了模型的决策过程,减少了总体处理需求。
- 准确性提高:通过缩小输出空间,即使是基础模型也能在结构化任务上实现更高的精度。
基准优势
以下是 Outlines 库经过验证的一些优势:
- 比基于正则表达式的验证管道快 2 倍。
- 与事后验证的 76% 相比,Schema 遵守率达到 98%。
- 支持复杂的约束,如递归 JSON Schema。
开始使用 Outlines
Outlines 可以无缝集成到现有的 Python 工作流中:
from pydantic import BaseModel # 定义数据结构 class Patient(BaseModel): id: int name: str diagnosis: str age: int # 加载模型并创建结构化生成器 model = models.transformers("microsoft/DialoGPT-medium") generator = generate.json(model, Patient) # 生成结构化输出 prompt = "Create a patient record for John Smith, 45, with diabetes" result = generator(prompt) # 返回有效的 Patient 实例 print(result.name) # "John Smith" print(result.age) # 45
对于更复杂的 Schema:
from enum import Enum class Status(str, Enum): ACTIVE = "active" INACTIVE = "inactive" PENDING = "pending" class User(BaseModel): username: str email: str status: Status created_at: datetime # 生成器强制执行枚举值和 datetime 格式 user_generator = generate.json(model, User)
在 Amazon SageMaker 中使用 .txt 的 dotjson
您可以通过在 AWS Marketplace 上部署 .txt 的模型之一(例如 DeepSeek-R1-Distill-Qwen-32B)来直接部署 .txt 的 Amazon SageMaker 实时推理解决方案,以生成结构化输出。以下代码假设您已经在您的 AWS 账户中部署了一个端点。
一个完整演示端点部署的 Jupyter Notebook 可在产品存储库中找到。
import json import boto3 # 根据您的 SageMaker 端点设置此项 endpoint_name = "dotjson-with-DeepSeek-R1-Distill-Qwen-32B" session = boto3.Session() structured_data = { "patient_id": 12345, "first": "John", "last": "Adams", "appointment_date": "2025-01-27", "notes": "Patient presented with a headache and sore throat", } payload = { "messages": [ { "role": "system", "content": "You are a helpful, honest, and concise assistant.", }, { "role": "user", "content": f"Create a medical record from the following visit data: {structured_data}", }, ], "response_format": { "type": "json_schema", "json_schema": { "name": "Medical Record", "schema": { "properties": { "patient_id": {"title": "Patient Id", "type": "integer"}, "date": {"title": "Date", "type": "string", "format": "date-time"}, "diagnosis": {"title": "Diagnosis", "type": "string"}, "treatment": {"title": "Treatment", "type": "string"}, }, "required": ["patient_id", "diagnosis", "treatment"], "title": "MedicalRecord", "type": "object", }, }, "max_tokens": 1000, }, } runtime = session.client("sagemaker-runtime") response = runtime.invoke_endpoint( EndpointName=endpoint_name, ContentType="application/json", Accept="application/json", Body=json.dumps(payload).encode(), ) body = json.loads(response["Body"].read().decode("utf-8")) # 查看模型生成的结构化输出 msg = body["choices"][0]["message"] content = msg["content"] medical_record = json.loads(content) medical_record
这种混合方法消除了对事后验证重试的需求。
AWS 上的替代结构化输出选项
虽然 Outlines 提供了生成时的一致性,但其他几种方法也提供了具有不同权衡的结构化输出:
替代方案 1:基于 LLM 的结构化输出策略
在使用大多数现代 LLM(如 Amazon Nova)时,用户可以直接在提示中定义输出 Schema,从而在 AWS 环境中支持类型约束、枚举和结构化模板。以下指南展示了 Amazon Nova 的不同提示模式。
# Nova 结构化输出示例 import boto3 bedrock = boto3.client('bedrock-runtime') response = bedrock.invoke_model( modelId='amazon.nova-pro-v1:0', body=json.dumps({ "messages": [{"role": "user", "content": "Extract customer info from this text..."}], "inferenceConfig": {"maxTokens": 500}, "toolConfig": { "tools": [{ "toolSpec": { "name": "extract_customer", "inputSchema": { "json": { "type": "object", "properties": { "name": {"type": "string"}, "email": {"type": "string"}, "phone": {"type": "string"} }, "required": ["name", "email"] } } } }] } }) )
替代方案 2:事后验证开源框架
事后验证开源框架已成为现代生成式 AI 系统中的关键层,它们提供结构化、可重复的机制来在模型输出被用户或下游应用程序使用之前对其进行评估和治理。通过将生成与验证分离,这些框架使团队能够在不持续重新训练或微调底层模型的情况下,强制执行安全、质量和策略约束。
LMQL
语言模型查询语言 (LMQL) 具有类似 SQL 的界面,并为 LLM 提供查询语言,使开发人员可以直接在提示中指定约束、类型要求和值范围。在多项选择和类型约束方面尤其有效。
Instructor
Instructor 通过使用 Schema 验证和自动重试机制来包装 LLM 输出,提供重试机制。与 Pydantic 模型的紧密集成使其适用于接受事后验证和更正的场景。
import boto3 import instructor from pydantic import BaseModel # 创建一个用于运行时交互的 Bedrock 客户端 bedrock_client = boto3.client('bedrock-runtime') # 使用 Bedrock 运行时设置 Instructor 客户端 client = instructor.from_bedrock(bedrock_client) # 定义结构化响应模型 class User(BaseModel): name: str age: int # 使用正确的消息结构调用 Claude Haiku 模型 user = client.chat.completions.create( modelId="global.anthropic.claude-haiku-4-5-20251001-v1:0", messages=[ {"role": "user", "content": [{"text": "Extract: Jason is 25 years old"}]}, ], response_model=User, ) print(user) # 预期输出: # User “name='Jason' age=25”
Guidance
Guidance 提供了对输出结构和格式的细粒度模板驱动控制,允许进行 Token 级别的约束。适用于一致的响应格式和对话流。
决策因素和最佳实践
选择正确的结构化输出方法取决于几个关键因素,这些因素直接影响实现复杂性和系统性能。
- 延迟考虑因素:响应时间要求显著影响结构化输出解决方案。通过添加重试机制,事后验证可能会增加延迟。相比之下,像 Outlines 这样的方法最适合延迟敏感的应用。与使用的基础模型相比,强制执行 Schema 会增加一些处理时间,但仍比事后生成策略快得多。
- 重试功能:自动重新生成功能(如 Instructor 中提供的功能)对于结构化输出至关重要,因为当初始生成尝试未能满足 Schema 要求时,它们提供了回退机制,在没有开发人员干预的情况下提高了整体可靠性。
- 流式传输支持:在流式传输期间进行部分 JSON 验证,可以在保持结构完整性的同时实现内容的渐进式交付,这对于需要实时结构化数据的应用中的响应式用户体验至关重要。
- 输入复杂性:上下文修剪技术优化了复杂输入的处理,有助于确保冗长或复杂的提示不会损害输出的结构化性质或超出 Token 限制。
- 部署策略:虽然通过 Amazon Bedrock API(Converse、InvokeModel)访问模型提供了无服务器解决方案,但 Outlines 目前仅通过 Amazon SageMaker 上的 AWS Marketplace 提供,需要您部署和托管模型。
- 模型选择:模型选择显著影响结构化输出的质量和效率。基础模型可能需要大量的提示工程才能遵守结构,而具有内置结构化输出功能的专业模型则提供更高的可靠性和更少的后处理需求。
- 用户体验:每种选项都有其优点和缺点。
- 进程内验证(Outlines):在生成过程中及早捕获错误,当模型犯错时可以提高速度,但当模型输出已经正确时也会增加延迟。
- 事后验证:提供全面的质量控制,但需要对不符合要求的输出进行错误处理。
- 性能:虽然实现结构化输出可以通过减少幻觉和提高输出一致性来提高模型准确性,但其中一些收益可能会带来权衡,例如在某些情况下推理能力下降或引入额外的 Token 开销。
结论
组织可以利用 AI 中的结构化输出范例来可靠地强制执行 Schema、与各种模型和 API 集成,并在事后验证与直接生成方法之间平衡,以获得更大的控制权和一致性。通过了解性能、集成复杂性和 Schema 强制执行方面的权衡,构建者可以根据其技术和业务要求定制解决方案,从而促进跨各种应用的可扩展和高效的自动化。
要了解更多关于在 AWS 上使用 LLM 实现结构化输出的信息:
- 访问 AWS 机器学习博客以获取详细教程和实施指南。
- 在我们的 Amazon Bedrock GitHub 存储库中探索完整的代码示例。
- 查阅 Amazon Bedrock 文档了解结构化输出的最佳实践。
- 通过其博客了解更多关于 .txt 的信息。
关于作者
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区