OpenAI Chat Completions 与 Responses API 协议差异

结论摘要:OpenAI 当前推荐新项目优先使用 Responses API。Chat Completions 仍受支持,适合维护已有聊天协议和客户端生态。Responses 不只是字段改名,它引入了 Item 数据模型、语义化流事件、服务端上下文状态以及后台任务生命周期。

本文对比的是 POST /v1/chat/completionsPOST /v1/responses。文中的 ID、模型名、token 数量和时间戳均为演示数据;JSON 重点展示协议结构,不代表一次真实接口调用的完整返回。

一、核心结论

  1. 新项目:需要推理模型、内置工具、多轮工具调用或长耗时任务时,优先采用 Responses API。

  2. 存量项目:Chat Completions 没有被官方标记为废弃,可以继续维护,不必仅因为 Responses 发布就立即重写。

  3. 协议兼容简单文本请求可以直接迁移;工具调用、流式响应、上下文状态和返回对象无法仅靠字段重命名完成无损转换。

  4. 网关设计建议分别实现 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_tokenscompletion_tokens input_tokensoutput_tokens
上下文管理 客户端通常重复发送历史消息 手动传递、previous_response_id 或 Conversation
流式处理 chat.completion.chunkchoices[].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

https://developers.openai.com/api/docs/guides/compaction

posted @ 2026-09-03 17:49  alin_qu  阅读(4)  评论(0)    收藏  举报