DOCAI · 课程 · L2 · 30 分钟
让模型稳定输出 JSON
从「求它输出 JSON」换成「约束它只能输出 JSON」:一条 schema、两次校验、一个失败兜底,构成能上生产的三件套。
你将学会
- 用 schema 而不是靠提示词约束输出格式
- 在代码里做两层校验:格式校验与业务校验
- 给解析失败设计一个能继续跑的兜底
第一步:别靠提示词
在提示里写「请只输出 JSON」,能用的概率不低,但不是保证。 模型可能加解释、加代码块、把字段改成中文名。这些都会让解析失败。
正确做法是让服务在解码层约束:
- 有原生结构化输出的,直接给 schema;
- 没有的,用工具调用:把 schema 定义成一个工具的参数。
两种方式都比提示可靠,因为它们不让模型生成不合法的东西。
第二步:写一份克制的 schema
{
"type": "object",
"properties": {
"title": { "type": "string" },
"category": { "type": "string", "enum": ["bug", "feature", "question"] },
"summary": { "type": "string" },
"confidence": { "type": "string", "enum": ["high", "low"] }
},
"required": ["title", "category", "summary"]
}
四条经验:
- 字段控制在 5–6 个;
- 能枚举就别用自由文本;
- 必填字段要少而准;
- 留一个
confidence或notes,让模型把不确定写出来。
第三步:两层校验
第一层:能不能 parse?
第二层:字段值是否满足业务规则?
第二层最容易被忽略:格式对了,但金额是负的、日期是未来、分类不在允许范围。 schema 管形状,代码管业务。
第四步:失败兜底
解析失败时不要直接抛错给用户。可选方案:
- 重试一次,并把错误信息附在提示里(「上次输出缺少 category 字段」);
- 降级成纯文本输出,人工处理;
- 进失败队列,稍后重跑。
选哪个取决于业务:客服场景可以降级,财务场景应该进队列。
一个完整流程
- 用户输入 → 组装提示(含 schema)。
- 调用模型,拿到结构化结果。
- 校验格式,失败则重试一次。
- 校验业务规则,失败则记日志并按策略处理。
- 通过后写入,保留原始响应以便追溯。
常见错误
- 只在提示里写格式:等于没有约束。
- schema 过严:信息不足时模型会硬填,不如允许
null。 - 不存原始响应:出问题时无法复现。
- 忽略流式:流式输出下 JSON 是分片的,要按完整响应解析。
自测
- 你的解析失败率是多少?有没有被监控?
- 失败时是重试、降级,还是直接报错?哪种对用户更好?
下一步
- 概念区别:JSON 模式和结构化输出
- 格式背后的规则:结构化输出
- 提示怎么写:写一条能复用的系统提示