Structured-Output与Constrained-Decoding

Structured-Output与Constrained-Decoding
Structured Output · JSON mode / Function Calling / Constrained Decoding / Schema 治理定位输出侧工程化的算法纵深专章。Function Calling 的工具编排见 15-MCP生产宿主Tool Schema 治理05-安全 §2.3 提过「结构化输出」本篇只挖**「怎么让 LLM 稳定产出合法结构化数据」的算法与工程**——三种路线的原理差异、Constrained Decoding 怎么在 logits 层强制、Schema 治理与生产坑。风格说明机制型为主——从「自由文本到结构化数据」的鸿沟出发拆解 JSON mode / Function Calling / Constrained Decoding 三条路线再讲 Schema 治理生命周期和与推理加速22的冲突。前置阅读01-Transformer理解 logits 与采样02-Prompt工程Tool Use 基础15-MCPTool Schema 治理。1. 本质为什么 LLM 输出结构化是工程刚需1.1 一句话定义Structured Output让 LLM 的输出严格符合预定义的结构JSON、XML、特定语法使下游系统Agent 工具调用、API 集成、数据管道能确定性解析而非靠正则从自由文本里抠。1.2 自由文本 vs 结构化的工程鸿沟维度自由文本输出结构化输出下游解析正则/LLM 抽取脆弱、概率失败json.loads()确定性失败率5-30%标点、转义、嵌套出错0.1%强约束可组合性无法直接喂下游 API直接作为 tool args校验事后 LLM-judgeSchema 校验编译期安全混入解释性废话schema 限定字段防越权工程金句「Agent 能不能可靠调工具取决于输出能不能稳定解析。Function Calling 不是模型能力问题是输出约束工程问题。」1.3 失败成本为什么不能靠 prompt 硬骗反例prompt 写「请只输出 JSON不要其他内容」 失败模式即使 GPT-4 也会 - 输出 json ... 代码块包裹需 strip - 字段名拼错 / 类型错number 写成字符串 - 多余字段 / 缺失必填字段 - 引号未转义导致 JSON 不合法 - 偶尔加一句「好的结果是」前缀 → 下游 json.loads() 抛异常 → Agent 工具调用失败 → 整条轨迹崩结论靠 prompt 约束输出 拿概率当确定性。生产必须用机制层强约束。2. 三条实现路线对比脆弱经常失败约束部分语法训练对齐格式logits 层强制Prompt 硬骗输出合法?Repair 重试2 JSON mode3 Function Calling4 Constrained Decoding100% 合法语法上不可能错路线机制合法率延迟开销灵活性适合1 Prompt Repair靠 prompt 约束 解析失败重试90-98%高重试高任何模型兜底/不支持 FC 的模型2 JSON mode模型内置强制 JSON 语法引号/括号合法~99%低中只保语法不保 schema简单 JSON3 Function Calling模型训练对齐 厂商解析层99%低中schema 内Agent 工具调用标配4 Constrained Decoding推理时 logits mask 强制符合 grammar~100%中推理时计算高任意 grammar自托管 严格 schema3. Constrained Decoding · 「语法上不可能错」的原理本章重点。这是自托管场景能做到100% 合法的根本手段。3.1 原理在采样时 mask 非法 tokenLLM 每生成一个 token本质是从 logits词表概率分布采样。Constrained Decoding 在采样前根据当前已生成内容和 grammarJSON Schema / 正则 / CFG把所有「会导致非法」的 token 概率置零——模型只能选合法 token。生成过程JSON Schema: {name: str, age: number} 已生成: {name: 张三, age: 当前合法 token: 数字字符0-9 ← logits 只保留这些 模型选: 2 5 已生成: {name: 张三, age: 25 当前合法 token: } 或 ,字段结束符 ← 只保留这些 模型选: } 结果: {name: 张三, age: 25} ← 语法上 100% 合法核心约束在采样层不是事后校验。模型不可能生成非法 token——因为它根本没机会选到。3.2 Grammar 的三种表达Grammar 类型表达力典型工具适合JSON Schema结构化数据outlines / xgrammar / 厂商 FCAgent 工具参数正则Regex线性模式outlines / guidance电话号/日期/枚举上下文无关文法CFG最强任意语法llama.cpp GBNFSQL/代码/DSL3.3 工程实现选型工具类型部署特点outlines开源库Python 自托管支持 JSON Schema/正则/CFG主流模型xgrammar开源库跨引擎vLLM/MLC 集成高性能 grammar 编译2024 主流llguidance开源库微软出品高性能 CFG厂商 FCOpenAI/Anthropic托管 APISaaS无需自管但绑厂商llama.cpp GBNF内置本地本地推理场景自托管 vLLM推荐xgrammar已深度集成 vLLM编译 grammar 后延迟开销 5%。outlines 更通用但工程化稍弱。3.4 与 Function Calling 的关系厂商 FCOpenAItools参数本质是厂商在 API 层帮你做了 constrained decoding 解析——黑盒。自托管想获得同等能力就用 outlines/xgrammar JSON Schema显式做 constrained decoding。两者可结合自托管用 grammar 强制 tool call 的 JSON 合法再用应用层解析tool_nameargs。4. Constrained Decoding 的代价与陷阱4.1 延迟开销grammar 编译 每步 logits mask 有成本。实测场景延迟开销简单 JSON Schema 5%复杂嵌套 schema10-20%CFGSQL/代码可达 30%优化预编译 grammarschema 固定时缓存 FSMxgrammar 用并行编译降低开销。4.2 与推理加速的冲突重要对齐 22-推理加速。Speculative Decoding 与 Constrained Decoding 存在张力Speculative 要求 draft 模型和主模型验证逻辑一致。若加 constrained decodingdraft 的候选也必须符合 grammar否则被 mask 掉接受率骤降。解法draft 阶段也跑同样的 grammar 约束部分引擎已支持否则 spec decoding 在结构化场景收益打折。金句「结构化输出和推理加速可以共存但要确保 draft 模型也走同样的 grammar——否则 speculative 的候选会被约束层全部否决加速归零。」4.3 质量陷阱合法但不正确最大陷阱Constrained Decoding 保证语法合法不保证语义正确。Schema: {order_id: string} 用户问: 查我的订单 模型输出: {order_id: 我不知道} ← 语法合法语义错误应对schema 层面加 enum / pattern 约束如order_id必须匹配\d{12}应用层加业务校验订单是否存在、是否属于该用户配合 LLM-judge 评估语义正确性02-Eval。4.4 覆盖率陷阱schema 变化重编译JSON Schema → FSM 的编译有成本。若 schema 每请求变化动态 schema每次重编译会吃延迟。应对schema 尽量稳定 缓存编译结果动态部分用 prompt 补充而非改 schema。5. Schema 治理生命周期对齐 15-MCP § Tool Schema 治理。本节讲输出 schema的治理输入侧 tool schema 在 15。迭代1 Schema 定义2 版本化3 编译缓存4 运行校验Repair5 监控合法率/失败模式阶段实践定义用标准 JSON Schemadraft 2020-12字段加 description enum pattern版本化schema 变更要版本号 向后兼容11-Registry 四维之一编译缓存grammar FSM 预编译缓存按 schema hash 索引运行校验constrained decoding 保语法 应用层保语义 失败 repair再生成监控合法率应 99%、repair 次数、语义错误率采样 LLM-judgeRepair 策略兜底即使有 constrained decoding也要留 repair 兜底应对极少数边界defsafe_parse(output:str,schema):try:datajson.loads(output)validate(data,schema)# 语义校验returndataexcept(JSONDecodeError,ValidationError):# repair把错误信息拼进 prompt 重生成最多 2 次returnretry_with_error(output,schema)原则constrained decoding 是第一道让合法率从 90% 提到 99.9%repair 是第二道兜 0.1%。不要只靠 repair也不要以为 constrained 就不需要 repair。6. STAR 实战Agent 工具调用从 92% 提到 99.8%情境S电商客服 Agent调用 8 个业务工具查单/退款/改地址…。工具参数靠 prompt 约束输出 JSON解析成功率 92%——8% 的请求因 JSON 非法导致工具调用失败用户感知「Agent 没反应」。任务T把工具调用成功率提到 99%不换模型。行动A分析失败8% 失败中60% 是语法错引号/转义/多余文本40% 是语义错字段值无效。上 Constrained Decoding自托管 vLLM集成 xgrammar把每个 tool 的 args schema 编译成 grammar约束 LLM 输出。语法合法率 → 99.95%。schema 强化给order_id加pattern: ^\d{12}$、reason加 enum让约束层连大部分语义错也挡掉。repair 兜底剩余 0.05% 用一次 retry。性能grammar 预编译缓存延迟开销 4%确认 spec decoding 的 draft 也走同 grammar§4.2。结果R工具调用成功率 92% → 99.8%Agent 整体任务完成率提升 6 个百分点延迟开销 4%可接受。7. 与相关章节的边界主题本章去这里看Tool Schema 治理 / MCP 工具编排输出 schema 侧15-MCP安全输出护栏 / 不盲信输出仅提校验05-安全 §2.3Speculative Decoding 冲突§4.222-推理加速制品四维版本schema 作为一维仅引用11-RegistryAgent 执行循环工具调用环节仅引用07-执行循环99. 面试速查 · 高频满分答Q1怎么让 LLM 稳定输出 JSON靠 prompt 够吗不够。靠 prompt 写「只输出 JSON」本质是拿概率当确定性——GPT-4 也会有 5-10% 失败代码块包裹、字段拼错、引号未转义、多余前缀。生产有四条路线①promptrepair兜底合法率 90-98%②JSON mode厂商内置强制语法~99%③Function Calling训练对齐解析层99%④Constrained Decoding推理时 logits mask~100%。生产标配是 FC 或 Constrained Decoding。Q2什么是 Constrained Decoding为什么能做到 100% 合法在采样层加约束——每生成一个 token根据当前已生成内容和 grammarJSON Schema/正则/CFG把所有「会导致非法」的 token 概率置零模型只能选合法 token。约束在采样层而非事后校验所以语法上不可能错——它根本没机会选到非法 token。工具选型自托管 vLLM 用 xgrammar已深度集成开销5%通用场景用 outlines厂商 API 用 FC厂商帮你做了。Q3Constrained Decoding 有什么代价和坑四个坑①延迟开销——grammar 编译每步 mask简单 schema 5%复杂嵌套 10-20%CFG 可达 30%要预编译缓存②与 Speculative Decoding 冲突——draft 的候选也必须符合 grammar否则被 mask 全否决加速归零解法是 draft 也走同样约束③合法但不正确——只保语法不保语义{order_id:不知道}也合法要加 enum/pattern 业务校验 LLM-judge④动态 schema 重编译——schema 每请求变化会吃延迟要缓存编译结果。Q4Function Calling 和 Constrained Decoding 是什么关系厂商 FCOpenAItools参数本质是厂商在 API 层帮你做了 constrained decoding 解析——黑盒省心但绑厂商。自托管想获得同等能力就用 outlines/xgrammar JSON Schema显式做。两者可结合自托管用 grammar 强制 tool call 的 JSON 合法再应用层解析 tool_nameargs。自托管 严格场景Constrained Decoding 是唯一能逼近 100% 合法率的手段。Q5你的 Schema 治理怎么做五步生命周期①定义——用标准 JSON Schema字段加 descriptionenumpattern②版本化——schema 变更走版本号向后兼容作为 11-Registry 四维之一③编译缓存——grammar FSM 预编译按 schema hash 缓存④运行校验——constrained decoding 保语法 应用层保语义 失败 repair⑤监控——合法率(99%)、repair 次数、语义错误率采样。原则constrained 是第一道90%→99.9%repair 是第二道兜底。Q6Agent 工具调用总是失败怎么排查先分失败类型语法错JSON 不合法还是语义错字段值无效。语法错→上 Constrained Decoding 或换支持 FC 的模型语义错→强化 schemaenum/pattern 业务校验 LLM-judge 监控。我实战把工具调用从 92% 提到 99.8%xgrammar 约束 schema 加 pattern repair 兜底延迟开销4%还确认了 spec decoding 的 draft 也走同 grammar 避免加速失效。一页 Checklist是否用 FC 或 Constrained Decoding而非纯 prompt 约束自托管是否集成了 xgrammar/outlinesgrammar 是否预编译缓存schema hash 索引schema 是否加了 enum/pattern/description是否有 repair 兜底constrained repair 双保险是否监控合法率、repair 次数、语义错误率Speculative Decoding 的 draft 是否走同样 grammar§4.2schema 变更是否版本化 向后兼容11-Registry官方文档与源码一级依据Structured Output· 本章机制依据官方文档L1与官方源码L2。写作规范docs/official-sources-registry.md §0L1 · 官方文档OpenAI - Structured Outputs / Function CallingAnthropic - Tool UseGoogle Gemini - Structured OutputvLLM - Guided Decoding (xgrammar/outlines)L2 · 官方源码dottxt-ai/outlinesStructured Generationmlc-ai/xgrammar高性能 grammar 编译microsoft/llguidanceCFG 约束guidance-ai/guidanceL3 · 论文Outlines: Fast Logits Extraction for Efficient Generation (Willard 2023)