这不是一次接口替换,而是数据模型从「消息序列」换成「条目事件序列」。 根本驱动力是模型的行为单元从「一次回复」变成了「执行一段过程」——推理模型的 CoT、多步工具调用、服务端托管状态,用 messages 数组表达不了。

演进时间线

timeline
    title OpenAI 模型调用接口的演进
    2023-03 : Chat Completions 上线<br/>messages 数组成为事实标准
    2023-06 : Function Calling<br/>工具调用塞进 assistant / tool 两条消息
    2023-11 : Assistants API beta<br/>Thread / Run / Step 服务端状态
    2024-09 : o1 推理模型<br/>reasoning tokens 在 messages 里无处安放
    2025-03 : Responses API 上线<br/>typed items + 单请求 agentic loop
    2025-08 : Assistants 宣布弃用<br/>迁移目标锁定 Responses
    2026-08 : Assistants 正式下线<br/>OpenAI 认定 Responses 已达 feature parity

关键点:Chat Completions(2023)和 Responses(2025)之间隔了两年,中间真正改变需求的是 推理模型(2024-09)和 Agent 成为主用法。

数据模型:Messages vs Items

Chat Completions

一次请求是一个 messages 数组,每条消息 = 一个 role + content。角色只有 system / developer / user / assistant / tool,模型输出的全部可能性被压缩成 content 加一个 tool_calls 字段。

Responses

一次请求是 input items,返回是 output items。每个 item 带 type 和 id,是一个联合类型:

item type语义
message文本 / 多模态内容,role = user / assistant / system / developer
reasoning推理摘要 + 加密推理内容(encrypted_content)
function_call自定义函数调用,带 call_id
function_call_output函数结果,用 call_id 配对
web_search_call / file_search_call / code_interpreter_call内置工具调用
computer_call / image_generation_call / mcp_call其余宿主工具
flowchart TB
    subgraph CC["Chat Completions:messages 数组"]
        direction LR
        C1["system"] --> C2["user"] --> C3["assistant<br/>content + tool_calls"] --> C4["tool<br/>tool_call_id + result"]
        C4 --> C3
    end

    subgraph RS["Responses:input / output items"]
        direction LR
        R1["message<br/>system"] --> R2["message<br/>user"] --> R3["reasoning<br/>summary + encrypted"] --> R4["function_call<br/>call_id"] --> R5["function_call_output<br/>call_id"] --> R6["web_search_call"] --> R7["message<br/>assistant"]
    end

为什么要转:五个动因

1. 推理模型的中间态无法用 messages 表达(最主要的推力)

o 系和 GPT-5 系产生 reasoning tokens,这些内容必须跨轮次、跨工具调用保留,模型才能延续同一条思考链。Chat Completions 的 schema 里没有这个位置——每轮请求都会把推理状态丢掉,模型只能重新想一遍。

OpenAI 内部评测给出的量化差异:同样的 prompt 和 setup,用 Responses 跑 GPT-5 时 SWE-bench 提升约 3%。这不是接口开销,是信息丢失造成的智力损失。

Responses 提供两条路:

  • store: true(默认)+ previous_response_id:服务端保存并自动带回推理上下文
  • store: false + include: ["reasoning.encrypted_content"]:无状态交付,但推理内容以加密形式随客户端往返

2. 从无状态重放升级为可选托管状态

Chat Completions 是无状态的:每轮把全部历史重新发一遍。状态管理(截断、压缩、去重、缓存命中)全由客户端承担。

Responses 把状态做成可选能力而非强制模型:

模式做法适用
完全无状态store: false,自己重放 items合规敏感、跨 provider 迁移
链式状态previous_response_id 串起多轮快速接入多轮
持久会话Conversations API(conv_ 对象,直接 append items)服务端长期会话、可审计

注意 store 默认是 true——迁移到 Responses 时数据留存是默认打开的,有合规要求必须显式关掉。

3. 工具从「客户端函数调用」变成「服务端 agentic loop」

Chat Completions 只认自定义函数,工具循环完全写在使用方:

flowchart TD
    subgraph A["Chat Completions:循环在客户端,O(N) 次模型往返"]
        A1["客户端拼 messages"] --> A2["POST /chat/completions"]
        A2 --> A3{"模型输出"}
        A3 -->|tool_calls| A4["客户端执行工具"]
        A4 --> A5["拼回 role=tool"]
        A5 --> A2
        A3 -->|文本| A6["客户端管理全部历史"]
    end

    subgraph B["Responses:单请求内完成 agentic loop"]
        B1["input + tools"] --> B2["POST /responses"]
        B2 --> B3["服务端编排<br/>web_search / file_search / code_interpreter / MCP / 自定义函数"]
        B3 --> B4["typed output items"]
        B4 --> B5["previous_response_id 或 Conversations 托管状态"]
        B4 --> B6["语义化 SSE 事件流"]
    end

内置工具是一等公民:web_search、file_search、code_interpreter、computer_use、image_generation、remote mcp。这些在 Chat Completions 时代要靠 Assistants 或各家自建胶水层。

代价同样明确:你不再控制检索参数、结果排序、文件索引实现。想调优就退回自定义函数。

4. 流式协议从「内容追加」升级为「语义事件」

Chat CompletionsResponses
传输形态连续追加 choices[0].delta.content具名事件:response.output_text.delta、response.function_call_arguments.delta、response.completed
消费方式把 delta 拼成字符串按 item 类型分派处理
表达力无法区分文本增量和工具参数增量天然区分

