设置

语言

Responses API 与 Chat Completions 在 Agent 开发中的对比:如何选择接口契约

CryptoCrypto
·2026年7月14日·约 6 分钟阅读·更新 2026年7月25日·294 次浏览
#编程#AI API#模型基础设施#TokenLab
Responses API 与 Chat Completions 在 Agent 开发中的对比:如何选择接口契约

对于智能体(Agent)工作负载,Responses API 是更好的默认选择:它通过 previous_response_id 提供服务器端对话状态、提供类型化的输出项而非单一的消息块,以及语义化的流式事件。这些特性减少了原本需要由你的编排层承担的记账工作。当你需要完全控制消息历史,或者正在集成围绕 OpenAI 聊天消息格式构建的工具时,Chat Completions 仍然是一个有效的选择;但对于多轮工具调用智能体而言,Responses 是更直接的适配方案。

这两个端点均记录在 GPT-5.6 和 GPT-5.5 的当前模型参考页面中,而 Responses 的共享请求/响应契约在 Responses create 参考文档中有详细说明。

关键要点

  • Chat Completions 由调用方管理:你在每次请求时发送完整的 messages 数组,并自行重构历史记录。
  • Responses 由服务器辅助:你发送 input 以及可选的 instructions,并可以使用 previous_response_id 来串联轮次,而无需重新发送历史记录。
  • 工具调用的结构不同:Chat Completions 将调用嵌套在 choices[0].message.tool_calls 下;Responses 则将其作为类型化项在扁平的 output 数组中发出。
  • 工具结果的匹配方式不同:Chat Completions 使用 tool_call_id,而 Responses 使用 function_call_output 项上的 call_id
  • 流式传输方式不同:Chat Completions 是基于分块的增量(deltas),而 Responses 是具名的语义事件。
  • 托管工具支持(网页搜索、代码解释器、文件搜索等)在两个 API 中均取决于模型;在假设可用性之前,请务必查看模型页面。

字段级对比

关注点 Chat Completions Responses
端点 POST /v1/chat/completions POST /v1/responses
主要输入 messages: [](每次调用需包含完整数组) input(字符串或项数组)
系统级引导 messages[0].role = "system" 顶层 instructions 字段
多轮延续 调用方重新发送整个 messages 历史 previous_response_id 在服务器端引用前一轮
输出形状 choices[0].message(单一消息对象) output: [],类型化项数组(消息、函数调用等)
工具调用位置 choices[0].message.tool_calls[] outputtype: "function_call" 的项
工具结果提交 带有 role: "tool", tool_call_id 的新消息 带有 type: "function_call_output", call_id 的项
流式传输 chunk.choices[0].delta 片段 具名事件(response.output_text.delta, response.completed 等)

previous_response_id:它的实际作用

在 Chat Completions 中,对话记忆完全由你负责。每个请求都必须包含完整的消息历史,服务器对前一轮对话没有任何概念。相反,Responses API 在每个响应对象上返回一个 id。如果你的应用程序持久化该 id 并在下一次调用时将其作为 previous_response_id 传回,服务器就会在内部重构之前的对话状态。你只需要为当前轮次发送新的 input 以及(可选的)新的 instructions。这会将状态管理从你的应用层转移到 OpenAI 的基础设施上,对于进行多次连续工具调用的智能体来说,这一点至关重要,因为你可以避免在每次跳转时重新序列化和重新传输不断增长的历史记录。

其权衡之处在于,你的应用仍然需要在轮次之间将该 id 持久化到某个地方(会话存储、数据库行);API 不会为你提供无限的保留或对过去响应的搜索功能,它只是让你能够引用紧接的前一个响应作为延续点。

当前请求示例 (gpt-5.6)

Chat Completions: 你拥有完整的历史记录:

{
  "model": "gpt-5.6",
  "messages": [
    { "role": "system", "content": "You are a support agent." },
    { "role": "user", "content": "Check order #4471 status." }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_order_status",
        "parameters": { "type": "object", "properties": { "order_id": { "type": "string" } } }
      }
    }
  ]
}

Responses: 包含 instructionsinput 的第一轮:

{
  "model": "gpt-5.6",
  "instructions": "You are a support agent.",
  "input": "Check order #4471 status.",
  "tools": [
    {
      "type": "function",
      "name": "get_order_status",
      "parameters": { "type": "object", "properties": { "order_id": { "type": "string" } } }
    }
  ]
}

Responses: 后续轮次,无需重新发送历史记录:

{
  "model": "gpt-5.6",
  "previous_response_id": "resp_abc123",
  "input": "What about order #4472?"
}

函数调用生命周期

Chat Completions:

  1. 模型返回 choices[0].message.tool_calls,每个调用包含一个 id 和函数名称/参数。
  2. 你在本地执行该函数。
  3. 你将助手消息(带有 tool_calls)附加到你的 messages 数组,然后附加一条新消息:{ "role": "tool", "tool_call_id": "<id>", "content": "<result>" }
  4. 你重新发送整个更新后的 messages 数组以继续。

