Skip to main content

OpenAI Responses API 与 Chat Completions:从 Message 到 Item

· 6 min read

OpenAI Responses API 与 Chat Completions 的本质差在数据模型:Message 还是 Item。

  • Chat Completions 把工具调用挂在 message.tool_calls,执行完再补 role=tool message。
  • Responses 把 message / function_call / output 拆成独立 Item,运行时一眼能区分。
  • Item 让权限 / 重试 / 审计能挂在具体调用上,而不是糊在 message 上。
  • API 只表达「模型建议调什么」,执行安全 / 审批归企业 runtime。
  • Responses 支持 previous_response_id,免去手动拼历史,但不解决长期记忆。
  • 流式推送:Responses 能告知 item 创建、参数生成、item 完成。
  • 结论:Responses 更 Agent-native,但不替代企业 runtime——平台层应走 adapter,业务层不直接绑定 OpenAI 对象。

看着像,骨子里不一样

Chat Completions 和 Responses 在简单问答场景下几乎没有差别——发个 prompt,收条回复,完事。

真正的分歧在 Agent 场景:模型要调工具、要多轮、要异步、还要被运行时治理。

两条 API 的分界点是它们用什么方式表达「模型这一轮做了什么」:

  • Chat Completions 围绕 Message,所有内容塞进 message
  • Responses 围绕 Item,不同事件类型各自一个 Item

这个差异决定了它们在 Agent 工程里能不能扛得住。

Message vs Item:盒子和积木

Chat Completions 的 message 是个盒子:

  • 普通回复 → message.content
  • 工具调用 → message.tool_calls(挂在同一条 assistant message 上)
  • 工具结果 → 单独一条 role=tool message 拼回历史

所有东西都围绕消息记录组织。简单问答无所谓,工具一多就要和 message 反复绑定 / 解绑。

Responses 的 Item 是积木:

  • 用户消息 → message Item
  • 模型要调函数 → function_call Item
  • 函数执行结果 → function_call_output Item
  • 推理过程 → reasoning Item

每块独立存在。运行时一眼就能区分这块是文字、那块是工具调用、另一块是工具结果。

记忆口诀:Chat Completions 关心「下一条 Assistant Message 是什么」;Responses 关心「这一轮我们做了哪些事」。

为什么 Item 模型更适合 Agent

Agent 不只是聊天,还要做事——退款、查订单、改配置、发邮件。

这些事在企业里都要过几道关:能不能调、参数校验过没过、金额大不大、要不要人工审批、网络超时怎么避免重复执行、事后怎么审计。

如果工具调用糊在 assistant message 的 tool_calls 字段里:

  • 想插一道「金额 > 1000 必须审批」,得解析 message JSON
  • 想给某次工具调用打 trace ID,得挂 message metadata
  • 想做幂等控制,还是得绕一圈

Item 模型下,每次工具调用是独立对象:

  • 审批钩子挂在 function_call Item 上,生命周期清晰
  • trace ID / retry policy / budget 直接挂 Item
  • 审计回放天然以「调用」为单位,不是以「对话」为单位

关键提醒:Item 化是 Agent 工程化的前提。如果工具调用没法被独立寻址、追踪、审计,后续的权限 / 审批 / 可观测性都得手糊。

职责边界:API 只建议,执行归 runtime

这里有个必须划清的边界:

Responses 能告诉你的:模型认为下一步该调什么工具、参数是什么。 Responses 不会替你做的:这个调用是不是该执行、参数有没有被注入、有没有权限、金额是否需要审批、超时怎么重试。

模型负责提出调用,企业系统负责安全执行。这条边界在 Chat Completions 和 Responses 都成立——只是 Responses 因为 Item 化,把这个分工显式化了:

把模型当成「给建议的乙方」,而不是「替你做事的甲方」。

状态管理:Responses 不解决长期记忆

Chat Completions 的历史是应用自己拼的——下一轮把要的消息列表塞进 messages。消息越长越贵,就要考虑裁剪、摘要、降本。

Responses 给了几种衔接方式:

  • 自己保存 Item 列表继续追加
  • previous_response_id 把新请求接在上一轮后面
  • conversation 持续保留上下文

但这些都是「会话状态」,不是「长期记忆」

哪些信息该长期记住、谁能访问什么、什么算过期,这些事 Responses 一个都没替你做,还是要自己设计。

流式事件:Responses 能显式表达「思考过程」

Chat Completions 流式推送的是文字增量——前端一个字一个字打出来。

Responses 在文字之外还能告诉你:

  • item 创建response.output_item.added——「现在有个 function_call 出现了」
  • 参数生成中response.function_call_arguments.delta——「模型还在拼参数,先别执行」
  • item 完成response.output_item.done——「这条 item 准备好了,可以执行了」
  • 整体结束response.completed——「这轮收尾」

前端因此能展示「正在搜索 / 正在整理结果 / 正在定位工具」这类过程,而不只显示「正在生成」。

这条对 Agent UX 很关键——用户得知道 Agent 在做什么、卡在哪步、为什么停了。

怎么选:三步决策

已经在用 Chat Completions 做聊天 / 摘要 / 分类 / 普通生成? 不迁移。Chat Completions 简单、好懂、跨厂商适配容易,没必要为新接口重写。

要做企业级 Agent / 工具密集 / 要审计和审批? 优先 Responses。Item 模型让工程化落地更顺,工具调用生命周期清晰。

做的是跨模型 Agent 平台? 不要让业务直接绑定 OpenAI 对象。内部定义自己的 runtime / event / approval,通过 adapter 适配 Responses 和 Chat Completions,业务层走统一模型。以后 Anthropic / Gemini 接口结构再变,业务层不用重写。

一句话总结:Responses 是更 Agent-native 的接口,但它不替代企业 runtime。模型供应商负责把「这一轮的工作」表达清楚,平台层负责把「调用安不安全 / 执行可不可控」治理到位。

References

  1. OpenAI Responses API 与 Chat Completions:从 Message 到 Item —— AI 架构师 Leo, 哔哩哔哩, 2026-09-02