对 Agent 运行时来说,这个差异很实在:只有知道「这一段是文本、那一段是工具参数」,才能边流式边渲染、边做并行工具调度。

5. 缓存与成本

上下文前缀重复度高的工作负载(长 system prompt、长工具定义、多轮 Agent)在 Responses 上缓存利用率更好。OpenAI 内部测试给出的区间是缓存利用率提升 40%~80%,对应的是实际账单。

硬约束:不是「建议迁移」,而是「能力只在一边」

这是最容易低估的一点。新模型的工具调用能力在 Chat Completions 上被主动限制:

Function tools with reasoning_effort are not supported for gpt-5.6-sol
in /v1/chat/completions. To use function tools, use /v1/responses
or set reasoning_effort to 'none'.

从 GPT-5.4 开始,Chat Completions 下 reasoning_effort != "none" 时禁止挂载 function tools。也就是说,想同时要「深度推理 + 工具调用」这个 Agent 的核心组合,在 Chat Completions 上已经被堵死。

这条限制在社区里争议很大(被认为是推动 Responses 采用的手段),但它清楚地划出了边界:Chat Completions 是兼容层,不再是能力前沿。

三方定位:谁活着,谁死了

Chat CompletionsResponsesAssistants
会话状态无状态,自管历史store + previous_response_id / ConversationsThreads / Runs(已移除)
内置工具无web search / file search / code interpreter / computer use / MCP / image gencode interpreter / file search
跨轮推理状态丢弃保留(链式或加密)thread 内保留
定位行业标准、兼容层OpenAI 默认推荐已下线
API 状态继续支持(OpenAI 承诺「supported for years」)推荐所有新项目使用2025-08-26 宣布弃用,2026-08-26 正式下线,无宽限期

Assistants 的替代关系:Assistants → Prompts(dashboard 创建、版本化),Threads → Conversations(存 items,不只存 messages),Runs → Responses,Run Steps → Items。

迁移对照

Chat CompletionsResponses
POST /v1/chat/completionsPOST /v1/responses
messages: [...]input: "..." 或 input: [...]
role: "system" 消息顶层 instructions
max_tokens / max_completion_tokensmax_output_tokens
response_formattext: { format: {...} }
response.choices[0].message.contentresponse.output_text
choices[0].delta.contentresponse.output_text.delta 事件
role: "tool" 结果消息function_call_output item(带匹配的 call_id)
客户端自行管理历史previous_response_id 或 Conversations

简单文本场景迁移成本极低——messages 数组可以直接当作 input 传进去,改个 endpoint 就能跑。复杂的是函数调用、结构化输出和流式消费三块。

对 Agent 工程的实际影响

  • OpenAI 官方栈全面转向 Responses:ChatGPT、Codex、Agents SDK 都直接构建在它之上;Codex 从 2025-10 起逐步停止 Chat Completions 支持
  • 兼容层开始跟进:Azure OpenAI/Foundry、阿里云百炼都提供 OpenAI 兼容 Responses 接口(百炼覆盖 qwen3.x、deepseek-v4、glm-5.x、kimi-k3 等),说明它正在从「OpenAI 私有协议」变成多 provider 接口形态
  • 二开与网关的适配成本:像 opencode 这类基于 AI SDK 的 harness,原生 OpenAI 走 @ai-sdk/openai、兼容网关走 @ai-sdk/openai-compatible,两种 provider 对 Responses / Chat Completions 的支持面并不一致——aisuite 那类统一接口层要做的适配工作量恰好来自这里
  • 兼容坑位:model-studio-pdf-understanding 记录了一个典型样本——百炼的 Responses 接口对 PDF 传参返回 200 但静默丢弃文件,必须回退 Chat Completions 或 DashScope 协议。协议兼容 ≠ 能力兼容

未收敛的问题

  • Chat Completions 的寿命:官方口径是「industry standard,继续支持」,但同时用工具调用限制把新能力锁在 Responses。这是「支持但边缘化」的典型信号,独立开发者是否要为 3% 基准提升付出迁移成本,取决于是否用推理模型 + Agent 循环
  • 无状态也要能推理:store: false 时推理内容默认不返回,想保留必须显式加 include: ["reasoning.encrypted_content"] 并手动回灌——多数团队在这里踩过坑
  • 跨 provider 锁定:Chat Completions 是行业事实标准,Anthropic、Google、国内厂商全都兼容它。Responses 目前主要由 OpenAI 及跟随者(Azure、百炼)实现,作为兼容层成熟度仍不齐
  • n 参数被移除:需要一次生成多候选的应用无法直接迁移,官方未给等价方案

相关

  • phistory — 从 trace 中提取 Codex 的 /v1/responses 请求,按 instructions / developer / user / additional_tools 切分 prompt,是 Responses 结构差异的实证案例
  • claude-tap — 对 OpenAI Responses / Chat Completions 双协议做上游兼容修正
  • aisuite — 多 provider 统一接口层,需要在两套协议之间做能力对齐
  • agent-harness-anatomy — Responses 把 Harness 的一部分(状态、工具循环、上下文管理)吸收进了 API 层
  • programmatic-tool-calling — 另一个方向的「谁来编排工具」:PTC 把循环放进代码沙箱,Responses 把循环放上服务端
  • agent-protocols — MCP / A2A / ACP 关注 Agent 与工具之间的连接层,与本文的模型调用原语不在同一层

参考