你是怎么解决大模型不按要求输出标准JSON格式的?—— 一场技术面试实录

2026-04-13 12:311阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

1.开场:聊聊踩过的坑

王工:我看你简历上写了两年LLM应用开发经验。我问一些实战经验问题:你在项目里让大模型返回JSON,遇到过什么麻烦没?

小张:遇到过,特别在大模型初期,GPT-4那个时代,经常出现格式不稳定,有时候会多个逗号,有时候key不带引号,偶尔还包一层markdown代码块.

王工:那你当时是怎么解决?

小张:一开始就利用提示词,在prompt里反复强调"请严格输出JSON格式,不要包含任何其他内容"。然后利用fewcase引导,会有点用,但不彻底,大概能到七八成的准确率。

王工:嗯,那你分析过为什么prompt约束不彻底吗?

小张:有想过,例如模型生成文本的本质是逐Token采样,它并没有一个内置的JSON解析器在检查语法。它只是根据训练数据"学会"了JSON长什么样,但这是统计意义上的,不是规则意义上的。

王工:对,这点很关键。OpenAI早期的JSONMode测试下来,合格率大概只有35%左右.

2.第一回合:JSONSchema的原理

王工:那后来你们怎么解决的?

小张:大模型进步非常快,官方OpenAI发布的Structured Output, 直接 置response_format 为 json_schema, 再 开strict:true。基本输出就一定会按照指定格式输出了

王工:那你说说它的底层实现吧?

小张:我理解是把JSONSchema是借用状态机,模型每生成一个Token,FSM就转移一次状态,然后根据当前状态算出下一步合法的Token,不合法的Token概率直接置零,这样就避免输出错误结构。

王工:说得挺好的。那我在问深如一点,你遇到过第一次请求特别慢、后面就快了的情况吗?

小张:遇到过,不过倒是没研究,感觉是Schema编译成FSM需要时间,第一次要做预处理,后面同样的Schema能复用缓存。

王工:不错。还有个细节-那为什么不能把所有约束都提前处理好呢?

小张:(想了一下)因为有些约束是上下文相关的吧?比如某个字段的值必须是enum里的选项,这得看前面生成了什么才能判断。

3.第二回合:更新的一些JSON方案

王工:Structured Output是2024年下半年的)案了,最近有没有别的更好的方案出现?

小张:有的。例如Claude4.5就加了原生的结构化输出支持,用法跟OpenAI差不多,都是通过JSONSchema约束输出格式。

王工:那你用过吗?跟OpenAI的方案有什么差异?

小张:尝试过。Claude那边对嵌套结构和复杂类型的支持感觉更灵活一些,但首次延迟也存在。不过我没做过系统的对比测试,所以不太好回答两者差异。

王工:这个态度挺实在的,没测过就不瞎说。国内有其它方案吗?

小张:有的,通义干问也有结构化输出,能支持JSON Object JSON Schema两种模式。

王工:嗯。还有一个方案你可能没注意一OpenRouter 去年12月出了个ResponseHealing功能,了解吗?

小张:这个我还真不知道。

王工:它的思路不一样,不是在生成时进行token状态预测约束,而是直接在响应返回前自动修复格式问题。官方说能减少80%以上的JSON缺陷。这适合那些底层模型不支持JSONSchema约束的模型

小张:哦,相当于是个后处理的增强版?

王工:可以这么理解。

4.第三回合:方案选型怎么做

王工:我们来一个临场问题吧,假如现在让你给新项目选方案,你会怎么考虑或选择?

小张:我会先分场景。如果是调用API,可以直接用原生的Structured Output例如刚刚说的OpenAI、Claude、通义干问。

王工:如果用的模型或API不支持StructuredOutput呢?

小张:那就只能靠后处理了。第一种就是常见的代码兼容的方式,例如用json-repair库修复常见的格式问题,配合Pydantic做校验,失败了就重试。还有就是您提到的后处理方式ResponseHealing

5.收尾:几个容易忽略的坑

王工:最后问几个细节。你在生产环境用Structured Output,踩过t么坑?

