← 返回题目列表

大模型输出的 JSON 不合法时应该如何修复?

高频 中等 第 6 / 25 题 更新于 2026/09/17
大模型JSON结构化输出容错

简化版

JSON 修复要先区分语法错误和语义缺失:多余逗号、代码围栏、引号不匹配可以用确定性解析或受限修复;缺少金额、枚举值非法、字段彼此矛盾不能靠修复模型猜。优先使用原生结构化输出或 Function Calling,服务端再做 Schema 与业务校验;修复次数设小上限,保留原始输出,失败后重新生成、降级或转人工。

详细版

推荐流水线是:提取候选 JSON → 严格解析 → 安全的确定性规范化 → JSON Schema 校验 → 业务规则校验。只有可证明不改变含义的修改才自动做,例如去掉 Markdown 围栏或 UTF-8 BOM;补全缺失字段属于语义生成,必须带原输入重新调用模型并明确缺口。

raw output
 -> extract one candidate
 -> strict parse
 -> bounded syntax repair
 -> schema validate
 -> business validate
 -> accept / regenerate / reject

避免正则贪婪截取第一个 { 到最后一个 },它会被解释文本和嵌套对象破坏。解析器应限制输入大小、嵌套深度和数字范围,防止资源攻击。每次记录错误类型、修复 diff、尝试次数和最终状态;高风险字段不能静默默认。

完整版教学

一、先把“JSON 不合法”拆成不同问题

输出可能根本不是 JSON,也可能语法合法但不符合 Schema,或 Schema 合法却违反业务规则。三类失败的修复方式完全不同。

例如 {"amount":100,} 是语法错误;{"amount":"一百"} 可能是类型错误;{"amount":1000} 在最多退款 500 元的业务中是规则错误。只调用一个“JSON 修复器”会把它们混在一起。

记忆钩子:修括号是语法,补字段是生成,判金额是业务;三层不能互相冒充。

二、源头上优先减少自由格式生成

若平台支持受 Schema 约束的结构化输出,应优先使用;工具调用场景则用 Function Calling。它们能显著减少围栏、解释文字和括号错误,但仍不保证字段事实正确。

提示中给出明确 Schema、枚举和一个正例也有帮助。不要同时要求“先详细解释推理,再只返回 JSON”,冲突指令容易让解释混进输出。

即使供应商宣称严格模式,客户端仍应解析和校验,因为网络截断、版本变化和业务约束仍可能失败。

三、候选提取不能靠贪婪正则

输出可能包含“结果如下:”和 Markdown 围栏,也可能有字符串内部的花括号。\{.*\} 的贪婪或非贪婪匹配都不了解 JSON 字符串转义与嵌套层级。

更稳的做法是使用流式 JSON 解码器从候选起点解析一个完整值,或要求协议层直接返回结构化对象。若输出包含多个对象,应根据契约明确拒绝,而不是随意选第一个。

bad:  explanation {"text":"a } b"} trailing
                 ^ 字符串里的 } 不能结束对象

四、自动语法修复必须保守

删除 BOM、剥离明确代码围栏、标准化换行通常不改变语义。把单引号替换成双引号则可能破坏文本中的撇号;自动补括号也可能掩盖响应被截断。

错误可否自动修原因
UTF-8 BOM可以不改变数据
明确 JSON 围栏可以只去展示包装
尾逗号谨慎可定位时含义通常明确
缺失右括号通常重生成可能是传输或长度截断
缺少必填字段不可猜缺少业务事实

修复后保存 diff,让监控知道系统修了什么,而不是只记录最终成功。

五、Schema 验证负责结构契约

Schema 校验必填字段、类型、枚举、长度和附加字段。例如把 additionalProperties 设为 false 可防止模型返回未预期字段,但兼容升级时要管理 Schema 版本。

{
  "type": "object",
  "required": ["category", "score"],
  "properties": {
    "category": {"enum": ["spam", "normal"]},
    "score": {"type": "number", "minimum": 0, "maximum": 1}
  },
  "additionalProperties": false
}

Schema 错误应以字段路径反馈给重生成模型,如 /score must be <= 1,比笼统说“JSON 错了”更容易修正。

六、语义校验不能用默认值掩盖

字段齐全不代表关系正确。开始时间必须早于结束时间,百分比之和可能要求等于 100%,退款金额不能超过原支付。这些规则由领域代码或权威服务执行。

若模型漏了 currency,自动填 CNY 只有在业务上下文明确保证时才安全;否则默认值会把“不知道”变成错误事实。可选字段也要区分“未提供”和“明确为空”。

高风险数据校验失败后应停止,不因修复次数用完就绕过规则。

七、重生成要携带原任务和精准错误

让修复模型只看坏 JSON,可能不知道缺失值从哪里来。重生成请求应包含原输入、原 Schema、坏输出和精简的验证错误,并要求仅纠正指定问题。

最多尝试一到两次;同类错误重复出现说明模型或契约不适合,继续循环只会烧 token。第一次输出 95% 可用、第二次修复 80% 剩余失败时,总成功率约为:

95% + 5% × 80% = 99%

再多轮的边际收益很小,却增加延迟和不可预测修改。

八、安全与可观测性不能遗漏

限制原始输出大小、嵌套深度、数组长度和数值范围,防止极端 JSON 耗尽解析资源。解析后使用普通数据对象,禁止反序列化成可执行类型或把字段直接拼 SQL、命令和模板。

监控解析失败率、Schema 失败率、业务失败率、修复成功率、平均尝试数和被修改字段。模型或 Prompt 更新后按错误类别比较,而不是只看最终 JSON 成功率。

日志保留原始输出需脱敏;生产秘密不应因一次解析异常进入错误平台。

九、常见误区与追问

  • 误区:用正则提取第一对花括号就行。 正则不理解嵌套与字符串转义。
  • 误区:JSON 能解析就可以进入业务。 还需 Schema 和业务不变量校验。
  • 误区:缺字段时填默认值最稳。 默认值可能把未知变成错误事实。
  • 误区:让模型无限修到成功。 应限制次数,重复失败后降级或人工处理。
  • 误区:结构化输出模式无需客户端验证。 网络截断与语义错误仍然存在。
  • 追问:什么时候可自动补括号? 只有能证明响应完整且修复不改变含义时;长度截断应重生成。
  • 追问:修复模型要看什么? 原任务、Schema、坏输出和精确字段错误,避免凭空补事实。
  • 追问:如何防止修复改变正确字段? 比较修复 diff,锁定已通过字段,并重新执行全部验证。

十、加强记忆

JSON 修复记住“三层关卡”:解析器管语法,Schema 管结构,领域规则管语义。先用结构化输出减少错误,再做保守、可记录的确定性清理;缺失事实不能靠补括号式修复,而要带原任务精准重生成。限制次数、输入规模和嵌套深度,保留原文与 diff,并在任何修复后重新跑完整验证。