OpenAI Responses API 详解
🧩 Responses API 是 OpenAI 面向新项目推荐的统一生成接口:它把文本与多模态输入、推理、工具调用、结构化输出和多轮状态统一到同一种 Item 模型中,适合构建聊天应用、RAG 与 Agent。
学习目标
读完后应能回答四个问题:
- Responses API 的 Item 模型与 Chat Completions 的 Message 模型差在哪里?
- 如何实现一个可终止、可校验的 Function Calling 循环?
previous_response_id、手动 Item 历史与 Conversation 如何选?- Structured Outputs 保证了什么,又没有保证什么?
⚠️ API 字段、模型名称、内置工具和数据保留策略可能持续变化。代码落地前应以当前 SDK 类型和官方文档为准,并锁定 SDK 版本做回归测试。
一句话理解
Chat Completions 更像“把消息发给模型并得到回复”,Responses API 更像“让模型在任务上下文中生成内容、调用工具并完成工作”。
它的请求入口是 POST /v1/responses。输入使用 input,输出是带类型的 output Item 数组;如果只需要最终文本,可以读取 SDK 提供的 response.output_text。
为什么需要 Responses API
过去,对话、Assistant、工具和状态管理分散在不同接口中。Responses API 将这些能力整合成统一原语:
- 原生支持文本、图片等多模态输入
- 更好地支持推理模型与推理上下文
- 支持 Web Search、File Search、Code Interpreter、Computer Use、远程 MCP 等内置工具
- 支持应用自定义 Function Calling
- 支持多轮状态、持久 Conversation 和无状态上下文
- 支持 Streaming 与 Structured Outputs
官方仍支持 Chat Completions,但建议新项目优先使用 Responses API。
最小调用示例
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await client.responses.create({
model: "gpt-5.6",
instructions: "回答要准确、简洁,并使用中文。",
input: "用一个例子解释什么是 RAG。",
});
console.log(response.output_text);
核心参数:
model:选择模型instructions:本次请求的高层行为约束input:字符串、消息或其他 Item 数组output_text:SDK 聚合最终文本的便捷属性
模型名称和能力会持续更新,实际项目应以当前官方文档与账户可用模型为准。
核心心智模型:Item
Responses API 不再把所有信息都塞进 Message,而是使用不同类型的 Item 表示交互中的基本单元。
常见 Item:
message:用户或模型消息reasoning:推理相关上下文function_call:模型请求调用应用函数function_call_output:应用执行函数后的返回值- 内置工具产生的调用和结果 Item
因此,一个 Response 的 output 不一定只有文本,也可能依次包含推理、一个或多个工具调用和最终消息。
for (const item of response.output) {
switch (item.type) {
case "message":
// 读取消息
break;
case "function_call":
// 执行应用侧函数
break;
case "reasoning":
// 处理推理相关 Item
break;
}
}
**经验法则:**只显示最终答案时用 output_text;实现工具循环、审计或复杂工作流时遍历 output,按 item.type 分发。
输入形式
直接字符串
const response = await client.responses.create({
model: "gpt-5.6",
input: "总结 TCP 三次握手。",
});
消息数组
const response = await client.responses.create({
model: "gpt-5.6",
input: [
{ role: "system", content: "你是一名计算机网络教师。" },
{ role: "user", content: "解释 TCP 三次握手。" },
],
});
新代码通常可将稳定规则放入顶层 instructions,将当前任务与上下文放入 input。
多轮对话与状态管理
Responses API 有三种常见方案。
方案一:previous_response_id
适合短期连续追问,让服务端关联上一轮 Response:
const first = await client.responses.create({
model: "gpt-5.6",
instructions: "使用中文回答。",
input: "什么是向量数据库?",
store: true,
});
const second = await client.responses.create({
model: "gpt-5.6",
instructions: "使用中文回答。",
previous_response_id: first.id,
input: "它在 RAG 中有什么作用?",
store: true,
});
注意:
- 顶层
instructions不会通过previous_response_id自动继承,稳定指令应在后续请求中重发 - 关联历史不代表历史 token 免费,历史输入仍会计入使用量
- 应保存 Response ID,并处理 ID 失效或上下文过长的情况
方案二:应用自己维护 Item 历史
适合需要裁剪、摘要、审计或 store: false 的场景:
const history: any[] = [
{ role: "user", content: "什么是 RAG?" },
];
const first = await client.responses.create({
model: "gpt-5.6",
input: history,
store: false,
});
history.push(...first.output);
history.push({ role: "user", content: "列出核心步骤。" });
const second = await client.responses.create({
model: "gpt-5.6",
input: history,
store: false,
});
对于推理模型,应保留并回传完整的 output Item,而不是只保存最终文本,否则可能丢失推理或工具上下文。
方案三:Conversations API
适合跨会话、设备或后台任务长期存在的对话。Conversation 是独立持久对象,可以持续保存消息、工具调用和工具结果等 Item。
| 场景 | 推荐方案 |
|---|---|
| 简单连续追问 | previous_response_id |
| 需要自定义裁剪、摘要或无状态部署 | 手动维护 Item |
| 跨设备、跨任务长期会话 | Conversations API |
Function Calling 工作流
Function Calling 的本质是:模型决定调用哪个函数并生成参数,但真正的函数由应用执行。
1. 声明工具
const tools = [
{
type: "function" as const,
name: "get_weather",
description: "查询指定城市的天气",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "城市名称,例如上海",
},
},
required: ["city"],
additionalProperties: false,
},
},
];
2. 让模型决定是否调用
const response = await client.responses.create({
model: "gpt-5.6",
input: "上海现在天气怎么样?",
tools,
});
3. 执行函数并回传结果
const toolOutputs = [];
for (const item of response.output) {
if (item.type !== "function_call") continue;
const args = JSON.parse(item.arguments);
const result = await getWeather(args.city);
toolOutputs.push({
type: "function_call_output" as const,
call_id: item.call_id,
output: JSON.stringify(result),
});
}
const finalResponse = await client.responses.create({
model: "gpt-5.6",
previous_response_id: response.id,
input: toolOutputs,
tools,
});
console.log(finalResponse.output_text);
关键点:
- 使用
call_id关联function_call与function_call_output - 模型生成的参数不可信,执行前必须做 Schema、权限和业务校验
- 工具返回值应精简、结构稳定,避免暴露敏感字段
- 一轮可能包含多个工具调用,不能假设只有一个
- 模型获得结果后可能继续调用其他工具,复杂 Agent 应循环处理,并设置调用次数、耗时和成本上限
内置工具
Responses API 可配置 Web Search、File Search、Code Interpreter、Computer Use 和远程 MCP 等工具,模型能在响应流程中自行选择工具。
const response = await client.responses.create({
model: "gpt-5.6",
input: "查找今天与 AI Agent 相关的重要消息并给出来源。",
tools: [{ type: "web_search" }],
});
不同工具的配置、支持模型、权限和计费可能不同,应查看对应工具的最新文档。模型可以调用工具,不等于模型天然拥有系统权限;凭证与数据边界仍须由应用控制。
Structured Outputs
下游程序需要可靠 JSON 时,应使用 Structured Outputs,而不是只在 Prompt 中要求“返回 JSON”。Responses API 的配置位于 text.format:
const response = await client.responses.create({
model: "gpt-5.6",
input: "张三,28 岁,擅长 TypeScript 和 React。",
text: {
format: {
type: "json_schema",
name: "developer_profile",
strict: true,
schema: {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
skills: {
type: "array",
items: { type: "string" },
},
},
required: ["name", "age", "skills"],
additionalProperties: false,
},
},
},
});
const profile = JSON.parse(response.output_text);
| 能力 | Structured Outputs | JSON Mode |
|---|---|---|
| 保证合法 JSON | 是 | 是 |
| 保证遵循指定 Schema | 是 | 否 |
| 适合稳定程序接口 | 更适合 | 兼容方案 |
仍需处理安全拒绝、输出截断和网络错误。Schema 正确也不代表业务语义必然正确。
Function Calling 还是 text.format?
- 模型需要调用代码、数据库或外部系统:使用 Function Calling
- 模型只需按固定数据结构回答:使用
text.formatStructured Outputs
Streaming
交互式产品通常使用流式输出降低首字延迟:
const stream = await client.responses.create({
model: "gpt-5.6",
input: "详细解释 Transformer。",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
}
}
生产代码不应只处理文本增量,还应识别完成、错误、拒绝、工具调用和响应不完整等事件,并在流结束后保存最终状态。
与 Chat Completions 的主要区别
| Chat Completions | Responses API |
|---|---|
POST /v1/chat/completions | POST /v1/responses |
输入核心是 messages | 输入核心是 input / Items |
输出位于 choices | 输出位于 typed output Items |
| 文本读取路径较深 | SDK 提供 output_text |
| 对话历史通常由应用维护 | 支持 Response 链、手动 Item 和 Conversation |
| 工具与 Agent 能力相对分散 | 统一内置工具和自定义函数 |
Structured Outputs 使用 response_format | 使用 text.format |
支持 n 生成多个候选 | 单次只生成一个候选,需要多个候选时发起多次请求 |
从 Chat Completions 迁移
迁移可拆成三步:
- 将请求地址从
/v1/chat/completions政为/v1/responses - 将
messages迁移为input,并从output或output_text读取结果 - 明确状态管理策略:
previous_response_id、手动维护 Item,或 Conversations API
迁移前:
const completion = await client.chat.completions.create({
model: "gpt-5.6",
messages: [
{ role: "system", content: "使用中文回答。" },
{ role: "user", content: "什么是 RAG?" },
],
});
console.log(completion.choices[0].message.content);
迁移后:
const response = await client.responses.create({
model: "gpt-5.6",
instructions: "使用中文回答。",
input: "什么是 RAG?",
});
console.log(response.output_text);
如果旧系统包含函数调用、多模态或复杂历史,不能只做字段改名,应同时调整工具定义、工具结果 Item、Structured Outputs 和状态逻辑。
存储、隐私和上下文
- Response 默认存储;不希望保存时设置
store: false - 官方文档说明,普通 Response 对象默认保存 30 天
- Conversation 及其中 Item 为持久对象,不受普通 Response 的 30 天期限限制
- 使用
previous_response_id时,历史输入仍计费 - API 数据不会在未经明确同意的情况下用于训练模型
- 对零数据保留等合规场景,应采用无状态方案,并按组织策略处理加密推理 Item
- 对话越长,上下文、延迟和费用越高;应设计滑动窗口、摘要或压缩策略
生产环境检查清单
- API Key 仅保存在服务端和密钥管理系统中
- 为请求设置超时、取消、重试与幂等策略
- 区分可重试错误与业务错误
- 校验模型生成的所有工具参数
- 在应用侧执行鉴权,不能只依赖 Prompt
- 给工具调用设置次数、耗时和成本上限
- 处理
completed、incomplete、failed与拒绝等状态 - 为流式响应处理断线和重复事件
- 记录 response ID、模型、耗时、token 和工具轨迹
- 对 Prompt、Schema、模型和工具变更建立回归评测
- 控制敏感数据进入模型及工具返回值的范围
- 根据数据保留要求选择
store和状态方案
什么时候选择 Responses API
适合:
- 新的对话或内容生成应用
- 需要推理模型的任务
- RAG、工具调用和 Agent 工作流
- 需要结构化 JSON 的业务接口
- 需要多模态输入或 OpenAI 内置工具的应用
可以继续使用 Chat Completions:
- 旧系统稳定运行且没有新能力需求
- 兼容供应商只实现 Chat Completions 协议
- 迁移成本暂时高于收益
常见误区
output 一定只有一条消息
错误。它可能包含推理、工具调用和消息等多个 Item。
使用 previous_response_id 就不再产生历史费用
错误。历史上下文依然会计入输入 token。
Function Calling 会自动执行函数
错误。模型只生成函数名和参数,应用必须执行并回传结果。
Structured Outputs 保证内容事实正确
错误。它保证结构,不保证事实、业务语义或数据来源正确。
开启 store: false 就可以忽略数据治理
错误。应用日志、监控、代理和工具系统仍可能记录数据,需要端到端审查。
参考资料
✅ 最终心智模型:把 Responses API 看作一个“生成 + 状态 + 工具”的统一事件循环。简单请求读取
output_text;复杂 Agent 遍历 typed Items,执行工具、回传结果,并持续控制上下文、权限、成本与可靠性。