小张:倒是有,例如Schema太复杂的时候会有状态爆炸问题,显存占用突然暴涨。我们后来直接团队内默认规则,要把Schema设计得尽量扁平,嵌套不允许超过三层。

王工:还有吗?

小张:有,当时还挺难发现的,是一个缓存失效问题,就是JSON的key顺序和Structured Output如果不一致,KVCache就没法复用,导致每次推理都会变慢。

王工:那在问最后一个,additionalProperties这个参数你怎么设的?

小张:设成false。不然模型可能会生成Schema之外的字段,下游解析会出问题。

王工:(点头)行,这个问题就聊到这。你对底层机制理解得挺深入的,新技术也在实时关注,不错。

小张:谢谢王工。

原文章来自: 小红书

网友解答:
--【壹】--:

遇到过,这时候就得换更好的模型了,或者改变生成逻辑,尽量别一次性输出所有的


--【贰】--:

感觉LLM这种上下文强相关的应用,不应该一次性把太复杂的业务塞到一个请求里,最好是能分步实现


--【叁】--:

本人刚入社区,不熟悉社规,以后需要引用的信息会放开头的,感谢指教


--【肆】--:

上下文多了加模型垃圾,这个不是很管用


--【伍】--:

json渲染页面并不好用,现在我们就不用这个来做,不过还有一点就可能是因为你们组件写的太复杂了,不够抽象化导致的


--【陆】--:

是的,巨复杂
这个五层 JSON 还要拿出来经过组件再转,所以对字段有严格要求准确性
后来考虑过先让模型输出不用管格式,再引入小模型转 JSON

各自专心的做一件事


--【柒】--:

我感觉有时候只能跑本地差模型,这种还是得考虑吧。而且好的模型应该是内置了状态机,不然按原理说的话没法100%结构化输出的


--【捌】--:

和模型强相关,但是主要看复杂度,一般来说json超过五层代表Agent业务拆的不对,需要重新规划设计


--【玖】--:

面试这么简单啊。就问一个点吗?还有信息来源放在最上面,看到后面才发现是小红书。


--【拾】--:

后来还引入了增量清洗,门禁一堆东西,就为了这个 JSON
现在搞吐了已经抛弃 JSON 了


--【拾壹】--:

现在也被json搞的头大~
前面加一层Pydantic,解决了标准json格式的问题~
但是经常缺字段!
设置默认值和可选,就可能 和程序逻辑 冲突或者不严谨~
不设置默认值和可选,虽然 和程序逻辑 完美契合了~但是就算加loop,在要求的字段错误的返回为空的时候,让llm去多循环几次,还是经常无法避免返回的字段为空问题~


--【拾贰】--:

本来是使用 JSON 做字段强约束,用于渲染页面的
发现效果实在不好


--【拾叁】--:

我们的项目里,五层的 JSON,在 BAML 的约束下,虽然返回了正确的 JSON 格式,但是总是缺字段错字段

垃圾模型尤其严重

佬有遇到过吗


--【拾肆】--:

随着模型进步其实很多问题不算是问题了,原本的开发经验不一定适用于后面的。

譬如中间的缓存失效的问题来说,在qwen3-8b的模型我就从来没有遇到过这个。

再比如中间的schema的设计问题,我们内部现在其实都不太用json格式来输出了,ison也用过但是感觉一般,现在其实是用yaml来做的。

感觉对面没怎么研究过非常新的技术,没怎么尝试过,像是去年的文章。


--【拾伍】--:

是的,这个也是我转发xhs经验贴,不过就我实习过的公司来看对json输出需求有的,没办法


--【拾陆】--:

我:那是你使用的差模型,用对了模型会不是标准json格式吗?


--【拾柒】--:

并且实际测试下来,让模型一边遵守多层的 JSON,一边满足提示词的需求,感觉注意力被分散,实际效果明显下降,现在转 md 了


--【拾捌】--:

我这边侧向传统的模型训练,对json格式输出要求还是挺多的


--【拾玖】--:

放1~2个例子,正则移除代码块标记,然后用json5解析

问题描述:

1.开场:聊聊踩过的坑

王工:我看你简历上写了两年LLM应用开发经验。我问一些实战经验问题:你在项目里让大模型返回JSON,遇到过什么麻烦没?

小张:遇到过,特别在大模型初期,GPT-4那个时代,经常出现格式不稳定,有时候会多个逗号,有时候key不带引号,偶尔还包一层markdown代码块.

王工:那你当时是怎么解决?

小张:一开始就利用提示词,在prompt里反复强调"请严格输出JSON格式,不要包含任何其他内容"。然后利用fewcase引导,会有点用,但不彻底,大概能到七八成的准确率。

王工:嗯,那你分析过为什么prompt约束不彻底吗?

小张:有想过,例如模型生成文本的本质是逐Token采样,它并没有一个内置的JSON解析器在检查语法。它只是根据训练数据"学会"了JSON长什么样,但这是统计意义上的,不是规则意义上的。

王工:对,这点很关键。OpenAI早期的JSONMode测试下来,合格率大概只有35%左右.

2.第一回合:JSONSchema的原理

王工:那后来你们怎么解决的?

小张:大模型进步非常快,官方OpenAI发布的Structured Output, 直接 置response_format 为 json_schema, 再 开strict:true。基本输出就一定会按照指定格式输出了

王工:那你说说它的底层实现吧?

小张:我理解是把JSONSchema是借用状态机,模型每生成一个Token,FSM就转移一次状态,然后根据当前状态算出下一步合法的Token,不合法的Token概率直接置零,这样就避免输出错误结构。

王工:说得挺好的。那我在问深如一点,你遇到过第一次请求特别慢、后面就快了的情况吗?

小张:遇到过,不过倒是没研究,感觉是Schema编译成FSM需要时间,第一次要做预处理,后面同样的Schema能复用缓存。

王工:不错。还有个细节-那为什么不能把所有约束都提前处理好呢?

小张:(想了一下)因为有些约束是上下文相关的吧?比如某个字段的值必须是enum里的选项,这得看前面生成了什么才能判断。

3.第二回合:更新的一些JSON方案

王工:Structured Output是2024年下半年的)案了,最近有没有别的更好的方案出现?

小张:有的。例如Claude4.5就加了原生的结构化输出支持,用法跟OpenAI差不多,都是通过JSONSchema约束输出格式。

王工:那你用过吗?跟OpenAI的方案有什么差异?

小张:尝试过。Claude那边对嵌套结构和复杂类型的支持感觉更灵活一些,但首次延迟也存在。不过我没做过系统的对比测试,所以不太好回答两者差异。

王工:这个态度挺实在的,没测过就不瞎说。国内有其它方案吗?

小张:有的,通义干问也有结构化输出,能支持JSON Object JSON Schema两种模式。

王工:嗯。还有一个方案你可能没注意一OpenRouter 去年12月出了个ResponseHealing功能,了解吗?

小张:这个我还真不知道。

王工:它的思路不一样,不是在生成时进行token状态预测约束,而是直接在响应返回前自动修复格式问题。官方说能减少80%以上的JSON缺陷。这适合那些底层模型不支持JSONSchema约束的模型

小张:哦,相当于是个后处理的增强版?

王工:可以这么理解。

4.第三回合:方案选型怎么做

王工:我们来一个临场问题吧,假如现在让你给新项目选方案,你会怎么考虑或选择?

小张:我会先分场景。如果是调用API,可以直接用原生的Structured Output例如刚刚说的OpenAI、Claude、通义干问。

王工:如果用的模型或API不支持StructuredOutput呢?

小张:那就只能靠后处理了。第一种就是常见的代码兼容的方式,例如用json-repair库修复常见的格式问题,配合Pydantic做校验,失败了就重试。还有就是您提到的后处理方式ResponseHealing

5.收尾:几个容易忽略的坑

王工:最后问几个细节。你在生产环境用Structured Output,踩过t么坑?

