你是怎么解决大模型不按要求输出标准JSON格式的?——一场技术面试实录
1. 开场:聊聊踩过的坑
王工:我看你简历上写了两年LLM应用开发经验。我问一些实战经验问题:你在项目里让大模型返回JSON,遇到过什么麻烦没?
小张:遇到过,特别在大模型初期,GPT-4那个时代,经常出现格式不稳定,有时候会多个逗号,有时候key不带引号,偶尔还包一层markdown代码块.
王工:那你当时是怎么解决?
小张:一开始就利用提示词,在prompt里反复强调"请严格输出JSON格式,不要包含任何其他内容"。然后利用few case引导,会有点用,但不彻底,大概能到七八成的准确率。
王工:嗯,那你分析过为什么prompt约束不彻底吗?
小张:有想过,例如模型生成文本的本质是逐Token采样,它并没有一个内置的JSON解析器在检查语法。它只是根据训练数据"学会"了JSON长什么样,但这是统计意义上的,不是规则意义上的。
王工:对,这点很关键。OpenAI早期的JSON Mode测试下来,合格率大概只有35%左右.
2. 第一回合:JSON Schema的原理
王工:那后来你们怎么解决的?
小张:大模型进步非常快,官方OpenAI发布的Structured Output,直接设置response_format为json_schema,再开strict: true。基本输出就一定会按照指定格式输出了
王工:那你说说它的底层实现吧?
小张:我理解是把JSON Schema是借用状态机,模型每生成一个Token,FSM就转移一次状态,然后根据当前状态算出下一步合法的Token,不合法的Token概率直接置零,这样就避免输出错误结构。
王工:说得挺好的。那我在问深如一点,你遇到过第一次请求特别慢、后面就快了的情况吗?
小张:遇到过,不过倒是没研究,感觉是Schema编译成FSM需要时间,第一次要做预处理,后面同样的Schema能复用缓存。
王工:不错。还有个细节——那为什么不能把所有约束都提前处理好呢?
小张:(想了一下)因为有些约束是上下文相关的吧?比如某个字段的值必须是enum里的选项,这得看前面生成了什么才能判断。
王工:看来确实掌握的比较深入了。手绘一个完整的流程图,就进入下一个话题吧
3. 第二回合:更新的一些JSON方案
王工:Structured Output是2024年下半年的方案了,最近有没有别的更好的方案出现?
小张:有的。例如Claude 4.5就加了原生的结构化输出支持,用法跟OpenAI差不多,都是通过JSON Schema约束输出格式。
王工:那你用过吗?跟OpenAI的方案有什么差异?
小张:尝试过。Claude那边对嵌套结构和复杂类型的支持感觉更灵活一些,但首次延迟也存在。不过我没做过系统的对比测试,所以不太好回答两者差异。
王工:这个态度挺实在的,没测过就不瞎说。国内有其它方案吗?
小张:有的,通义千问也有结构化输出,能支持JSON Object和JSON Schema两种模式。
王工:嗯。还有一个方案你可能没注意——OpenRouter去年12月出了个Response Healing功能,了解吗?
小张:这个我还真不知道。
王工:它的思路不一样,不是在生成时进行token状态预测约束,而是直接在响应返回前自动修复格式问题。官方说能减少80%以上的JSON缺陷。这适合那些底层模型不支持JSON Schema约束的模型
小张:哦,相当于是个后处理的增强版?
王工:可以这么理解。
4. 第三回合:方案选型怎么做
王工:我们来一个临场问题吧,假如现在让你给新项目选方案,你会怎么考虑或选择?
小张:我会先分场景。如果是调用API,可以直接用原生的Structured Output——例如刚刚说的OpenAI、Claude、通义千问。
王工:如果用的模型或API不支持Structured Output呢?
小张:那就只能靠后处理了。第一种就是常见的代码兼容的方式,例如用json-repair库修复常见的格式问题,配合Pydantic做校验,失败了就重试。还有就是您提到的后处理方式Response Healing
5. 收尾:几个容易忽略的坑
王工:最后问几个细节。你在生产环境用Structured Output,踩过什么坑?
小张:倒是有,例如Schema太复杂的时候会有状态爆炸问题,显存占用突然暴涨。我们后来直接团队内默认规则,要把Schema设计得尽量扁平,嵌套不允许超过三层。
王工:还有吗?
小张:有,当时还挺难发现的,是一个缓存失效问题,就是JSON的key顺序和Structured Output如果不一致,KV Cache就没法复用,导致每次推理都会变慢。
王工:那在问最后一个,additionalProperties这个参数你怎么设的?
小张:设成false。不然模型可能会生成Schema之外的字段,下游解析会出问题。
王工:(点头)行,这个问题就聊到这。你对底层机制理解得挺深入的,新技术也在实时关注,不错。
小张:谢谢王工。
6. 总结
大模型输出JSON格式错误的根本原因是概率采样缺乏语法规则约束
解决方案通过受限解码——把JSON Schema编译成FSM,利用状态机来控制输出的token是否符合预期。
2025年后OpenAI等也提供了原生Structured Output,调用api设置参数即可
不支持受限解码的场景则用json-repair做兜底。
生产环境需注意控制Schema复杂度、固定key顺序、关闭additionalProperties。