Responses:

  1. output 数组包含一个 type: "function_call" 的项,其中包括 call_idnamearguments
  2. 你在本地执行该函数。
  3. 你发送一个新请求,将 previous_response_id 设置为前一个响应的 id,并将 input 设置为包含一个 type: "function_call_output" 的项,匹配 call_id 以及结果。
  4. 服务器已经保留了函数调用的上下文,因此你无需重新发送之前的轮次。

扁平的类型化输出项与带有嵌套数组的单一消息之间的结构差异,往往简化了 Responses 中的解析逻辑,因为你可以遍历 output 并根据 type 进行切换,而不是深入挖掘消息的可选字段。

决策清单

  • 正在构建带有工具调用的多轮智能体? 默认使用 Responses;previous_response_id 消除了历史记录记账的负担。
  • 需要对历史记录内容进行精确控制(脱敏、自定义摘要、非标准消息注入)?Chat Completions 明确提供了这种控制,因为你需要自行组装 messages
  • 正在迁移现有的 Chat Completions 集成? 权衡重构成本与状态管理节省的开销;对于短期的单轮调用,收益较小。
  • 依赖托管工具(搜索、代码解释器、文件工具)?在提交之前,请在特定模型的页面上验证支持情况,因为可用性因模型和端点而异。
  • 需要具有细粒度事件语义的流式传输(例如,无需检查增量形状即可区分文本增量与工具调用增量)?Responses 的具名事件比 Chat Completions 的通用增量块更明确。
  • 在围绕聊天消息构建的现有框架或 SDK 中工作? 在项目进行中切换契约之前,请确认其对 Responses 的支持成熟度。

多提供商智能体与契约转换

智能体很少长时间停留在单一提供商上。编码智能体可能会路由到 Claude Sonnet 5 或 Kimi K2.7 Code 进行实现工作,回退到 DeepSeek V4 Flash 或 Gemini 3.5 Flash 进行廉价的草稿处理,并偶尔调用 GLM-5.2 或 Qwen3.7 Plus 进行开源权重成本控制。这些提供商并不一定原生暴露 OpenAI 的 Chat Completions 或 Responses 契约。

这就是路由层发挥作用的地方。TokenLab 在 docs.tokenlab.sh 上的文档描述了一个用于访问多个模型提供商的单一 API 表面和密钥,这消除了为每个提供商契约手动编写单独客户端集成的需求。我们关于 契约兼容性头别名 的相关文章介绍了如何映射请求头,以便针对一种契约形状编写的代码可以访问那些不原生支持该契约的模型。如果你正在构建一个需要调用多个模型系列的聊天机器人或智能体,我们关于 使用一个 API 密钥构建 AI 聊天机器人 的指南以更具体的方式介绍了设置过程。

有关可通过 TokenLab 访问的当前完整模型列表(包括上述提到的前沿、编码和低成本路由选项),请参阅 我们的模型页面。在确定架构之前,请确认当前的可用性和任何特定于契约的说明,因为模型阵容的变化频率高于 API 契约。

限制

本文没有重述 OpenAI 针对任一契约的精确字段级 API 参考,因为这些细节是版本化的且可能会发生变化。请勿将上述请求形状示例视为生产就绪的代码。我们也没有深入涵盖每个提供商的原生契约;Claude、Gemini、DeepSeek 和 GLM 各自发布了自己的 API 参考,它们都没有义务匹配 OpenAI 的 Chat Completions 或 Responses 形状。如果你的智能体需要关于工具调用顺序、流式事件格式或批处理行为的保证,请根据指定提供商的当前文档进行验证,而不是根据本文。

常见问题解答

Responses API 是 Chat Completions 的替代品吗? OpenAI 的快速入门文档将 Responses API 定位为新开发(包括智能体用例)的当前路径,而 Chat Completions 仍然是其记录在案的 API 表面的一部分。Chat Completions 在任何给定时间是被弃用、停止支持还是仅仅是遗留功能,你应该直接在 OpenAI 的当前文档中确认,因为支持状态可能会发生变化。

Claude、Gemini 或 DeepSeek 等其他提供商使用相同的契约吗? 并非原生使用。每个提供商都定义了自己的请求和响应形状。如果你需要在 OpenAI 模型与 Claude Sonnet 5 或 DeepSeek V4 Pro 等提供商之间运行智能体,请计划一个转换层,而不是假设存在共享契约。

切换契约会改变模型输出质量吗? 不会。契约是请求和响应的传输与结构,而不是模型本身。输出质量取决于你调用的模型(例如 GPT-5.5 与 Claude Sonnet 5),而不是你使用 Chat Completions 还是 Responses API 来调用它。

如果你正在评估哪种契约和哪些模型适合你的智能体,请从针对 TokenLab 记录的端点进行的小型测试构建开始,并直接比较编排开销。访问 docs.tokenlab.sh 开始针对你自己的工作负载进行比较。

来源

价格观测于 2026-07-14

分享:

公开模型最近更新

用本文涉及的模型开始构建

对比价格、测试路由,把文章里的调研直接变成可运行的 API 调用。