返回文章列表
LLMStructured OutputJSON Schema可靠性工程化

结构化输出可靠性:JSON 崩坏的 7 种原因(以及可落地修复链路)

结构化输出失败不是“模型太笨”,而是系统契约不完整:Schema 不严、上下文污染、输出过长、工具回执漂移、重试导致重复执行……本文总结 JSON 崩坏最常见的 7 个根因,并给出可直接落地的修复链路:严格 Schema、分层解析、自动修复、回执校验、幂等与观测指标,帮助你把结构化输出从 demo 拉到生产。

2026年3月4日
Synthly 团队
预计阅读 17 分钟
结构化输出可靠性:JSON 输出崩坏的常见原因与修复链路示意

📷 Photo by Photomandi PK via Pexels

先把话说透:JSON 崩坏是系统问题,不是“再调一调 prompt”

结构化输出一旦进入生产,你面对的就不是“偶尔格式不好看”,而是:

  • 解析失败 → 请求失败
  • 字段漂移 → 下游逻辑误判
  • 重试风暴 → 成本飙升/重复执行

所以本文按“根因 → 修复”来讲。


一、原因 1:Schema 太松(或根本没有)

常见错误:

  • 允许 additionalProperties
  • 字段类型没约束(string/number 混用)
  • 枚举值不限制

修复要点:

  • 输入 Schema 严格:additionalProperties: false
  • 输出结构固定:{ success, data, error }
  • 错误码可枚举:error.code

二、原因 2:输出合同不清晰(字段存在,但意义不清)

很多团队以为“有字段就行”,但字段语义不清会导致:

  • 字段填了,但不满足业务约束
  • 必填字段被填成占位符

修复要点:

  • 在 prompt 里写清:每个字段的语义与约束
  • 用业务校验器验证(不仅是 schema 校验)

三、原因 3:模型被“解释性文本”诱导(JSON 混入自然语言)

症状:

  • JSON 前后出现解释段落
  • 在字段里塞了整段说明

修复要点:

  • 把“解释”与“结构化输出”分开:
    • 结构化部分只输出 JSON
    • 解释部分放到另一个字段或另一个响应
  • 使用明确的输出指令:只允许一个 JSON 对象

四、原因 4:上下文污染(历史对话把格式带偏)

当历史消息里出现:

  • 旧版字段
  • 不同格式示例
  • 用户粘贴的 JSON 片段

模型可能被带偏。

修复要点:

  • 在系统层做消息分区:系统政策/示例/用户输入分离
  • 对关键字段用“版本号”控制
  • 对示例做最小化与一致性治理

五、原因 5:输出太长(括号配对与注意力崩坏)

输出越长,越容易出现:

  • 括号丢失
  • 数组元素缺逗号
  • 字符串未转义

修复要点:

  • 分段生成:先生成结构骨架,再填充细节
  • 对大字段做分页/引用(不要一次塞进 JSON)
  • 对代码/长文本字段做 base64 或外部存储引用(按场景)

六、原因 6:工具回执漂移(Observation 变形导致字段漂移)

如果你把工具回执原样塞进上下文,回执结构变动会导致:

  • 模型“猜测”缺失字段
  • 字段命名随回执变化

修复要点:

  • 回执先做提取与摘要(结构化观察摘要)
  • 对回执做 schema 校验与版本化

与 ReAct/工具调用相关的闭环可参考:


七、原因 7:重试策略错误(解析失败 → 无限重试 → 成本爆炸)

最危险的链路:

  • JSON 解析失败
  • 系统直接重试同样 prompt
  • 模型依旧失败
  • 重试风暴出现

修复要点:

  • 重试要带“修复指令”,不是原样重试
  • 限制重试次数,超过阈值走 fallback
  • 对写操作必须幂等,避免重复执行

稳定性基线可参考:


八、可落地的修复链路(建议直接照搬)

你可以把结构化输出做成一个管道:

  1. 生成:模型输出 JSON(只输出 JSON)
  2. 解析:严格 JSON parse
  3. Schema 校验:不通过则进入 repair
  4. Repair:用“最小修复指令”让模型修复 JSON(带上错误信息)
  5. 业务校验:必填字段、枚举、跨字段约束
  6. 最终 fallback:拒绝/追问/人工确认
  7. 观测:记录 parseFail、schemaFail、repairSuccess

伪代码:

resp = llm(prompt)
json = tryParse(resp)
if !json: resp = llm(repairPrompt(resp, parseError))
validateSchema(json)
validateBusiness(json)
return json

关键不是代码,而是“每一步都有清晰的失败出口”。


九、上线指标:你要能回答“现在到底稳定吗”

建议至少做这些分组指标:

  • 按模型版本:parseFail%、schemaFail%、repairSuccess%
  • 按提示词版本:同上
  • 按任务类型:同上
  • 按工具类型:回执漂移导致的失败占比

当你能把失败归因到“某版本 + 某任务 + 某字段”,结构化输出才算进入工程可控状态。


常见问题

Repair 会不会引入新的幻觉?

会,所以 repair 只做“语法与结构修复”,不要在 repair 阶段让模型改语义。业务语义应由业务校验与工具证据保证。

我能不用模型做 repair 吗?

可以。对常见错误(缺括号、尾逗号、引号转义),可以用确定性修复器先尝试;修不了再交给模型。这样更省钱,也更可控。

想看更多工程化文章见 /articles,也可以在 /apps/new 体验 Agent 能力。