题记与说明
本报告综合同日完成的两份分轴研究整理而成:纵轴《2026-10-28-结构化输出与函数调用可靠性-vertical.md》(发展史)与横轴《2026-10-28-结构化输出与函数调用-可靠性工程-horizontal.md》(横向对比)。综合时消除了两章之间的重复与口径矛盾(裁定见文末附录),关键事实一律保留来源链接。
信息可靠性声明:OpenAI《Introducing Structured Outputs in the API》官方博客与 MCP 2025-06-18 规范变更日志为分轴研究中的一手全文阅读;其余多为官方文档、搜索结果摘要与二手报道转述;早期背景(正文以【背景】标注)来自模型既有知识、未在本次会话逐一核验。全文无假设性数据。
TL;DR
让 LLM 可靠输出结构化数据,已从 2023 年"求模型说 JSON"演进为四道防线:厂商 strict 结构化输出与自托管约束解码(XGrammar 等)保语法,Pydantic/Zod 应用层校验保语义,带错误重试兜底,推理与输出通道分离护住思维链。(口径提示:此处"防线"是功能划分,不是分层方案;全文分层口径统一采用二.1 的 A–D 四层技术栈,与本节及一.0 的映射关系见一.0 末尾的口径说明。)关键节点:2023-06 函数调用诞生;2024-08 OpenAI strict 模式达 100% schema 遵循;2025 年三大厂商补齐、MCP 把契约延伸到工具结果;2026 年语法层基本解决,重心转向动态 schema 与语义正确性。组合答案:语法交给约束解码、语义留给应用校验、重试只喂错误 diff、别裸用 JSON mode;约束是否伤害推理仍无定论,按场景取舍。
一、纵轴:发展脉络(2013–2026)
0. 课题的三层结构
"结构化输出与函数调用的可靠性工程"由三个技术层构成,三者的组合方式正是本课题的核心问题:
- JSON mode / 结构化输出(API 层):服务商在推理接口上提供的开关,如 OpenAI 的
response_format(json_object→json_schema)、Google 的responseMimeType+responseSchema、Anthropic 的output_format,保证"输出至少是合法 JSON",进而保证"符合给定 schema"; - 约束解码(推理层):在 token 采样阶段用有限状态机(FSM)、上下文无关文法(CFG)屏蔽非法 token,从生成机制上保证语法正确,代表工作有 Outlines、Guidance/llguidance、GBNF、XGrammar;
- schema 校验与重试(应用层):用 JSON Schema / Pydantic / Zod 在应用侧验证语义与业务规则,失败后带着错误信息重问模型,代表实践有 Instructor、Guardrails、TypeChat。
纵轴按时间展开三者从"互不相干"到"分层组合"的演化史;第四层(协议层,MCP)在 2024 年后加入。
口径说明(与二.1 的映射):本节"三层 + 第四层协议层"是按问题发生位置的功能划分;二.1 的"四层技术栈 A–D"是按 2026-10 产品形态的划分,两者对应关系为:①↔A 层(厂商 API 原生结构化输出)、②↔B 层(约束解码引擎)、③↔C 层(应用层框架),而 ③ 中的 Pydantic/Zod 作为契约载体与第四层(MCP)在二.1 中合并归入 D 层(校验与协议层);"推理与输出通道分离"是横跨 A/B 层的架构约定,在二.1 中不计为独立层。自第二节起,全文横向对比与组合建议统一采用 A–D 口径。
1. 史前与酝酿(2013–2022):需求先行,工具缺位
- 契约语言的工业基础。JSON Schema 规范草案自 2013 年 draft-04 起长期演化,最终形成 draft 2020-12 等版本,"用 schema 描述数据契约"早已是软件工业的成熟实践【背景】。这为后来 LLM 结构化输出直接复用 JSON Schema 作为接口语言埋下伏笔。
- 学术先例。约束解码在传统 NLP 中已有探索,例如 2021 年面向语义解析的 PICARD 通过增量解析约束代码生成【背景】,但未进入 LLM 应用开发的主流视野。
- GPT-3 时代的"裸奔"。开发者在 prompt 里求模型"请输出 JSON",再用正则、字符串截取抢救输出,普遍靠"循环重试 + 拼接修复"兜底【背景】。这一痛点至今有定量注脚:单次社区实测仅靠提示词约束约每 10 次输出失败 1 次(测试的模型、时间与 schema 复杂度等条件未详,仅作量级参考;实测博客)。
- 2022-12:LMQL 论文(ETH Zurich SRI Lab,《Prompting Is Programming》,arXiv:2212.06094,代码 github.com/eth-sri/lmql)把约束、控制流写进 prompt 查询语言,是"约束式 LLM 编程"在 ChatGPT 时代的首个系统性表述(报道见 MarkTechPost)。
阶段驱动因素:2022-11 ChatGPT 引爆应用层需求(【背景】),JSON 作为系统间集成的通用语,使"模型输出不可解析"成为头号痛点;学术界先给出理论工具,但尚无产品级实现。
2. 2023:函数调用诞生,约束解码生态爆发
- 2023-05 前后:应用层校验框架先行。Shreya Rajpal 开源 Guardrails AI,以"校验失败就重问"的循环为模型输出建 SLA(Latent Space 播客第 12 期,2023-05-16)。同期(2023-05-18)微软发布 Guidance(现 guidance-ai/guidance),模板语言内嵌正则/CFG 约束与 token healing(SeeAI 评测)。
- 2023-06-13:函数调用正式诞生。OpenAI 随 gpt-3.5-turbo-0613 与 gpt-4-0613 快照模型在 Chat Completions API 引入 function calling(官方博客经 Apidog 报道与 Artificial Analysis 模型页确认日期)。开发者第一次能在 API 里声明"我要的 JSON 长什么样","按 schema 说"取代了"求模型说 JSON"。
- 2023-07:两条约束路线成型。微软发布 TypeChat,把 prompt 工程改造成"schema 工程"(DevClass, 2023-07-24);dottxt 团队发布 Outlines,将 JSON Schema/正则编译为有限状态机、每步采样屏蔽非法 token,方法论沉淀为《Efficient Guided Generation for LLMs》(arXiv:2307.09702),成为引用最广的 FSM 约束解码文献。
- 2023-09:本地侧跟上。llama.cpp 社区引入 GBNF 文法约束采样并内置 json-schema-to-grammar 转换器(始于 issue #3303,转换器见 test-json-schema-to-grammar.cpp),本地模型第一次获得产品级结构化输出能力。
- 2023-10:ToolDec(arXiv:2310.07075)证明 FSM 引导解码可消除工具调用的全部语法错误——约束解码对函数调用场景的价值有了早期定量证据。
- 2023-11-06:OpenAI DevDay 推出 JSON mode。随 GPT-4 Turbo 提供
response_format: {"type": "json_object"}(DevDay 报道、实践指南、OpenAI Academy 资料回顾)。注意其边界:只保证合法 JSON,schema 仍要靠 prompt 描述——官方等于承认了"合法 ≠ 正确"的鸿沟。 - 同期:Instructor 确立"校验 + 重试"范式。Jason Liu 创建的 Instructor(现属 567-labs/instructor-ai 组织)以补丁方式扩展 OpenAI SDK,用 Pydantic 模型解析校验、失败自动带错误重问,并率先支持 Pydantic 模型直接转 JSON Schema。
阶段驱动因素:RAG、数据抽取与 agent 原型潮放大了格式失败的成本;开源推理栈靠约束解码建立差异化;"校验-重试"与"生成时约束"两条路线并行,但 API 层、应用层与推理层之间尚未打通。
3. 2024:从 JSON mode 到 Structured Outputs 的军备竞赛,与"约束是否伤害能力"之争
评测先行:2024-02-26 伯克利发布 BFCL v1(CHANGELOG),首次对可执行函数调用做系统评测;v2 "Live"(2024-04 起)引入真实查询抗泄漏集;v3(2024-09-19)加入多轮、有状态、缺参场景。2024-06 Sierra 发布 τ-bench(arXiv:2406.12045),评测"工具-代理-用户"三方交互与策略遵从。
API 层大跃进:
- 2024 年春夏,Google 在 Gemini API 与 Vertex AI 推出 controlled generation(
responseMimeType: application/json+responseSchema,采用 OpenAPI 3.0 schema 子集;Vertex 实践讨论);2024-04 Anthropic 在 Messages API 以 beta 开放工具调用。 - 2024-08-06:OpenAI 发布 Structured Outputs(一手全文阅读确认)——本课题最重要的事件节点。官方博客 Introducing Structured Outputs in the API:
- 两种用法:函数/工具定义加
strict: true(gpt-4-0613 及以后),或response_format: {"type": "json_schema", "strict": true}(gpt-4o-2024-08-06 与 gpt-4o-mini-2024-07-18 起); - 可靠性数字:strict 模式在内部评测中对 gpt-4o-2024-08-06 达到 100% schema 遵循,而旧方法下 gpt-4-0613 不足 40%;
- 底层机制:正是学术界倡导的约束解码——服务端把 JSON Schema 编译为 CFG,动态屏蔽非法 token,代价是首个请求需预处理(典型 schema <10 秒,复杂 schema 可达一分钟)并加收延迟;
- 工程细节:
refusal字段区分拒答与正常输出、strict 模式暂不兼容并行函数调用、只支持 JSON Schema 子集(硬上限见横轴部分); - 官方明确致谢 outlines、jsonformer、instructor、guidance、lark——开源生态的路线被巨头产品化,宣判了纯 prompt 式 JSON mode 的过渡性。OpenAI 同期在官方 SDK 原生支持 Pydantic/Zod 到 JSON Schema 的转换,三层技术第一次被官方"打包"。
- 两种用法:函数/工具定义加
学术辩论:约束解码有没有代价:2024-05《Grammar-Aligned Decoding》(NeurIPS 2024)证明约束解码会系统性扭曲模型分布;2024-08《Let Me Speak Freely?》(Appier AI Research)报告格式限制显著损害推理任务表现;反方随后出现——ACL 2025 industry 论文《Grammar-Constrained Decoding Makes LLMs Better》主张约束反而提升符号推理准确率(ACL Anthology)。"可靠性 vs 能力"成为此后数年的核心张力。
推理模型登场:2024-09-12 OpenAI 发布 o1 系列(o1-preview / o1-mini,o1 System Card 落款 2024-09-12)——"先思考后作答"的推理模型首次产品化。它把"约束解码会不会伤害思考"从学术问题推成产品决策的前置条件:对推理模型而言,若 schema 约束作用于思维链通道,代价会直接落在推理质量上——这为 2025 年 harmony 式"通道分离"(见第 4 节)埋下伏笔。
推理层性能军备赛与生态下沉:2024-11 CMU/MLC 发布 XGrammar(MarkTechPost 报道),靠"上下文无关预检查 + token 缓存"与自适应掩码缓存优化约束解码——两章引用的加速口径不同:论文(arXiv:2411.15100)口径为文法编译提速约 28 倍,媒体转述官方口径为最高 100x 加速,本报告并列保留、引用时注意区分。同月(2024-11-25)Anthropic 发布 MCP(Model Context Protocol)(发布公告链接;规范文本以官方站点各版本 changelog 为准,见参考来源 9),以 JSON Schema 描述工具输入参数,函数调用接口标准开始跨厂商统一。2024-12 结构化输出下沉全栈:本地端 Ollama 0.5(format 参数直收 JSON Schema)、聚合层 OpenRouter(2024-12-12)、推理引擎 vLLM 于 2024 年末合入 XGrammar 后端(具体合入版本未核验),并在 2025-01-14 官方博客《Structured Decoding in vLLM》中正式确认:负载下每输出 token 耗时(TPOT)最多改善 5 倍——即最高降至约 1/5,官方口径。
阶段驱动因素:agent 热潮使"调错一次函数就断链"不可接受,可靠性从加分项变为门槛;OpenAI 把学术成果产品化并公布量化口径形成示范效应;XGrammar/vLLM 消除了性能借口;学术圈开始系统质疑"免费午餐"。
4. 2025:组合范式定型——分层防御 + 推理通道分离
- 2025-01:vLLM 官方博客《Structured Decoding in vLLM》确立工程格局,"guided decoding"正式更名为"structured outputs",术语统一。同期 EPFL 发布 JSONSchemaBench(约 1 万条真实 JSON schema,GitHub/Kubernetes/Snowplow 等,按 trivial→ultra 分级;HF 数据集),专门测约束解码框架的覆盖率、效率与有效性。
- 2025-02:CRANE(ICML 2025)从表达力理论角度证明约束会削弱模型能力,主张"约束生成与自由生成混合"——为"推理不约束、答案才约束"的架构提供理论依据。
- 2025-03:MCP 发布 2025-03-26 规范(Streamable HTTP、OAuth 2.1、工具注解);OpenAI 推出 Responses API,结构化输出(
text.format)与工具编排成为一等公民(社区讨论可见迁移成本)。 - 2025-06-18:MCP 新规范加入 structured tool output(一手阅读 changelog 确认):工具可声明
outputSchema(JSON Schema 2020-12),结果携带structuredContent并向后兼容地同时返回文本块,客户端"应当"校验——可靠性工程从"模型→应用"单向延伸到"工具→模型"反向通道。 - 2025-07:BFCL v4 进入 agentic 阶段,新增 Web Search、Memory Management 类别,评测对象从"单次调用"彻底转向"智能体工具编排"。
- 2025-08:OpenAI 发布 GPT-5 与开源权重模型 gpt-oss,采用 harmony 响应格式(analysis / commentary / final 三通道):约束解码只作用于 final 通道,思维链通道刻意保持自由——"先自由推理、后结构化输出"从论文建议变成产品制度。工程边界随之显性化:vLLM issue #44012 记录了启用推理解析器时
json_schema约束"泄漏"到自由通道失效的问题。 - 2025-09:SqueezeBits 发布 XGrammar 与 LLGuidance 在 vLLM/SGLang 上的横向实测,比较吞吐、延迟与"不支持 schema 特性时的处理",成为自托管选型最直接的实测材料。
- 2025-11:Anthropic 结构化输出公测(两章口径矛盾,裁定见附录:纵轴记为 2025-09,横轴给出 beta header
structured-outputs-2025-11-13,本报告采 2025-11 公测口径),先支持 Claude Sonnet 4.5 与 Opus 4.1,承诺响应严格符合 JSON schema,SDK 同时提供 JSON Schema / Zod / Standard Schema 助手(@claudeai 公告、API 文档、实践评述)。第三方渠道(如 Bedrock)能力检测仍不一致(PydanticAI issue #4368)。至此三大服务商全部原生提供 schema 级保障。MCP 规范最新修订至 2025-11-25。
阶段驱动因素:推理模型(o1/o3/gpt-oss 一系)把"约束是否伤害思考"从学术争论逼成产品决策,催生"通道分离"架构;MCP 把 JSON Schema 变成工具生态的通用接口语言;评测体系转向 agentic,可靠性定义再度扩容。
5. 2026(当下):生产化共识与未竟之争
- 2026-01:XGrammar 团队发布续作 XGrammar-2(HF 页面),面向 agentic 场景的动态/未定 schema,编译提速 6x、端到端开销趋近于零——约束解码前沿转向"多轮 agent 中 schema 边跑边变"。
- 2026-04:BFCL 榜单页面更新(2026-04-12),V4 整体式 agent 评测持续迭代,
pip install bfcl-eval==2025.12.17可复跑。 - 2026-06:arXiv:2606.09395《Empirical Study for Structured Output Control in LLMs》在软件工程场景系统评测主流 LLM 的结构化输出控制能力,研究重心从"能不能"转向"什么场景该怎么配"。
- 2026-09:小模型约束解码研究(arXiv:2609.23742):约束解码把五个模型在 JSONSchemaBench 上的 schema 有效率从 78.6–92.9% 提到 100%,但内容正确性差距显著——"语法对 ≠ 语义对"有了定量结论。
- 2026-10:arXiv:2610.35328《Constrained Decoding: Harmful or Beneficial? Revisiting...》——诞生两年半后,"约束是否有害"仍在被重新审视,说明该权衡没有终极答案,只有场景化结论。应用侧,Instructor 新增语义校验(semantic validation)能力(官方博客)。
- 生产化共识(当下最佳实践):① 语法层优先用服务商 strict 结构化输出/约束解码(自托管用 vLLM/XGrammar、Ollama);② 语义层仍以 Pydantic/Zod/JSON Schema 二次校验业务不变量;③ Instructor/Guardrails 式"带错误信息重问"作为恢复层兜底;④ 架构层推理与输出分离(harmony 式通道分离)。
- 消费者意识觉醒:聚合路由时代出现"假 100%"问题——部分提供商只是 prompt 级 best-effort 而非真约束解码(Hacker News 讨论);OpenRouter 文档要求
require_parameters: true才强制路由到支持的提供商(OpenRouter 文档)。
6. 贯穿全程的驱动因素与主线
驱动因素的四次切换:① 2022–2023 痛点驱动(JSON 解析失败 → 函数调用与 FSM 约束解码出现);② 2024 可靠性驱动(agent 链式调用放大单点失败 → strict 模式、评测基准、性能优化爆发);③ 2025 能力权衡驱动(推理模型兴起 → 通道分离、混合生成、约束范围精细化);④ 2026 生产与信任驱动(多提供商、动态 schema、跨路由一致性 → 语义校验与重试层的价值被重新确认)。
主要参与者:OpenAI(function calling → JSON mode → Structured Outputs → Responses API/harmony)、Anthropic(工具调用 → MCP → 结构化输出)、Google(Gemini/Vertex controlled generation)、Microsoft(Guidance、TypeChat、llguidance)、dottxt(Outlines 及其论文)、ETH Zurich(LMQL)、EPFL(JSONSchemaBench)、CMU/MLC(XGrammar/-2)、UC Berkeley(BFCL/Gorilla)、Sierra(τ-bench)、应用层生态(Instructor、Guardrails AI、PydanticAI)、基础设施(llama.cpp/GBNF、vLLM、Ollama、OpenRouter、Fireworks、Together)。
一句话结论:这四年的主线,是"约束解码"从学术构想被 API 巨头收编为产品能力,"schema 校验"从应用层自救沉淀为标准接口(MCP、Pydantic/Zod SDK),最终收敛为分层组合架构——API 层约束保语法、应用层校验保语义、重试机制兜底、推理通道保持自由;而"约束与能力如何兼得"仍是尚未终结的核心张力。
二、横轴:横向对比(2026-10-28 时间截面)
1. 格局:四层技术栈 + 两条横切线
在当下时间截面,"如何让 LLM 稳定吐出合法、可用、语义正确的结构化数据"不是一个单点技术,而是四层技术栈 + 两条横切线。任何一种具体手段(如"开 JSON mode")的竞品,是同一层和相邻层的所有替代手段:
| 层 | 角色 | 对比对象 |
|---|---|---|
| A. 厂商 API 原生结构化输出 | 托管式约束解码 | OpenAI Structured Outputs / JSON mode、Anthropic Structured Outputs(beta)、Gemini responseSchema、OpenRouter(聚合层透传) |
| B. 约束解码引擎(自托管) | 推理时语法约束 | XGrammar / XGrammar-2、Outlines、guidance(llguidance)、LM Format Enforcer、llama.cpp GBNF,及 vLLM / SGLang / TensorRT-LLM 集成 |
| C. 应用层框架 | schema 定义 + 校验 + 重试编排 | Instructor、PydanticAI、BAML、LangChain with_structured_output、TypeChat(已基本停滞/归档,未核验) |
| D. 校验与协议层 | 契约的标准载体 | JSON Schema(draft 2020-12)、Pydantic / Zod / Standard Schema、MCP outputSchema + structuredContent |
| 横切线 1. 评测基准 | 可靠性的"卷子" | BFCL(函数调用)、JSONSchemaBench(结构化输出)、τ-bench |
| 横切线 2. 研究证据 | "约束是否伤害能力"的裁判 | Let Me Speak Freely?、Grammar-Aligned Decoding、CRANE、ToolDec、2026 年系列研究 |
2. 主对比表
| 方案 | 保证强度 | 成本(延迟/工程) | 生态与互操作 | 成熟度(截至 2026-10) | 适用场景 |
|---|---|---|---|---|---|
Prompt-only + json.loads | 无保证;单次社区实测约 10% 概率失败(模型、时间与 schema 复杂度条件未详,仅作量级参考,实测) | 零接入成本,隐性失败成本最高 | 通用 | 落后 | 一次性脚本、容错率高的草稿场景 |
OpenAI JSON mode(json_object) | 仅保证合法 JSON,不保证符合 schema;上下文不含"JSON"字样会报错 | 极低 | OpenAI 系 | 成熟但官方已不推荐 | 被 Structured Outputs 全面替代 |
OpenAI Structured Outputs(json_schema + strict:true) | 语法级强保证(服务端 CFG 约束解码);有 schema 子集限制与硬上限 | 首次使用新 schema 有预处理延迟(典型 <10 秒,复杂可达 1 分钟) | OpenAI 全系 + 微调端点;事实上的 API 标准 | 最成熟 | 生产 API 主力,schema 复杂度中低 |
| Anthropic Structured Outputs(beta) | schema 遵循保证;beta header structured-outputs-2025-11-13 | 新发布,部分渠道(Bedrock 等)支持检测不齐(issue) | Claude 系;SDK 支持 Zod/Standard Schema | 公测中 | Claude 生态、Sonnet 4.5 / Opus 4.1 及以后 |
| Gemini responseSchema | 非严格约束,社区称"best effort";仅支持 OpenAPI 3.0 子集;propertyOrdering 为私有扩展且 OpenAI 兼容端点不尊重 | 低 | Gemini 系,与 OpenAI 兼容层存在行为差异 | 可用但有已知缺陷(字段改名、顺序被忽略,论坛) | Gemini 原生应用,容忍偶尔偏差 |
| OpenRouter 等聚合层 | 透传,取决于路由到的 provider;supported_parameters 可查支持度 | 低,但失败排查成本高 | 多厂商统一入口 | 可用 | 多模型路由,需自行校验兜底 |
| vLLM + XGrammar(自托管默认) | 推理时 token 级语法保证;不支持的 schema 会静默回退到 Outlines(讨论 #15213) | 编译开销已大幅优化;需运维自托管 | vLLM / SGLang / TensorRT-LLM / MLX 广泛集成 | 高(2024-11 论文 → 2026 XGrammar-2) | 开源模型、私有化、Agent 高并发 |
| vLLM + guidance(llguidance)/ Outlines | 同上;Outlines 覆盖 XGrammar 不支持的 schema 子集 | Outlines 核心(outlines-core)已用 Rust 提速 | HF transformers / Ollama / vLLM | 高 | schema 用到 XGrammar 不支持的关键字时 |
| llama.cpp GBNF | 本地语法约束 | 手写 GBNF 成本高 | llama.cpp 本地生态 | 成熟、偏手工(现状未单独核验) | 端侧 / 本地小模型 |
| Instructor(校验+重试层) | 不保证语法,但保证"最终返回通过 Pydantic 校验的对象"(重试把校验错误喂回模型) | 多次重试的延迟与 token 成本 | Python/JS 多语言;2026 年新增语义校验 | 高,事实上的轻量标准 | 任何 API/本地模型之上加一层兜底 |
| PydanticAI | 同 Instructor 校验思路,output_type 原生产出已验证的 Pydantic 实例 | 框架级接入成本 | 与 Pydantic/Logfire 同族;Marvin、ControlFlow 已重构其上 | v1.x 稳定线(2026 年已迭代至 1.6x) | Agent 工作流 + 结构化输出一体 |
| BAML | 自有 SPL schema DSL,提示词更干净;附 playground/测试 | 需学 DSL | BoundaryML 生态 | 成长中(星数未核实) | 复杂 schema、提示词工程密集团队 |
MCP outputSchema + structuredContent | 协议层契约:工具结果声明输出 schema,客户端应校验;不解决模型侧生成 | 工具开发者一次性定义成本 | MCP 标准(2025-06-18 引入,最新修订 2025-11-25),各大 SDK | 标准化进行中(校验失败语义仍在讨论) | Agent 工具调用结果的类型安全 |
| BFCL / JSONSchemaBench / τ-bench(评测) | 不直接产出,但把"可靠性"变成可比数字 | 评测运行成本 | 学术+社区通用 | BFCL 已到 V4(页面 2026-04-12 更新) | 模型选型、回归测试 |
3. 分层要点与已知的坑
A 层(厂商 API)。OpenAI strict:true 的 schema 子集限制:所有字段必须 required、可选字段以可空类型表达、必须 additionalProperties: false、根不能是 anyOf;硬上限包括至多 5000 个对象属性、嵌套至多 10 层、schema 总长至多 120,000 字符、枚举值至多 1000 个;不支持 allOf/not/dependentRequired/if-then-else 等关键字;模型可返回独立 refusal 字段(来源:OpenAI Structured Outputs 官方文档)。官方文档明确两件事:JSON mode "只保证输出是合法 JSON",且官方建议始终用 Structured Outputs 取代 JSON mode。Gemini 的已知缺陷:随机改写字段名、propertyOrdering 在 OpenAI 兼容端点被忽略、非服务端严格约束(Google AI 论坛、HN 讨论)。聚合层按 provider 粒度透传,路由到不支持的 provider 就会失败,社区抱怨"除了 OpenAI 几乎都翻车"(OpenRouter 文档、r/openrouter)。
B 层(自托管约束解码)。vLLM 默认后端 XGrammar,可显式选 guidance(llguidance)或 Outlines;当 schema 用到 XGrammar 不支持的 JSON Schema 特性时静默回退到 Outlines——行为悄悄变了,这是自托管可靠性工程里最阴的坑(vLLM 文档、讨论 #15213)。Outlines 有培训材料转述的对比数据:约束生成比"正则后校验重试"管线快约 2 倍、schema 遵循率 98% 对 76%(二手数据,仅作量级参考;outlines、outlines-core)。选型实测首选 SqueezeBits 2025-09 对比。
C 层(应用框架)。Instructor(文档、仓库)核心模式"schema 进提示 → 解析 → Pydantic 校验 → 失败把错误 diff 喂回重试";PydanticAI(仓库)生态收敛明显;BAML 差异化在自有 DSL;TypeChat 作为 2023 年开创者已基本停滞/归档(未单独核验),是横轴上的"退出者"样本。
D 层(校验与协议)。MCP 2025-06-18 为工具引入可选 outputSchema(JSON Schema 2020-12)与 CallToolResult.structuredContent,要求向后兼容同时返回文本块,客户端"应当"校验(规范);但"校验失败怎么办"仍在 SDK 层讨论中(python-sdk #1702、csharp-sdk SEP-2145)。可靠性契约从"模型输出"延伸到"工具结果"的闭环。
横切线(评测与研究)。BFCL 从 v1 的 AST 匹配一路迭代到 V4 整体式 agent 评测;JSONSchemaBench 提供约束解码框架的覆盖率/效率/有效性标尺;研究证据链:ToolDec(2023,约束消除工具调用语法错误)→ Grammar-Aligned Decoding(2024-05,约束扭曲分布)→ Let Me Speak Freely?(2024-08,格式越强推理掉分越多)→ ACL 2025 反方(约束提升符号推理)→ CRANE(2025-02,表达力理论+混合生成)→ 小模型定量研究(2026-09,schema 有效率 100% 但内容正确性差距显著)→ 2026-10 revisit——争论未终结。
4. 组合策略:P0–P5
横轴对比的结论不是"谁取代谁",而是四层各管一段、叠着用:
| 组合策略 | 语法保证 | 语义保证 | 典型成本 | 适用 |
|---|---|---|---|---|
| P0 纯提示 | ✗ | ✗ | 最低 | 草稿、demo |
| P1 JSON mode + 解析 + 校验 + 重试(Instructor 式) | 弱(有重试兜底) | 靠 Pydantic/自定义校验 | 重试 token + 延迟 | 厂商不支持 strict schema 时 |
| P2 厂商 Structured Outputs(strict json_schema / tool_choice 强制) | ✓(服务端约束解码) | 仍需自己校验 + 处理 refusal | 首次 schema 预处理延迟 | 生产 API 首选 |
| P3 自托管约束解码(vLLM+XGrammar/Outlines) | ✓(本地推理时) | 同样需自校验;注意后端静默回退 | 自托管运维 + 文法编译 | 私有化、开源模型、Agent 高并发 |
| P4 分层组合:约束解码(语法)+ Pydantic 语义校验 + 定向重试 + 模型降级 | ✓ | ✓ | 最高但可控 | 金融/医疗等高可靠要求 |
| P5 协议层收口:MCP outputSchema + 客户端校验工具结果 | 工具侧契约 | 客户端应校验 | 工具开发一次性 | Agent 与工具生态 |
三条工程铁律(由上述证据直接推出):
- 语法交给约束解码,语义留给 schema 校验,重试只喂错误 diff——因为 100% schema 有效 ≠ 内容正确(arXiv:2609.23742),而重试全量重生成既贵又不稳。
- 永远别裸用 JSON mode——官方已建议用 Structured Outputs 取代(OpenAI 文档);用聚合层时先查
supported_parameters、需要时开require_parameters: true。 - 自托管要盯住后端回退——vLLM 在 XGrammar 不支持 schema 时静默切 Outlines(vLLM #15213),行为变化要在监控里可见。
5. 残留风险清单
Gemini 的"best effort"式结构化输出、聚合层的 provider 粒度差异、vLLM 的静默后端回退、约束解码对推理能力的潜在折损(Let Me Speak Freely 争议仍未定论)、Anthropic beta 在第三方渠道的检测不一致、MCP 校验失败语义未定——这些是当下做可靠性工程时真正需要写进预案的部分。
三、交叉洞察:两轴结合说明了什么
洞察 1:语法层可靠性已经"解决",问题重心完成了三次迁移
纵轴与横轴是两条独立证据链,却在同一结论上交汇。纵轴显示:2024-08 OpenAI 产品化约束解码并给出 100% schema 遵循的量化口径 → 2024-25 下沉全栈(vLLM/Ollama/OpenRouter/llama.cpp)→ 2026 前沿转向动态 schema(XGrammar-2)。横轴显示:厂商侧(OpenAI 2024、Anthropic 2025-11 补齐)与开源侧(XGrammar 进入 vLLM/TensorRT-LLM/SGLang 默认栈)双线收敛,"JSON 不合法"从常态问题降级为边缘问题。由此,问题重心完成了三次迁移:语法正确(已解决)→ 语义正确(活跃战场,"语法对 ≠ 语义对"在 2026 年有了定量证据)→ 动态与双向契约(多轮 agent 中 schema 边跑边变、工具结果反向校验)。2026 年的研究题目(arXiv:2606.09395)已经是"什么场景该怎么配",而不是"能不能"。
洞察 2:"约束 vs 能力"之争如何直接变成产品架构
把两轴放在一起,能看到学术与产品的一次完整闭环:LMQL/Outlines 把约束解码从构想做成工程(2022-23)→ OpenAI 致谢并产品化(2024-08)→ Grammar-Aligned Decoding 与 Let Me Speak Freely? 提出质疑(2024)→ ACL 2025 反方与 CRANE 把争论理论化(2025)→ GPT-5/gpt-oss 的 harmony 三通道把争论的"暂时结论"直接固化为产品制度:推理通道自由、仅 final 通道约束(2025-08)→ 2026-10 的 revisit 论文证明争论仍未终结。两轴结合给出的判断是:多项证据提示约束的"能力税"与任务类型相关(Let Me Speak Freely? 报告格式限制在推理任务上掉分),但方向与幅度存在反例(ACL 2025 报告约束反而提升符号推理准确率),且 2026-10 的 revisit 论文仍未定论——因此工程答案不是"约束还是不约束"的二选一,而是"在哪里约束"——这正是当下各家产品的共识架构,也是本课题标题里"怎么组合"在架构层的最终答案。vLLM issue #44012 记录的约束"泄漏"到思维链通道的失效案例,说明这条边界在开源栈里仍是需要显式守护的工程细节。
洞察 3:可靠性定义的五次扩容,与评测基准一一对应
纵轴的时间线上,"可靠"的定义至少扩容了五次,每次都有对应的评测/协议出现(五项按各阶段起点时间排序,阶段之间在时间上有重叠):① 输出可解析(合法 JSON)——JSON mode 时代(2023-11 起),无系统基准;② 符合 schema——BFCL v1(2024-02)与 Structured Outputs(2024-08);JSONSchemaBench(2025-01)随后为这一阶段补上标尺,但它测的是约束解码框架的语法覆盖率/效率/有效性(语法层标尺),不测内容正确性;③ 多轮 agentic 可靠——τ-bench(2024-06)与 BFCL v3/v4(2024-09 / 2025-07),评测从单次调用转向智能体编排;④ 工具结果的双向契约——MCP outputSchema/structuredContent(2025-06-18)及其仍在争论的校验失败语义;⑤ 语义与内容正确——小模型研究(2026-09,schema 有效率 100% 但内容正确性差距显著),"语法对 ≠ 语义对"至此有了定量结论,也是当前最新的扩容方向。横轴补充了关键判断:评测驱动选型正在取代厂商营销话术——pip install bfcl-eval==2025.12.17 可复跑的公开基准,让"100%"之类的宣称必须接受第三方复核;而"假 100%"(prompt 级 best-effort 冒充真约束解码)的信任问题,正说明市场已经把"可靠性"当成需要可验证承诺的商品属性。
洞察 4:市场结构——两层市场、粘合层价值重估与退出者
横轴的格局是"两层市场":托管 API(A 层)赢在零运维与官方保障,自托管(B 层)赢在控制力、成本与数据主权,两者长期并存而非取代。更有意思的是 C 层的价值变迁——纵轴显示 Instructor/Guardrails 在 2023 年的使命是"补语法短板"(当时 API 没有任何保证),到 2026 年语法短板被 A/B 层补齐后,它们的价值退化为"统一语义校验、重试编排与多模型适配"的粘合层,并继续向语义校验(Instructor 2026 新能力)延伸。生态边界的另一侧是退出者与标准化者:TypeChat 归档、Guidance 收敛为 llguidance 后端;而 MCP、Standard Schema、Pydantic/Zod SDK 转换成为标准化载体。对使用者的含义:不要押注单一粘合层框架的语法能力(那已是商品),要押注其语义校验与生态适配能力。
洞察 5:对用户的判断与建议
综合两轴,给出可执行的判断与建议:
- 默认架构取 P4 分层组合:厂商 strict 结构化输出(或自托管约束解码)打底 → Pydantic/Zod 语义校验业务不变量(枚举、范围、跨字段关系)→ 失败后带错误 diff 定向重试 → refusal 与校验失败率写进监控与 SLA。这是两章证据共同指向的当下最优解。
- 选型要点:OpenAI 系生产首选 Structured Outputs,注意 schema 硬上限(5000 属性/10 层嵌套/1000 枚举)与首次预处理延迟;Claude 生态注意 beta header 与 Bedrock 等渠道检测不一致;Gemini 仅在容忍字段偏差的场景使用;多模型路由必查
supported_parameters,必要时开require_parameters: true;自托管用 vLLM+XGrammar 并把"静默回退"纳入监控;端侧用 GBNF。 - 何时允许降级:草稿、demo 等容错率高的场景,P0 纯提示即可——但"约 10% 失败率"出自单次社区实测(模型、时间与 schema 复杂度条件未详,见一.1 与主对比表标注),是否接受 P0 请以自有流量、真实 schema 实测的失败率为准,不必照搬外部数字;除此之外,P0/P1 都应视为过渡态。
- 高可靠场景(金融/医疗等):P4 之上再加模型降级预案(重试失败后切换模型或转人工),并把 BFCL/JSONSchemaBench 回归测试纳入 CI,让"可靠性"成为可复现数字而非营销承诺。
- 推理模型场景:保持"推理自由、输出约束"的通道分离,警惕约束泄漏到思维链(vLLM #44012 类问题);对推理密集任务,评估约束的能力税后再决定约束范围——这正是 2026-10 revisit 论文提醒的"场景化结论"。
- 持续关注三件事:动态 schema(XGrammar-2 方向)、MCP 校验失败语义的标准化(python-sdk #1702、SEP-2145)、"约束 vs 能力"的后续实证(arXiv:2610.35328)。它们决定下一轮组合方式的演进方向。
附一:两章口径差异的裁定与未验证项
综合时发现并处理了以下矛盾,裁定原则是"更具体、可自洽、有一手证据者优先":
- Anthropic 结构化输出的时间:纵轴记为 2025-09(随 Claude Sonnet 4.5 推出)并称"后转 GA";横轴给出 beta header
structured-outputs-2025-11-13并记为公测中。裁定:采横轴 2025-11 公测口径(日期更具体,且与"第三方渠道检测不齐"的现状自洽);纵轴"2025-09"与"后转 GA"无法被横轴证据支持,予以修正。 - XGrammar 加速数字:纵轴引 MarkTechPost 转述"官方口径最高 100x";横轴引论文"编译加速约 28 倍"(arXiv:2411.15100)。裁定:并列保留并注明口径——论文口径为文法编译提速约 28 倍,媒体转述口径为端到端最高 100x。
- vLLM 后端格局:纵轴"outlines + XGrammar 双后端"(2025-01 博客口径)与横轴"默认 XGrammar + guidance、静默回退 Outlines"。裁定:以横轴为准(附讨论 #15213),纵轴表述视为早期博客口径。
- 同一工作的不同名称:纵轴的"结构化输出基准研究(arXiv:2501.10868)"与横轴的"JSONSchemaBench(EPFL)"为同一工作,统一命名;机构归属一并统一为 EPFL(HF 数据集组织为 epfl-dlab),LMQL 则出自 ETH Zurich SRI Lab,两者不得混写(正文"主要参与者"已按此修正)。
- 同一链接的双重用途:HN 讨论 #46332119 在两章中分别用作"假 100% 信任问题"与"Gemini best-effort"证据,合并为同一条信任问题证据。
- 去重:OpenAI Structured Outputs 详情、BFCL 时间线、Let Me Speak Freely 争论、vLLM/XGrammar、MCP 结构化输出、OpenRouter 等在两章重复出现的内容,各保留一次并置于最自然的小节。
未验证项(两章明示、本报告如实保留):BFCL 具体前十名分数(页面为 JS 渲染,未抓到,故未引用具体名次);Instructor/PydanticAI/BAML 的 GitHub 星数;Mistral/DeepSeek JSON mode 细节、TypeChat 归档现状、llama.cpp GBNF 现状;Outlines "98% vs 76%、约 2 倍"为培训材料转述的二手数据;modelcontextprotocol.io 与 modelcontextprotocol.info 两个规范域名的关系(主站/迁移/镜像)未核验;vLLM 合入 XGrammar 后端的具体版本未核验;两章以【背景】标注的早期事实(JSON Schema 规范史、PICARD、ChatGPT/GPT-4 发布时间等)未逐一复核。
附二:落地速查——最小组合示例、成本边界、监控要点与口径选择
正文读完最可能追问的五个操作性问题,在此基于文内证据直接回答;其中成本量化超出本研究范围,明确标注为后续研究建议。
1. P4 分层组合的最小示例。以 OpenAI 系 + Pydantic 为例(示意伪代码,按正文引用的官方用法整理,未在本次研究中实际运行):
schema = Invoice.model_json_schema() # Pydantic → JSON Schema:D 层契约载体
def ask(messages):
return client.chat.completions.create(
model="gpt-4o-2024-08-06",
response_format={ # ① 语法:A 层服务端约束解码(strict)
"type": "json_schema",
"json_schema": {"name": "invoice", "strict": True, "schema": schema},
},
messages=messages,
)
for attempt in range(3): # ③ 重试只喂错误 diff:C 层编排
raw = ask(messages).choices[0].message
if raw.refusal: # refusal 单独处理,不当解析失败重试
break
try:
return Invoice.model_validate_json(raw.content) # ② 语义:Pydantic 校验
except ValidationError as e:
messages.append({"role": "user",
"content": f"上次输出未通过校验,错误如下,请修正后重发:{e}"})
raise FallbackError() # ④ 降级:切模型/转人工(高可靠场景)自托管时把 ① 换成 vLLM+XGrammar(或 Ollama format 直收 JSON Schema),其余各步不变,并按下条加监控。
2. 各层延迟与重试成本的量化数字:本研究没有。两章证据里仅有的相关定量口径是:OpenAI strict 模式首次使用新 schema 的预处理延迟(典型 <10 秒、复杂 schema 可达 1 分钟,官方口径);Outlines 培训材料转述的"约 2 倍提速、98% 对 76%"(二手数据);单次社区实测的提示词约 10% 失败率(条件未详)。重试带来的 token 与延迟成本、各层叠加后的端到端延迟分布,两章均无实测数据——超出本研究范围,列为后续研究建议:用自有流量对 P0–P4 各档压测,记录失败率、重试次数分布与延迟分位数。
3. "静默回退可见"要监控什么(由文内证据推出的监控要点,非实测结论):
- 部署时静态检测:schema 用到 XGrammar 不支持的 JSON Schema 特性即告警或改写(具体特性清单以 vLLM 文档为准;讨论 #15213 记录了该回退场景);
- 运行时记录结构化输出后端实际生效的引擎(XGrammar / Outlines / guidance),回退事件计数并告警;
- 分层失败率仪表盘:JSON 解析失败、schema 校验失败、语义校验失败、重试、
refusal分别计数——语法问题冒充语义问题时能立刻分辨; - 聚合层场景:按 provider 维度记录
supported_parameters命中情况,路由变更时复查,必要时开require_parameters: true。
4. XGrammar 的 28x 与 100x 引用哪个:默认引论文口径"文法编译提速约 28 倍"(arXiv:2411.15100,可一手核验);"最高 100x"为媒体转述的官方口径、本次未一手核验,仅在注明来源性质时使用(见附录一裁定 #2)。
5. Anthropic beta 何时 GA:文内证据没有 GA 时间表;附录一裁定 #1 已指出"后转 GA"的说法无法被横轴证据支持。跟进方式:盯官方文档的 beta header(structured-outputs-2025-11-13)与 changelog,确认 GA 后再把它从"公测中"移入默认选型。
四、参考来源
官方文档与产品公告
- OpenAI, *Introducing Structured Outputs in the API*(2024-08-06,一手全文): https://openai.com/index/introducing-structured-outputs-in-the-api/
- OpenAI Structured Outputs 官方文档: https://platform.openai.com/docs/guides/structured-outputs
- OpenAI function calling 发布报道(2023-06-13): https://apidog.com/blog/openai-updates-gpt-3-5-turbo-and-gpt-4 ;https://artificialanalysis.ai/models/gpt-3-5-turbo-0613
- DevDay 2023 JSON mode: https://note.com/shigel_jp/n/nf9f70085e392?hl=en ;https://infinitytechstack.uk/openai-academy/function-calling-structured-outputs/structured-outputs-json-mode ;https://www.vrdmn.com/2024/01/get-structured-json-data-back-from-gpt.html
- OpenAI Responses API 社区讨论: https://community.openai.com/t/responses-api-documentation-on-structured-outputs-is-lacking/1356632/3
- Anthropic 工具调用 beta(2024-04): https://x.com/AnthropicAI/status/1775979799644934281
- Anthropic Structured Outputs 公告与文档: https://x.com/claudeai/status/1989410368192668037 ;https://platform.claude.com/docs/en/api/beta/messages/batches/results ;https://platform.claude.com/docs/en/build-with-claude/structured-outputs ;解读 https://daily.dev/posts/a-hands-on-guide-to-anthropic-s-new-structured-output-capabilities-3o27zi984 ;https://towardsdatascience.com/hands-on-with-anthropics-new-structured-output-capabilities
- Google Vertex controlled generation: https://discuss.google.dev/t/structured-output-in-vertexai-batchpredictionjob/179285/3 ;Gemini 字段名问题: https://discuss.ai.google.dev/t/structured-output-ignoring-schema-field-names/110880/3
- MCP 规范变更日志(2025-06-18,一手全文): https://modelcontextprotocol.io/specification/2025-06-18/changelog ;2025-03-26: https://spec.modelcontextprotocol.io/specification/2025-03-26/changelog/ ;最新修订 2025-11-25: https://modelcontextprotocol.info/specification/2025-11-25 ;发布公告(2024-11-25): https://www.anthropic.com/news/model-context-protocol 。域名说明:正文同时引用 modelcontextprotocol.io(2025-06-18 changelog,本次研究一手阅读)与 modelcontextprotocol.info(2025-11-25 修订版)两个域名,两者关系(主站/迁移/镜像)未核验,正式引用前请以官方 SDK 与产品公告指向的站点为准。
- OpenRouter 结构化输出: https://openrouter.ai/blog/announcements/structured-outputs-and-free-gemini-flash-20 ;https://openrouter.ai/docs/guides/features/structured-outputs ;https://openrouter.ai/docs/client-sdks/typescript/sdks/providers/README
- Ollama 结构化输出: https://ollama.com/blog/structured-outputs
- vLLM 结构化解码: https://vllm.ai/blog/2025-01-14-struct-decode-intro ;https://docs.vllm.ai/en/latest/features/structured_outputs.html
- XGrammar: https://xgrammar.mlc.ai ;报道 https://www.marktechpost.com/2024/11/24/cmu-researchers-propose-xgrammar-an-open-source-library-for-efficient-flexible-and-portable-structured-generation
- Outlines: https://github.com/dottxt-ai/outlines ;outlines-core: https://github.com/dottxt-ai/outlines-core
- Guidance: https://www.marktechpost.com/2023/05/18/microsoft-ai-releases-guidance-a-next-gen-language-for-prompt-programming ;https://github.com/guidance-ai/guidance ;https://blog.seeai.co.uk/control-llm-with-guidance-microsofts-alternative-to-langchain
- TypeChat: https://microsoft.github.io/TypeChat/docs/techniques ;https://www.devclass.com/ai-ml/2023/07/24/microsoft-previews-typechat-structured-conversational-ai-for-developers/1624792
- Guardrails AI: https://www.latent.space/p/guaranteed-quality-and-structure ;https://www.guardrailsai.com
- Instructor: https://github.com/jxnl/instructor ;https://python.useinstructor.com ;https://python.useinstructor.com/blog ;https://python.useinstructor.com/prompting/self_criticism/self_refine
- PydanticAI: https://github.com/pydantic/pydantic-ai ;Bedrock 检测不一致: https://github.com/pydantic/pydantic-ai/issues/4368
- llama.cpp GBNF: https://github.com/ggml-org/llama.cpp/issues/3303 ;https://github.com/ggml-org/llama.cpp/blob/master/tests/test-json-schema-to-grammar.cpp
论文与评测基准
- LMQL: https://arxiv.org/abs/2212.06094 ;https://github.com/eth-sri/lmql ;https://www.marktechpost.com/2023/07/29/eth-zurich-researchers-introduce-lmql-a-programming-language-for-language-model-interaction
- Outlines 论文(Efficient Guided Generation): https://arxiv.org/abs/2307.09702
- ToolDec: https://arxiv.org/html/2310.07075v3
- Berkeley Function-Calling Leaderboard: https://gorilla.cs.berkeley.edu/leaderboard.html ;CHANGELOG: https://github.com/ShishirPatil/gorilla/blob/main/berkeley-function-call-leaderboard/CHANGELOG.md
- τ-bench: https://openreview.net/revisions?id=OtpSDqHzeC
- Grammar-Aligned Decoding: https://arxiv.org/abs/2405.21047 ;https://neurips.cc/virtual/2024/poster/96599
- Let Me Speak Freely?: https://arxiv.org/abs/2408.02442 ;反方(ACL 2025 industry): https://aclanthology.org/2025.acl-industry.34.pdf
- CRANE(ICML 2025): https://arxiv.org/abs/2502.09061
- XGrammar 论文: https://arxiv.org/abs/2411.15100 ;XGrammar-2: https://arxiv.org/pdf/2601.04426 ;https://huggingface.co/papers/2601.04426
- JSONSchemaBench: https://arxiv.org/html/2501.10868v1 ;https://huggingface.co/datasets/epfl-dlab/JSONSchemaBench
- 2026 年研究: 结构化输出控制实证 https://arxiv.org/html/2606.09395v1 ;小模型约束解码 https://arxiv.org/abs/2609.23742 ;Constrained Decoding revisit https://arxiv.org/abs/2610.35328
工程实测与社区讨论
- SqueezeBits 后端实测(XGrammar vs LLGuidance): https://blog.squeezebits.com/guided-decoding-performance-vllm-sglang
- 提示词失败率实测: https://blogs.tanmaybohra.com/posts/stop-prompting-for-json-constrained-decoding
- vLLM 后端回退讨论: https://github.com/vllm-project/vllm/discussions/15213 ;约束泄漏到思维链通道: https://github.com/vllm-project/vllm/issues/44012
- MCP 校验失败语义讨论: https://github.com/modelcontextprotocol/python-sdk/issues/1702 ;https://github.com/modelcontextprotocol/csharp-sdk/issues/1551
- "假 100%"与 Gemini best-effort 信任讨论: https://news.ycombinator.com/item?id=46332119 ;聚合层社区反馈: https://www.reddit.com/r/openrouter/comments/1vzlcj8/why_do_structured_outputs_always_fail_except
(完)