AI 输出选 JSON Schema、Markdown 还是纯文本?先看谁要消费
按下游消费者选择 AI 输出协议,区分 JSON 语法、Schema 和业务正确性,并为拒绝、截断与解析失败设计出口。
所属问题主题上下文与 Prompt↗先带着一个真实任务阅读,再完成页面中的工作台。能让另一位同事复核你的产物,才算完成本课。
同一段 AI 回答,给人看和交给程序执行,风险完全不同。人能看懂“约在昨晚”,程序却可能把它写成一个精确时间;人在网页上能读懂标题,解析器却可能把标题顺序误当成字段。选输出格式时,先写清谁消费、消费后做什么、缺字段时停在哪里,再决定用 JSON Schema、Markdown 或纯文本。
这件事与Prompt 验收契约相邻,但解决的是不同一层:验收契约规定内容、证据和不确定性是否合格;本页规定结果怎样交到下游,以及不合格式或不完整时系统怎样处理。若模型要调用外部函数,参数和真实执行仍应遵循工具调用契约;不要拿给用户看的响应格式代替工具的输入授权。
从消费者倒推格式
| 下游要做的事 | 优先考虑 | 真正要固定的边界 |
|---|---|---|
| 将多个字段送入代码、数据库或界面组件 | 受支持的严格 JSON Schema 输出 | 字段、类型、枚举、缺失值、额外字段与版本;消费前校验 |
| 给人审阅一份分段说明或清单 | Markdown | 标题和列表服务阅读,不让代码从标题位置猜业务字段;配置可信渲染器 |
| 给语音、短信或仅显示一行的界面 | 纯文本 | 长度、术语、绝对时间与换行;若只接受固定代码,逐字匹配允许值 |
| 程序与人都需要同一事实 | 结构化数据加单独的展示层 | 程序读取字段,界面另行渲染;两层使用同一份已校验事实 |
Markdown 可以用专门的解析器处理,纯文本也能约定有限代码;这里并非说它们“不能被程序读取”。关键是:如果下游依赖某个字段,标题、粗体或自然语言位置就不能悄悄充当未经版本管理的接口。反过来,仅供人看的几句话,不必强行包成 JSON 再让用户读引号和括号。
JSON、JSON mode 与严格 Schema 是三种不同保证
Prompt 里写“请输出 JSON”只是要求;JSON mode 由 API 限制为 JSON 语法,但不保证必需字段、类型或枚举符合你的结构。提供商的严格结构化输出在受支持的模型和接口上进一步约束指定的 JSON Schema。OpenAI 和 Anthropic 都明确列出子集及例外;不能把完整 JSON Schema 标准里的任意关键字都假定为该 API 已强制执行。OpenAI 要求严格输出的根为对象、所有字段为必填,并给对象设置 additionalProperties: false;不知道的值可用允许 null 的字段表达。Anthropic 的部分 SDK 会把 API 不支持的约束转为描述,并由相应 helper 在本地校验;更换 helper 或直接调用 API 时必须重新确认实际保证。
在接入表里记下提供商、API、模型版本、Schema 版本和核对日期。先用一条正常输入、一条缺信息输入验证真实接口,再考虑上线。即使结构完全符合,地点、日期、引用和业务决定仍可能错;这属于语义和事实校验,Schema 无法替你完成。
案例一:把设施报修文本送进只读待核队列
一条合成报修写着:“东馆二楼扶梯昨晚停了,屏幕显示 E04。报修人没有提及受伤情况。”接收程序只要把信息送入待核队列,不能自动派工、结案或推断伤情。“昨晚”没有绝对日期,不能为了填满字段而猜一个时间。
可将响应约束为下面的简化结构。它是供读者调整的跨平台示意,实际接入时仍须核对所用 API 支持的关键字,并在应用端复查。
{
"type": "object",
"properties": {
"location": { "type": "string" },
"asset_type": { "type": "string", "enum": ["escalator", "other"] },
"observed_at": { "type": ["string", "null"] },
"error_code": { "type": ["string", "null"] },
"injury_status": { "type": "string", "enum": ["reported", "explicitly_denied", "unknown"] }
},
"required": ["location", "asset_type", "observed_at", "error_code", "injury_status"],
"additionalProperties": false
}
这条输入的合格候选为 {"location":"东馆二楼","asset_type":"escalator","observed_at":null,"error_code":"E04","injury_status":"unknown"}。null 表示无法从输入得知可用的绝对时间;unknown 表示没有伤情信息,而不是“确认无人受伤”。程序可展示待补问题,但不能替现场人员作安全判断。
下列四种失败要按首个出错关卡分开诊断。max_output_tokens 或流未完成属于响应边界;只有提供商报告完整结束、正文却不是合法 JSON,才把它归入语法错误。
| 输出片段 | 首个失败层 | 处理 |
|---|---|---|
提供商报告达到输出上限,正文停在 {"location":"东馆二楼", | 响应边界 | 整条拒收,不把未完成流入库;按明确的截断策略处理 |
提供商报告完整结束,正文却是 {"location":"东馆二楼", | JSON 语法 | 拒收并记录解析错误;有限重试只适用于没有外部效果的生成 |
"injury_status":"none" | Schema 枚举 | 拒收并记录字段路径;不得默默改成 unknown |
"observed_at":"昨晚" 或猜出的精确日期 | 业务语义 | 前者不是约定的绝对时间,后者无来源;转待核并要求日期资料 |
第四行说明为何只有“JSON 能解析”远远不够。一个字符串值可以通过基本类型检查,却仍违反“时间必须可追溯且精确到带时区的日期时间”这条业务规则。若使用更强的格式约束,也要检查当前提供商是否真的强制该关键字;来源是否支持这个日期,仍需独立复核。
案例二:同一展馆交接,分别给网页和值班电话
另一条合成记录写着:“西厅投影仪灯泡已更换;解说牌字体尚待确认;馆长将在 2026 年 10 月 4 日 10:00(上海时间,UTC+08:00)复核。”值班员在网页上浏览,可用 Markdown 把已完成、待确认和下一步分成标题与清单,让人快速复核。网页应按既定 Markdown 渲染规则处理链接和 HTML,不能直接把未受信内容当作可信页面代码。这个排版是给人看的,程序不应依靠“第二个标题下面第一条”来决定任务状态。
电话语音或短信则适合纯文本:“西厅投影仪灯泡已更换。解说牌字体待确认。馆长将在 2026 年 10 月 4 日 10:00(上海时间)复核。”去掉 Markdown 标记,保留绝对时间、时区与未完成事项。若交接还要更新工单,先保存经过校验的结构化事实,再由界面和短信分别生成展示文字;不要从展示文字反向抽取工单字段。
先检查响应状态,再解析完整内容
把一次生成交给下游之前,按顺序过门槛:
- **响应边界。**请求是否成功,流是否结束,提供商有没有报告拒绝、输出上限、内容截断或其他未完成状态?严格结构化输出也可能因拒绝或截断而不符合 Schema。遇到拒绝,走业务允许的说明或人工路径,不通过换措辞绕过;遇到截断,不把已收到的半段数据作为成功结果。
- **语法与结构。**仅在完整响应上解析 JSON,再校验 Schema 版本、字段、类型、枚举和多余字段。流式展示可以先显示“处理中”,但不能把尚未闭合的 JSON 对象写入正式记录。对于 JSON mode,结构校验尤其不可省;对于严格模式,也要处理接口、SDK 和模型版本变化及例外状态。
- **事实与业务规则。**日期是否来自输入,单位和时区是否一致,引用是否指向允许的证据,
unknown是否被错误翻译成“否”?这些错误可能出现在完全合法的 JSON 里。最终动作仍服从验收契约和执行端权限。
生成类、无外部效果的任务可以给语法或结构失败设置有限次数的重新生成,并保留原输入和错误类型用于复测;连续失败则澄清需求、换到已验证的备用路径或交给人。不要用正则“修好”缺失字段后当作模型原意,也不要把非法枚举静默替换。若模型调用工具后产生了未知的外部效果,重发请求前先查真实状态;服务降级方案和工具契约分别处理备用模型兼容性与重复执行。
填一份输出协议检查表
下方工作台可填写、复制和导出。先记录消费者、接口版本、格式选择与字段含义,再放一条有效响应和四条非法响应:未完成、JSON 语法、Schema、语义。为每类失败写出阻断位置、可否重试、允许的下一步以及人工负责人,最后用同一组案例在实际模型和 API 上复测。只在浏览器中保存脱敏案例编号与合成内容,不要粘贴顾客原文、凭据或受限日志。
只有正常样例会通过还不够:至少试一条缺日期输入、一条拒绝或截断、一条类型或枚举错误,以及一条结构合规却事实错误的输出。把首个失败层记清楚,再到回答失败诊断定位该改 Schema、输入、校验器还是下游交接。
常见问题
用严格 JSON Schema 后,还需要本地校验吗?
需要处理拒绝、截断、接口差异和业务语义。具体字段约束是否已被 API 强制,取决于提供商及所用 Schema 子集、SDK helper 和模型版本;不能把一家的保证直接移植到另一家。应用端至少要核验响应状态与会影响决策的事实,并为无法消费的响应准备出口。
一个固定标签也要套 JSON 吗?
若下游只接受 pass、review、reject 三个代码,严格逐字校验的纯文本协议可以很小;但只要需要理由、证据和下一步等多个字段,版本化的结构化响应更容易维护。不要让自然语言里一个类似的词触发自动动作。
不适用边界
本页只设计最终响应的表示、校验和解析失败路径,不证明模型回答真实,也不授权任何写入动作。高影响决定仍要验证来源、身份和人工审批;如果系统无法确认一次外部效果是否已发生,先核实状态再决定是否重试。
核验来源
这篇内容参考了哪些一手资料?
来源用于核对定义、风险边界或操作事实;判断框架和工作台由 AI Vista 独立编写。
- OpenAI API documentation — Structured model outputs核验于 2026-10-01
- Claude API documentation — Structured outputs核验于 2026-10-01
- JSON Schema — Object reference核验于 2026-10-01
AI 工具可能协助研究、提纲和语言编辑;事实、案例和最终措辞由编辑复核。发现错误请通过联系页提交更正。
可带走的工具
AI 输出协议检查表
选择下游可接收的格式,并演练每种非法响应的出口。
此工作台会在当前浏览器保存草稿。只用合成输入和脱敏错误片段;不要粘贴顾客原文、凭据、受限日志或完整模型对话。
- 01写任务摘要用脱敏摘要写明要交付的结果。
- 02补齐判断字段写清输入类别、风险、证据位置和接手方式。
- 03交给同事复核对方能复述结论,工具才算完成。
本课已读
完成工作台,再标记已读。
已读状态会更新课程目录与学习进度。
- 01字段齐全
- 02案例走过
- 03可以复核
文章实践笔记
读到这里,留下一条可复核的判断。
下方虚构示例展示写法;你的笔记只保存在当前浏览器。记录哪一步有效、哪个边界不成立,或一个值得测试的问题。
这篇文章还没有示例或本机笔记。你可以记录第一条具体观察。