从零开发文本、推理、工具或 Agent 工作流,优先使用 Responses API;已有稳定的 Chat Completions 业务不必停机重写,可以逐个用户流量迁移。OpenAI 当前明确推荐新项目尝试 Responses,同时继续支持 Chat Completions。选择依据应是所需能力和迁移成本,而不是把后者误判为已经弃用。
官方资料(2026-10-29 核对):迁移到 Responses API · Create a response · Create chat completion · Conversation state · Streaming responses
一张表看懂核心区别
| 维度 | Responses API | Chat Completions | 迁移时要改什么 |
|---|---|---|---|
| 端点 | POST /v1/responses | POST /v1/chat/completions | 请求 URL 与 SDK 方法 |
| 输入 | input 字符串或 typed Items;可用顶层 instructions | messages[] | 消息映射与稳定指令 |
| 输出 | response.output 的 typed Items;纯文本可读 output_text | choices[0].message | 不要把每个 Item 都当消息 |
| 多轮状态 | previous_response_id、手动重放 Items 或 Conversations API | 应用自己维护并重发 messages | 决定状态、裁剪与保留策略 |
| 工具 | 自定义函数,以及符合条件的托管工具 | 以自定义函数调用为主,能力依模型而异 | 工具定义、调用项与输出项 |
| Structured Outputs | text.format | response_format | 移动 Schema 位置并重测 |
| Streaming | 按 event.type 处理语义化 SSE | 读取 choices[].delta | 重写流式消费者 |
| 多个候选 | 不提供 Chat Completions 的 n 对等参数 | 部分模型/场景支持 n | 需要时发起独立请求 |
什么时候应该选 Responses API?
- 新项目:希望跟随 OpenAI 当前推荐的生成接口,减少未来二次迁移。
- 推理与多步骤工具:需要保留 typed reasoning、function call 或工具输出项,而不是只读取一段 assistant 文本。
- 托管工具:需要网页搜索、文件搜索等官方当前支持的工具,并接受其权限、价格与数据边界。
- 会话状态:希望通过
previous_response_id快速串联回合,或用 Conversations API 管理持久会话对象。 - 统一多模态输入:想在同一套 Item 模型中处理文本、图片、文件及工具结果。
如果你只需要简单单轮文本生成,Responses 也能保持很轻;不要为了“Agent”一词加入不需要的工具和状态。
什么时候继续使用 Chat Completions?
- 现有流程稳定、监控完善,近期没有 Responses 独有能力需求。
- 大量业务代码、测试与数据结构依赖
messages、choices和delta。 - 第三方网关或内部 SDK 尚未完整支持 Responses 的 Items、事件和工具形状。
- 迁移风险大于当前收益,需要先做双写或小比例灰度。
继续使用不等于永远不评估。把迁移拆成单轮文本、结构化输出、函数调用、流式和多轮状态五类,逐项验证,比一次性替换更安全。
最小请求对照:不是只换一个 URL
Chat Completions
import OpenAI from "openai";
const client = new OpenAI();
const completion = await client.chat.completions.create({
model: "YOUR_MODEL",
messages: [
{ role: "developer", content: "回答要简洁。" },
{ role: "user", content: "解释幂等性。" }
]
});
console.log(completion.choices[0].message.content);Responses API
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "YOUR_MODEL",
instructions: "回答要简洁。",
input: "解释幂等性。"
});
console.log(response.output_text);output_text 适合只取最终文本。使用推理、工具或多模态输出时,应遍历 response.output,根据 Item 的 type 分别处理 message、reasoning、function_call 等类型,不能假设数组里只有 assistant message。
多轮对话:状态由谁管理?
Responses 提供三种常见方式,选择前先明确保留、成本和可观测性要求。
previous_response_id:把上一条 Response ID 传给下一条,适合快速串联;但顶层instructions不会自动继承,需要每次重发。- 手动回放 Items:把之前的
outputItems 放入下一次input,适合自己裁剪上下文或采用无状态处理;必须保留工具、函数输出和需要的 reasoning Items。 - Conversations API:需要持久会话对象时使用;应单独设计生命周期、删除、访问控制与数据保留。
previous_response_id 不是省 Token 开关。官方说明链中此前输入 Token 仍作为输入计费。应使用 API Usage 比较实际 Token 与成本,而不是只看请求体是否变短。
函数调用与工具迁移的三个坑
- 定义形状变化:Chat Completions 与 Responses 的函数工具配置结构不同,不能原样复制后假设等价。
- 调用和结果是两个 Item:Responses 用
function_call输出项与function_call_output输入项配对,并通过call_id关联。 - 不要丢失中间 Items:手动维护上下文时,遗漏 reasoning、工具调用或工具结果会破坏后续回合。
迁移前为每个函数准备固定测试:参数 Schema 校验、拒绝路径、超时、重复执行和幂等键。端点切换成功但工具副作用重复,仍然是失败迁移。
Structured Outputs 和 Streaming 怎么改?
结构化输出
Chat Completions 常把 JSON Schema 放在 response_format;Responses 使用 text.format。迁移后要重新验证 Schema、拒答、截断和解析错误,不能只检查 HTTP 200。
流式输出
Chat Completions 的处理器通常读 choices[0].delta。Responses 会发出带类型的 SSE 事件,例如 response.created、response.output_text.delta、response.completed 和 error。前端或代理应按 event.type 分支,并处理连接中断后的未完成状态。
const stream = await client.responses.create({
model: "YOUR_MODEL",
input: "用三点解释缓存。",
stream: true
});
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
}
if (event.type === "error") {
// 记录 request id、错误类型和可安全重试的边界
}
}
可回滚的迁移步骤
- 先盘点:列出模型、消息角色、函数、Structured Outputs、Streaming、
n、日志和状态保存方式。 - 选单轮文本流:从无工具、无流式的低风险场景开始,建立 Responses 基线。
- 改输入输出:把 messages 映射为 input/instructions,把 choices 读取改为 output_text 或 typed Items。
- 明确状态:选择 previous_response_id、手动 Items 或 Conversations;写清保留和删除策略。
- 逐类迁移:结构化输出、函数调用、托管工具和流式处理分别验收。
- 双端对比:使用同一脱敏测试集比较答案、延迟、Token、工具成功率、错误率和费用。
- 小流量灰度:设置可快速回滚的功能开关,不在同一发布中同时更换模型、Prompt 和端点。
- 扩量后复盘:查看 Usage、429 和 5xx/超时,确认限额与重试没有恶化。
迁移验收清单
- 每条路径都能读取正确的最终文本或 typed Items。
- 系统/开发者 instructions 在每次需要的请求中出现。
- 函数结果使用正确
call_id,副作用有幂等保护。 - Structured Outputs 使用正确字段并通过 Schema 测试。
- 流式消费者处理 completed、error 和断线。
- 日志记录端点、模型、response/request ID、延迟、usage 与错误类型,但不记录 Secret。
- 同一模型、同一测试集完成质量、Token、延迟与成本对比。
- 保留 Chat Completions 回滚路径,直到 Responses 流量稳定。
Responses 的后台任务可通过事件通知完成,但接收器仍需独立处理原始请求体验签、webhook-id 幂等和快速 2xx。完整实现见 OpenAI Webhooks 指南。
Responses 与 Chat Completions 都不能只靠接口选择解决内容风险;独立审核和结果字段见 OpenAI Moderation API 指南。
Responses 支持多种文件类型和外部 URL,Chat Completions 文件部分当前只支持 PDF;完整对照见 OpenAI Files API 指南。
需要 Vector Store、摄取状态、过滤和 citations;完整实现见 OpenAI File Search 指南。
常见问题
新项目应该使用 Responses API 还是 Chat Completions?
OpenAI 当前建议新项目优先尝试 Responses API,以使用最新平台能力;如果现有 Chat Completions 流程稳定且暂时不需要托管工具或更丰富的状态管理,可以继续运行并按业务流逐步迁移。
Chat Completions 已经弃用了吗?
没有。OpenAI 当前迁移文档明确说明 Chat Completions 仍受支持。不要因为出现 Responses API 就假设旧端点立即下线,也不要在没有回归测试时一次性切换全部流量。
把端点改成 /v1/responses 就算迁移完成了吗?
不算。还要把 messages 与 choices 的读写逻辑改为 input 与 typed output Items,调整工具调用、Structured Outputs、流式事件和多轮状态管理,并重新验证错误处理与用量。
previous_response_id 会减少此前上下文的计费吗?
不会自动免除。官方说明即使通过 previous_response_id 串联响应,链中的既往输入 Token 仍按输入 Token 计费;它解决的是状态传递,不是免费上下文。
使用 previous_response_id 后还要重复发送 instructions 吗?
要。官方 API 参考说明上一条 Response 的顶层 instructions 不会自动带到下一条,因此稳定的系统或开发者指令需要在每次请求中重新发送。
Chat Completions 的流式处理代码可以直接用于 Responses 吗?
不能直接复用。Chat Completions 主要读取 choices 中的 delta;Responses 使用带 type 的语义化 SSE 事件,例如 response.output_text.delta 和 response.completed,消费者必须按事件类型处理。
Responses API 一定比 Chat Completions 便宜吗?
不能只按端点判断。费用取决于模型、输入输出 Token、缓存、工具、后台或批处理方式等。迁移时应对同一测试集比较行为、延迟、Token 用量、错误率和官方当日定价。
单次图片生成/编辑可直接用 Image API;需要对话式连续修改时用 Responses 的 image_generation 工具,具体边界见 OpenAI Images API 教程。