从 JSON Schema 到 Structured Outputs
让大模型输出的不再是“看起来像 JSON 的文本”,而是能够被程序稳定消费、校验和落库的结构化数据。
在 AI 应用里,最难处理的往往不是模型“会不会回答”,而是它能不能按照程序需要的形状回答。字段缺失、类型错误、额外解释文字、数组层级变化,任何一种情况都可能让后续代码直接报错。
01. 为什么只提示“请返回 JSON”还不够
很多项目最初都会这样写 Prompt:
请分析下面的文本,并返回 JSON:
{
"sentiment": "positive | negative",
"score": 0 到 1
}
这种写法通常能得到“像 JSON 的结果”,但它并不构成可靠的接口契约。模型可能把 score 写成字符串,也可能增加 reason 字段,甚至在 JSON 前后补一段解释。对人来说问题不大,对程序来说却意味着解析、校验和重试。

JSON mode 主要解决第一层;Structured Outputs 把约束推进到第二层;第三层仍然需要业务代码继续验证。
02. JSON Schema 到底是什么
JSON Schema 可以理解为“JSON 数据的说明书和验收规则”。普通 JSON 描述一份具体数据,JSON Schema 描述这份数据应该长什么样。
具体数据
{
"title": "Structured Outputs 入门",
"category": "backend",
"published": true
}
对应的 JSON Schema
{
"type": "object",
"properties": {
"title": { "type": "string" },
"category": {
"type": "string",
"enum": ["frontend", "backend", "ai"]
},
"published": { "type": "boolean" }
},
"required": ["title", "category", "published"],
"additionalProperties": false
}
最简单的 schema 是空对象 {},它接受任何合法 JSON。实际开发中,我们会通过 type、properties、required 等关键字逐步收紧规则。正式项目还建议使用 $schema 声明采用的规范版本,例如 Draft 2020-12。
一个容易忽略的区别
JSON Schema 本身是一套通用规范;OpenAI Structured Outputs 只支持其中的一个子集。因此,“在普通 JSON Schema validator 中合法”不代表“可以原样提交给 OpenAI API”。
03. 先掌握这些常用关键字
{
"type": "object",
"properties": {
"title": { "type": "string" },
"summary": { "type": ["string", "null"] },
"level": {
"type": "string",
"enum": ["beginner", "intermediate", "advanced"]
},
"keywords": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["title", "summary", "level", "keywords"],
"additionalProperties": false
}
type
限定数据类型,例如 object、string、number、array。
properties
声明对象允许出现的字段。
required
指定必须返回的字段。
enum
把取值限制在固定集合内。
items
描述数组元素的结构。
additionalProperties
控制是否允许额外字段。
在 OpenAI Structured Outputs 中,所有字段都需要放进 required。如果某个字段业务上允许缺失,可以把它写成 ["string", "null"],用 null 模拟“可选”。
04. JSON mode 与 Structured Outputs 的差别


不要把 Structured Outputs 理解成“模型突然更聪明”
它解决的是输出格式可靠性,而不是事实正确性。模型仍然可能在合法字段中填入错误内容,所以数据库查询、金额、日期和权限判断仍需额外校验。
05.不要只处理“成功返回”
Structured Outputs 能显著降低格式错误,但并不意味着每次请求都一定返回 schema 对象。至少需要考虑下面三类分支:

常见错误:把所有返回值都直接交给 JSON parser
refusal、incomplete 和网络错误都不应被当作普通业务 JSON 处理。先判断响应状态,再进入解析流程,错误信息会清晰很多。
06. OpenAI 对 JSON Schema 的限制
OpenAI 当前支持 JSON Schema 的一个子集。写 schema 时,下面几条尤其重要:
- 根节点必须是
object,不能在顶层直接使用anyOf。 - 所有字段都必须列入
required;可选字段可通过与null的联合类型表达。 - 每个 object 都必须设置
additionalProperties: false。 - 输出字段顺序会遵循 schema 中的 key 顺序,可利用这一点保持结果稳定。
- schema 存在规模限制,包括对象属性总数、嵌套深度、字符串总长度和 enum 数量。
- 第一次使用某个新 schema 时,服务端可能需要额外处理时间;相同 schema 的后续请求通常不会重复承担这部分延迟。
官方文档当前给出的主要规模上限包括:总 object property 数最多 5000、嵌套最多 10 层、全部属性名和 enum 等字符串总长度最多 120,000 字符、所有 enum 合计最多 1000 个值。复杂业务不要把整套数据库模型机械塞进一个 schema,更合理的做法是按任务拆分。
07. 工程实践:Schema 要像 API 契约一样设计
先设计消费端,再设计输出端
不要从“模型能返回什么”出发,而要从“下一步代码需要什么”出发。前端要渲染卡片,就定义卡片所需字段;数据库要写入记录,就定义写入前真正需要的数据。字段越少,约束越明确,整体可靠性通常越高。
字段名承担的是接口语义
result、data 这类泛化字段不利于维护。更具体的 risk_level、evidence、recommended_action 能让 Prompt、schema 和业务代码形成一致的语义。
枚举值要稳定,不要追求“自然语言好看”
程序内部更适合使用 low / medium / high 这类固定标识,再由 UI 做中文映射。直接让模型输出“风险较低”“暂时没有明显风险”等自由文本,会让条件判断重新变得脆弱。
把格式校验和业务校验分开
Structured Outputs 可以保证 confidence 是 number,却不一定保证它处于 0 到 1,也不会判断模型依据是否真实。格式层通过后,再进行数值范围、数据库存在性、权限和事实核验。
适合使用 Structured Outputs 的场景
信息抽取、分类结果、表单填充、Agent 工具参数、UI 数据模型、批量内容审核、工作流节点输入输出,以及任何需要稳定接入程序逻辑的模型响应。
更多推荐



所有评论(0)