小张:倒是有,例如Schema太复杂的时候会有状态爆炸问题,显存占用突然暴涨。我们后来直接团队内默认规则,要把Schema设计得尽量扁平,嵌套不允许超过三层。

王工:还有吗?

小张:有,当时还挺难发现的,是一个缓存失效问题,就是JSON的key顺序和Structured Output如果不一致,KVCache就没法复用,导致每次推理都会变慢。

王工:那在问最后一个,additionalProperties这个参数你怎么设的?

小张:设成false。不然模型可能会生成Schema之外的字段,下游解析会出问题。

王工:(点头)行,这个问题就聊到这。你对底层机制理解得挺深入的,新技术也在实时关注,不错。

小张:谢谢王工。

原文章来自: 小红书

网友解答:
--【壹】--:

遇到过,这时候就得换更好的模型了,或者改变生成逻辑,尽量别一次性输出所有的


--【贰】--:

感觉LLM这种上下文强相关的应用,不应该一次性把太复杂的业务塞到一个请求里,最好是能分步实现


--【叁】--:

本人刚入社区,不熟悉社规,以后需要引用的信息会放开头的,感谢指教


--【肆】--:

上下文多了加模型垃圾,这个不是很管用


--【伍】--:

json渲染页面并不好用,现在我们就不用这个来做,不过还有一点就可能是因为你们组件写的太复杂了,不够抽象化导致的


--【陆】--:

是的,巨复杂
这个五层 JSON 还要拿出来经过组件再转,所以对字段有严格要求准确性
后来考虑过先让模型输出不用管格式,再引入小模型转 JSON

各自专心的做一件事


--【柒】--:

我感觉有时候只能跑本地差模型,这种还是得考虑吧。而且好的模型应该是内置了状态机,不然按原理说的话没法100%结构化输出的


--【捌】--:

和模型强相关,但是主要看复杂度,一般来说json超过五层代表Agent业务拆的不对,需要重新规划设计


--【玖】--:

面试这么简单啊。就问一个点吗?还有信息来源放在最上面,看到后面才发现是小红书。


--【拾】--:

后来还引入了增量清洗,门禁一堆东西,就为了这个 JSON
现在搞吐了已经抛弃 JSON 了


--【拾壹】--:

现在也被json搞的头大~
前面加一层Pydantic,解决了标准json格式的问题~
但是经常缺字段!
设置默认值和可选,就可能 和程序逻辑 冲突或者不严谨~
不设置默认值和可选,虽然 和程序逻辑 完美契合了~但是就算加loop,在要求的字段错误的返回为空的时候,让llm去多循环几次,还是经常无法避免返回的字段为空问题~


--【拾贰】--:

本来是使用 JSON 做字段强约束,用于渲染页面的
发现效果实在不好


--【拾叁】--:

我们的项目里,五层的 JSON,在 BAML 的约束下,虽然返回了正确的 JSON 格式,但是总是缺字段错字段

垃圾模型尤其严重

佬有遇到过吗


--【拾肆】--:

随着模型进步其实很多问题不算是问题了,原本的开发经验不一定适用于后面的。

譬如中间的缓存失效的问题来说,在qwen3-8b的模型我就从来没有遇到过这个。

再比如中间的schema的设计问题,我们内部现在其实都不太用json格式来输出了,ison也用过但是感觉一般,现在其实是用yaml来做的。

感觉对面没怎么研究过非常新的技术,没怎么尝试过,像是去年的文章。


--【拾伍】--:

是的,这个也是我转发xhs经验贴,不过就我实习过的公司来看对json输出需求有的,没办法


--【拾陆】--:

我:那是你使用的差模型,用对了模型会不是标准json格式吗?


--【拾柒】--:

并且实际测试下来,让模型一边遵守多层的 JSON,一边满足提示词的需求,感觉注意力被分散,实际效果明显下降,现在转 md 了


--【拾捌】--:

我这边侧向传统的模型训练,对json格式输出要求还是挺多的


--【拾玖】--:

放1~2个例子,正则移除代码块标记,然后用json5解析