OpenAI API 怎样为结构化输出定义 JSON Schema
来源:17golang原创
时间:2026-10-26 02:38:48 101浏览 收藏
我第一次把模型输出接到业务对象时,最容易混淆的是“返回了合法 JSON”和“返回了符合业务结构的 JSON”。前者可以用 JSON mode,后者应该把 JSON Schema 交给 Structured Outputs,让接口约束字段形状。
官方文档:https://developers.openai.com/api/docs/guides/structured-outputs
Responses API 把配置放在text.format,Chat Completions API 把配置放在response_format。两种写法都要准备一个对象 Schema,并认真处理required、additionalProperties和拒答分支。
先分清两个请求入口
Structured Outputs 不是另一个独立的模型接口,而是请求体里的一组结构化输出配置。当前更适合新代码的 Responses API 使用 text.format;如果项目仍在使用 Chat Completions,则使用 response_format。两者共同指向 type: "json_schema" 和一份 Schema。

| 调用入口 | 配置位置 | 关键字段 |
|---|---|---|
| Responses API | text.format | type、name、schema、strict |
| Chat Completions API | response_format | type、json_schema、strict |
用 Responses API 提交一份最小 Schema
下面的例子让模型返回一张工单摘要。字段数量故意保持很小:主题、优先级和是否需要跟进。这样更容易看清 Schema 本身,而不是被业务字段淹没。
import OpenAI from "openai";
const client = new OpenAI();
const ticketSchema = {
type: "object",
properties: {
subject: { type: "string", description: "工单主题" },
priority: { type: "string", enum: ["low", "normal", "high"] },
follow_up: { type: "boolean" },
},
// Structured Outputs 要把对象字段全部列入 required。
required: ["subject", "priority", "follow_up"],
// 关闭额外字段,避免模型输出未声明的键。
additionalProperties: false,
};
const response = await client.responses.create({
model: process.env.OPENAI_MODEL ?? "gpt-6-astra",
input: "把‘支付页面偶发超时,请跟进日志’整理成工单摘要。",
text: {
format: {
type: "json_schema",
name: "ticket_summary",
strict: true,
schema: ticketSchema,
},
},
});
// output_text 是 SDK 提供的文本聚合入口,业务层再按约定解析 JSON。
console.log(response.output_text);
这里最关键的不是把 JSON 写得很长,而是让每个对象层级都明确声明字段。name 是这份格式的标识,strict: true 表示按严格结构请求;enum 则把优先级限制在三个值内。
Schema 里最容易漏掉的三件事
我在迁移旧的 JSON mode 请求时,通常先检查下面三处。它们比“模型能不能返回花括号”更决定后续解析是否稳定。

一是每个对象都要写 required
顶层对象要写 required,数组里的对象、嵌套对象也一样。Structured Outputs 的约束要求字段是必填的;如果业务上有“没有值”的情况,可以把字段声明为允许 null,但仍把它放进 required,这样返回对象的键集合仍然稳定。
{
"type": "object",
"properties": {
"note": { "type": ["string", "null"] }
},
"required": ["note"],
"additionalProperties": false
}
这段 JSON 不添加注释,以保持格式本身有效;note 的含义是“键一定存在,但值可以是字符串或 null”。
二是对象要关闭额外字段
additionalProperties: false 会把对象边界说清楚。不要只在顶层加它,嵌套对象也要按同样规则处理,否则下游 DTO、数据库映射或前端状态对象可能遇到未预期字段。
三是拒答不一定符合你的 Schema
用户输入触发安全拒答时,返回内容可能是 refusal,而不是你定义的对象。因此业务代码要先判断拒答或未完成响应,再把正常内容交给 JSON 解析器;Schema 约束解决的是正常结构,不替代安全分支和业务语义校验。
它和 JSON mode 到底差在哪
JSON mode 的目标是让结果成为合法 JSON,但不保证字段名、类型和嵌套结构都遵循你的设计。Structured Outputs 在可支持的 Schema 范围内进一步约束结构,所以当结果要直接驱动 UI、工单对象或数据管道时,我会优先采用它。
| 比较项 | JSON mode | Structured Outputs |
|---|---|---|
| 保证合法 JSON | 是 | 是 |
| 保证遵循 Schema | 否 | 是,仍受支持 Schema 范围限制 |
| 配置示例 | json_object | json_schema + strict |
| 适合场景 | 只需要可解析 JSON | 需要稳定字段和类型的下游对象 |
如果使用 Chat Completions,配置形状可以写成下面这样。它是严格 JSON,所以不在代码块里插入注释;每一层对象仍需补齐 required 和 additionalProperties: false。
{
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "ticket_summary",
"strict": true,
"schema": {
"type": "object",
"properties": {
"subject": { "type": "string" },
"priority": { "type": "string", "enum": ["low", "normal", "high"] },
"follow_up": { "type": "boolean" }
},
"required": ["subject", "priority", "follow_up"],
"additionalProperties": false
}
}
}
}
我会怎样把它放进项目
我的习惯是先用一个小 Schema 打通“请求—解析—错误处理”三段,再逐步加入嵌套数组和枚举。字段命名尽量直观,重要字段补 description;不要一开始就把整个数据库对象原样搬进输出格式。
- 需要稳定键集合:把字段列入
required,缺省值用null表达。 - 需要防止模型扩展字段:每个对象都设置
additionalProperties: false。 - 需要接 UI 或数据管道:单独处理
refusal、截断和 JSON 解析错误。
最后要记住,Structured Outputs 只负责输出结构,不会替你判断业务事实是否正确。Schema 设计得越小、字段描述越清楚,接入成本通常越低;当项目只是偶尔需要一段 JSON,JSON mode 可能已经够用。
相关问题
Responses API 的 Schema 放在哪里?
放在请求的 text.format 中,格式类型使用 json_schema,同时提供名称、Schema 和严格模式设置。
字段想表达“没有值”怎么办?
保留字段并允许它接受 null,不要把字段从 required 数组里删掉。
Structured Outputs 能替代业务校验吗?
不能。它约束 JSON 的形状,业务层仍要检查权限、数值范围、引用存在性和实际业务规则。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
412 收藏
-
114 收藏
-
277 收藏
-
124 收藏
-
123 收藏
-
231 收藏
-
417 收藏
-
352 收藏
-
348 收藏
-
439 收藏
-
241 收藏
-
208 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习