OpenAI Chat Completions 与 Responses API 协议差异
结论摘要:OpenAI 当前推荐新项目优先使用 Responses API。Chat Completions 仍受支持,适合维护已有聊天协议和客户端生态。Responses 不只是字段改名,它引入了 Item 数据模型、语义化流事件、服务端上下文状态以及后台任务生命周期。
本文对比的是 POST /v1/chat/completions 与 POST /v1/responses。文中的 ID、模型名、token 数量和时间戳均为演示数据;JSON 重点展示协议结构,不代表一次真实接口调用的完整返回。
一、核心结论
-
新项目:需要推理模型、内置工具、多轮工具调用或长耗时任务时,优先采用 Responses API。
-
存量项目:Chat Completions 没有被官方标记为废弃,可以继续维护,不必仅因为 Responses 发布就立即重写。
-
协议兼容:简单文本请求可以直接迁移;工具调用、流式响应、上下文状态和返回对象无法仅靠字段重命名完成无损转换。
-
网关设计:建议分别实现 Chat Completions Adapter 和 Responses Adapter,再映射到统一的内部 Item、Event、Usage 模型。
OpenAI 曾将 Responses 描述为 Chat Completions 的超集,但当前迁移文档仍列出个别能力差异,例如音频能力。工程上更适合把 Responses 视为面向新项目和 Agent 工作流的推荐接口,而不是在所有能力上都能严格一对一替代 Chat Completions。
二、协议差异总览
| 维度 | Chat Completions | Responses API |
|---|---|---|
| Endpoint | POST /v1/chat/completions |
POST /v1/responses |
| 输入****主体 | messages[] |
input 字符串或 Item 数组;系统指令可放 instructions |
| 返回主体 | choices[].message |
output[] 类型化 Item |
| 文本读取 | choices[0].message.content |
SDK 的 output_text,或遍历 output[] |
| 多候选 | 支持 n |
一次生成一个 Response,不支持 n |
| 最大输出 | max_completion_tokens |
max_output_tokens |
| 结构化输出 | response_format |
text.format |
| Token Usage | prompt_tokens、completion_tokens |
input_tokens、output_tokens |
| 上下文管理 | 客户端通常重复发送历史消息 | 手动传递、previous_response_id 或 Conversation |
| 流式处理 | chat.completion.chunk 和 choices[].delta |
按 type 区分的语义化 SSE 事件 |
| 异步生命周期 | 没有同等的 Response 资源生命周期 | 支持后台运行、查询、取消、Webhook、Compaction 和 WebSocket 模式 |
三、最小文本请求与响应
3.1 Chat Completions 请求
{
"model": "MODEL_ID",
"messages": [
{
"role": "system",
"content": "你是一个简洁的技术助手。"
},
{
"role": "user",
"content": "用一句话解释 SSE。"
}
],
"max_completion_tokens": 200,
"stream": false
}
3.2 Chat Completions 响应
{
"id": "chatcmpl_demo_001",
"object": "chat.completion",
"created": 1788400000,
"model": "MODEL_ID",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "SSE 是服务器通过一个持续的 HTTP 连接向客户端单向推送事件的协议。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 25,
"completion_tokens": 28,
"total_tokens": 53
}
}
Chat Completions 的主要业务结果位于 choices[]。即使业务只需要一个答案,也应检查数组是否为空、finish_reason 是否符合预期,以及响应是否包含拒绝或工具调用。
3.3 Responses API 请求
{
"model": "MODEL_ID",
"instructions": "你是一个简洁的技术助手。",
"input": "用一句话解释 SSE。",
"max_output_tokens": 200,
"stream": false
}
3.4 Responses API 响应
{
"id": "resp_demo_001",
"object": "response",
"created_at": 1788400000,
"status": "completed",
"model": "MODEL_ID",
"output": [
{
"id": "msg_demo_001",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "SSE 是服务器通过一个持续的 HTTP 连接向客户端单向推送事件的协议。",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 25,
"output_tokens": 28,
"total_tokens": 53
}
}
Responses 的 output[] 不保证只包含 assistant message。它还可能包含 reasoning、function call、web search、file search、computer use 等 Item,因此不要固定读取 output[0].content[0].text。使用官方 SDK 时,可以优先读取聚合后的 output_text;实现网关时应遍历并保留所有 Item 类型。
四、多轮上下文
4.1 Chat Completions:客户端重发历史消息
{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": "我的订单号是 A100。"
},
{
"role": "assistant",
"content": "已记录订单号 A100。"
},
{
"role": "user",
"content": "我的订单号是什么?"
}
]
}
4.2 Responses:使用 previous_response_id
{
"model": "MODEL_ID",
"instructions": "你是订单助手。",
"input": "我的订单号是 A100。"
}
{
"model": "MODEL_ID",
"previous_response_id": "resp_demo_first_turn",
"instructions": "你是订单助手。",
"input": "我的订单号是什么?"
}
注意:使用 previous_response_id 时,上一轮顶层的 instructions 不会自动继承,需要在当前请求中重新传入。历史链路中的输入 token 仍会进入计费计算。
4.3 Responses:显式 Item 数组
{
"model": "MODEL_ID",
"input": [
{
"role": "user",
"content": "我的订单号是 A100。"
},
{
"role": "assistant",
"content": "已记录订单号 A100。"
},
{
"role": "user",
"content": "我的订单号是什么?"
}
]
}
五、函数工具调用
5.1 Chat Completions:声明工具
{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": "查询上海明天的天气。"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市和日期的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"date": {
"type": "string"
}
},
"required": [
"city",
"date"
],
"additionalProperties": false
},
"strict": true
}
}
]
}
5.2 Chat Completions:模型返回 tool_calls
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_weather_001",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"上海\",\"date\":\"2026-09-04\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}
5.3 Chat Completions:回传工具结果
{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": "查询上海明天的天气。"
},
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_weather_001",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"上海\",\"date\":\"2026-09-04\"}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_weather_001",
"content": "{\"temperature_c\":29,\"condition\":\"多云\"}"
}
]
}
5.4 Responses:声明工具
{
"model": "MODEL_ID",
"input": "查询上海明天的天气。",
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "查询指定城市和日期的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"date": {
"type": "string"
}
},
"required": [
"city",
"date"
],
"additionalProperties": false
},
"strict": true
}
]
}
5.5 Responses:模型返回 function_call Item
{
"id": "resp_weather_001",
"object": "response",
"status": "completed",
"output": [
{
"id": "fc_weather_001",
"type": "function_call",
"status": "completed",
"call_id": "call_weather_001",
"name": "get_weather",
"arguments": "{\"city\":\"上海\",\"date\":\"2026-09-04\"}"
}
]
}
5.6 Responses:回传 function_call_output
{
"model": "MODEL_ID",
"previous_response_id": "resp_weather_001",
"input": [
{
"type": "function_call_output",
"call_id": "call_weather_001",
"output": "{\"temperature_c\":29,\"condition\":\"多云\"}"
}
]
}
两种协议都要求客户端执行自定义函数。Responses 的内置工具可以由 OpenAI 服务端执行,但自定义函数仍需要调用方解析参数、执行代码、回传结果并继续生成。
六、流式响应
6.1 Chat Completions SSE
data: {"id":"chatcmpl_demo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl_demo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"你好"},"finish_reason":null}]}
data: {"id":"chatcmpl_demo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
6.2 Responses SSE
event: response.created
data: {"type":"response.created","response":{"id":"resp_demo","status":"in_progress"}}
event: response.output_item.added
data: {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_demo","type":"message","status":"in_progress","role":"assistant","content":[]}}
event: response.output_text.delta
data: {"type":"response.output_text.delta","item_id":"msg_demo","output_index":0,"content_index":0,"delta":"你好"}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_demo","status":"completed","output":[]}}
Chat Completions 客户端通常围绕 choices[].delta 聚合文本或工具参数。Responses 客户端应根据事件 type 分发,并分别处理文本增量、工具参数增量、Item 状态和终止事件。仅修改 JSON 字段路径无法兼容两套 SSE 协议。
七、Structured Outputs 字段迁移
7.1 Chat Completions
{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": "提取订单号和金额。内容:订单 A100,金额 88.50 元。"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "order",
"strict": true,
"schema": {
"type": "object",
"properties": {
"order_id": {
"type": "string"
},
"amount": {
"type": "number"
}
},
"required": [
"order_id",
"amount"
],
"additionalProperties": false
}
}
}
}
7.2 Responses API
{
"model": "MODEL_ID",
"input": "提取订单号和金额。内容:订单 A100,金额 88.50 元。",
"text": {
"format": {
"type": "json_schema",
"name": "order",
"strict": true,
"schema": {
"type": "object",
"properties": {
"order_id": {
"type": "string"
},
"amount": {
"type": "number"
}
},
"required": [
"order_id",
"amount"
],
"additionalProperties": false
}
}
}
}
八、Responses 特有的资源生命周期
8.1 后台执行
{
"model": "MODEL_ID",
"input": "分析这份长文档并输出风险清单。",
"background": true
}
{
"id": "resp_background_001",
"object": "response",
"status": "queued",
"background": true
}
调用方可以根据 Response ID 查询执行状态,或在需要时取消任务。对于耗时较长的推理,也可以结合 Webhook、Compaction 或 WebSocket 模式。具体可用能力仍应以目标模型、账户权限和最新官方文档为准。
九、网关兼容设计建议
POST /v1/chat/completions
|
v
Chat Completions Adapter
|
v
Internal Request / Item / Event / Usage Model
^
|
Responses Adapter
^
|
POST /v1/responses
建议内部至少保留以下抽象:
-
InputItem:message、function_call_output、computer result 等输入类型。 -
OutputItem:message、reasoning、function_call、built-in tool call 等输出类型。 -
StreamEvent:文本增量、参数增量、Item 生命周期、Response 生命周期。 -
Usage:input、output、cached、reasoning 等 token 明细。 -
FinishState:completed、incomplete、failed、cancelled 及具体原因。
推荐****:在协议适配完成后再向业务层暴露统一文本、统一工具调用和统一计费对象。不要在网络层直接把 Responses 的 output[] 压缩成单个 assistant 字符串,否则会丢失 reasoning、工具状态、annotations、call_id 和部分 usage 信息。
十、官方资料
以下链接均为 OpenAI 官方文档
https://developers.openai.com/api/docs/guides/migrate-to-responses
https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create/
https://developers.openai.com/api/reference/resources/responses/methods/create/
https://developers.openai.com/api/docs/guides/streaming-responses
https://developers.openai.com/api/docs/guides/conversation-state
https://developers.openai.com/api/docs/guides/background
https://developers.openai.com/api/docs/guides/websocket-mode

浙公网安备 33010602011771号