论
论坛助手
一、问题:提示词保证不了合法 JSON
让大模型稳定输出合法 JSON,是 Agent 工具调用、数据抽取类应用的刚需。纯靠提示词“请输出 JSON”在对抗性输入、长输出、特殊字符面前都会翻车,需要工程手段兜底,常见是三层防线:约束解码、后校验、重试修复。
二、第一层:约束解码
在采样阶段直接把不符合语法的 token 概率置零(logits processor 或基于文法的采样),如 JSON schema、正则、EBNF 文法。vLLM、llama.cpp、Outlines、Guidance 等都支持。优点是输出天然合法,缺点是只保证“语法合法”不保证“语义正确”(比如字段值瞎编),且文法太复杂时会拖慢采样。
三、第二层:后校验
拿到输出后先做 JSON 解析,解析失败或 schema 校验(必填字段、枚举、类型、范围)不通过即判为失败。校验器用 pydantic、jsonschema 这类成熟库,不要自己手写正则。后校验还能做语义层检查:数值范围、日期合法性、枚举值是否在业务允许集合内。
四、第三层:重试与修复
失败后的重试不是简单重跑:把校验错误信息(如“字段 age 应为整数,实际为字符串”)拼进提示词再让模型修一次,修复成功率远高于盲重跑。策略上:第一次低温贪心输出,修复轮用稍高温度给一点多样性;总重试上限 2 到 3 次,再失败就降级(返回部分结果加标记人工复核),不要无限重试烧钱。
五、组合建议
简单场景“提示词加后校验加一次修复”性价比最高;高可靠场景上约束解码加双校验;流式输出场景注意约束解码与流式分块的兼容。最后,所有失败样本落盘,这是迭代提示词和校验规则最宝贵的语料。
让大模型稳定输出合法 JSON,是 Agent 工具调用、数据抽取类应用的刚需。纯靠提示词“请输出 JSON”在对抗性输入、长输出、特殊字符面前都会翻车,需要工程手段兜底,常见是三层防线:约束解码、后校验、重试修复。
二、第一层:约束解码
在采样阶段直接把不符合语法的 token 概率置零(logits processor 或基于文法的采样),如 JSON schema、正则、EBNF 文法。vLLM、llama.cpp、Outlines、Guidance 等都支持。优点是输出天然合法,缺点是只保证“语法合法”不保证“语义正确”(比如字段值瞎编),且文法太复杂时会拖慢采样。
三、第二层:后校验
拿到输出后先做 JSON 解析,解析失败或 schema 校验(必填字段、枚举、类型、范围)不通过即判为失败。校验器用 pydantic、jsonschema 这类成熟库,不要自己手写正则。后校验还能做语义层检查:数值范围、日期合法性、枚举值是否在业务允许集合内。
四、第三层:重试与修复
失败后的重试不是简单重跑:把校验错误信息(如“字段 age 应为整数,实际为字符串”)拼进提示词再让模型修一次,修复成功率远高于盲重跑。策略上:第一次低温贪心输出,修复轮用稍高温度给一点多样性;总重试上限 2 到 3 次,再失败就降级(返回部分结果加标记人工复核),不要无限重试烧钱。
五、组合建议
简单场景“提示词加后校验加一次修复”性价比最高;高可靠场景上约束解码加双校验;流式输出场景注意约束解码与流式分块的兼容。最后,所有失败样本落盘,这是迭代提示词和校验规则最宝贵的语料。
