OpenAI Responses API 与 Chat Completions:从 Message 到 Item
OpenAI Responses API 与 Chat Completions 的本质差在数据模型:Message 还是 Item。
- Chat Completions 把工具调用挂在
message.tool_calls,执行完再补role=toolmessage。 - 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=toolmessage 拼回历史
所有东西都围绕消息记录组织。简单问答无所谓,工具一多就要和 message 反复绑定 / 解绑。
Responses 的 Item 是积木:
- 用户消息 →
messageItem - 模型要调函数 →
function_callItem - 函数执行结果 →
function_call_outputItem - 推理过程 →
reasoningItem
每块独立存在。运行时一眼就能区分这块是文字、那块是工具调用、另一块是工具结果。
记忆口诀:Chat Completions 关心「下一条 Assistant Message 是什么」;Responses 关心「这一轮我们做了哪些事」。
为什么 Item 模型更适合 Agent
Agent 不只是聊天,还要做事——退款、查订单、改配置、发邮件。
这些事在企业里都要过几道关:能不能调、参数校验过没过、金额大不大、要不要人工审批、网络超时怎么避免重复执行、事后怎么审计。
如果工具调用糊在 assistant message 的 tool_calls 字段里:
- 想插一道「金额 > 1000 必须审批」,得解析 message JSON
- 想给某次工具调用打 trace ID,得挂 message metadata
- 想做幂等控制,还是得绕一圈
Item 模型下,每次工具调用是独立对象:
- 审批钩子挂在
function_callItem 上,生命周期清晰 - 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
- OpenAI Responses API 与 Chat Completions:从 Message 到 Item —— AI 架构师 Leo, 哔哩哔哩, 2026-09-02