OpenAI Chat Completions API vs Responses API 深度对比
文章目录
面向正在学习 AI Agent 开发的工程师,系统讲解 OpenAI 两代 API 的设计差异、适用场景、内部实现机制,以及对第三方生态的影响。
1. 背景:为什么会有两套 API?
OpenAI 的 API 经历了三代演进:
Completions API(GPT-3 时代,已废弃)
|
Chat Completions API(GPT-3.5/4 时代,当前行业标准)
|
Responses API(2025年3月推出,面向 Agent 场景的下一代 API)
Chat Completions API 设计于 2023 年,核心定位是"无状态的对话补全"——你发一组 messages,模型返回一条 completion,仅此而已。它不知道上一次对话是什么,不会帮你执行任何工具,也不会自动循环。
随着 Agent 应用的爆发,开发者发现自己在 Chat Completions 之上反复构建相同的基础设施:对话状态管理、工具执行循环、搜索集成、代码沙箱……OpenAI 于是推出了 Responses API,把这些通用能力下沉到平台层。
用 Java 类比:Chat Completions 像是原始的 JDBC——你自己管连接、写 SQL、处理结果集;Responses API 像是 Spring Data JPA——平台帮你管理了大量样板逻辑,你只需要声明意图。
2. 核心设计差异
2.1 请求格式对比
Chat Completions API(POST /v1/chat/completions):
{
"model": "gpt-4o",
"messages": [
{ "role": "system", "content": "你是一个有帮助的助手" },
{ "role": "user", "content": "帮我搜索一下今天北京的天气" }
],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取天气",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}],
"temperature": 0.7,
"max_tokens": 1000
}
Responses API(POST /v1/responses):
{
"model": "gpt-4.1",
"input": "帮我搜索一下今天北京的天气",
"instructions": "你是一个有帮助的助手",
"tools": [{ "type": "web_search" }],
"previous_response_id": "resp_abc123"
}
2.2 关键差异一览
| 维度 | Chat Completions | Responses API |
|---|---|---|
| 端点 | POST /v1/chat/completions | POST /v1/responses |
| 输入格式 | messages 数组(完整对话历史) | input(当前输入)+ previous_response_id(引用历史) |
| 系统提示 | 放在 messages 中,role: "system" | 独立的 instructions 字段 |
| 状态管理 | 无状态,客户端自己维护历史 | 有状态,服务端存储对话历史 |
| 工具类型 | 仅 function(自定义函数) | function + web_search + file_search + code_interpreter |
| 工具执行 | 客户端执行 | 内置工具由平台自动执行 |
| Agent Loop | 客户端自己写循环 | 平台自动编排循环 |
| 响应对象 | chat.completion | response |
| 回复位置 | choices[0].message.content | output[0].content[0].text |
3. 无状态 vs 有状态:最根本的区别
3.1 Chat Completions:无状态模型
每次请求都是独立的。如果你想实现多轮对话,必须自己把完整的对话历史拼接到 messages 中:
# 客户端维护对话历史
messages = [
{"role": "system", "content": "你是一个助手"},
{"role": "user", "content": "我叫小明"},
{"role": "assistant", "content": "你好小明!"},
{"role": "user", "content": "我叫什么?"} # 第二轮
]
# 每次都要发送完整历史
response = client.chat.completions.create(
model="gpt-4o",
messages=messages # 包含所有历史消息
)
这意味着:对话越长,每次请求的 token 消耗越大(因为要重复发送历史);客户端需要自己管理消息列表的增长和截断。
3.2 Responses API:有状态模型
服务端帮你存储了对话历史,你只需要引用上一次响应的 ID:
# 第一轮
response1 = client.responses.create(
model="gpt-4.1",
input="我叫小明",
instructions="你是一个助手"
)
# 第二轮:只需引用上一次的 response ID
response2 = client.responses.create(
model="gpt-4.1",
input="我叫什么?",
instructions="你是一个助手",
previous_response_id=response1.id # 服务端自动拼接历史
)
# response2 会正确回答"小明"
用 Java 类比:Chat Completions 像是无状态的 REST API(每次请求带完整上下文),Responses API 像是有状态的 Session(服务端记住了你是谁)。
3.3 状态管理的工程实现
previous_response_id 背后的实现机制:
客户端发送: { input: "我叫什么?", previous_response_id: "resp_abc" }
|
v
OpenAI 服务端:
1. 根据 resp_abc 从存储中取出之前的完整对话历史
2. 将新的 input 追加到历史末尾
3. 拼接成完整的 messages 数组
4. 调用模型推理(模型看到的还是完整的 messages)
5. 存储新的响应,生成新的 response_id
6. 返回结果
所以模型本身并不"记住"任何东西——它每次看到的仍然是完整的消息序列。"有状态"是平台层的工程实现,不是模型能力。
4. 工具调用:客户端循环 vs 平台自动编排
这是两套 API 在 Agent 开发中最大的实际差异。
4.1 Chat Completions:你来跑循环
import json
from openai import OpenAI
client = OpenAI()
messages = [{"role": "user", "content": "北京今天天气怎么样?"}]
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}]
# 你自己写的 Agent Loop
while True:
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools
)
choice = response.choices[0]
if choice.finish_reason == "tool_calls":
# 1. 模型决定调用工具
messages.append(choice.message)
for tool_call in choice.message.tool_calls:
# 2. 你来执行工具
args = json.loads(tool_call.function.arguments)
result = get_weather(args["city"])
# 3. 你来回传结果
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
# 4. 继续循环,让模型处理工具结果
else:
# 5. 模型生成了最终回复
print(choice.message.content)
break
整个循环逻辑(判断是否需要调用工具 - 执行工具 - 回传结果 - 再次调用模型)全部由你的代码负责。
4.2 Responses API:平台帮你跑循环
from openai import OpenAI
client = OpenAI()
# 使用内置工具,一次调用搞定
response = client.responses.create(
model="gpt-4.1",
input="北京今天天气怎么样?",
tools=[{"type": "web_search"}] # 内置工具
)
# 直接拿到最终结果,中间的搜索过程平台自动完成了
print(response.output[0].content[0].text)
当使用内置工具(web_search、file_search、code_interpreter)时,平台内部自动完成了:模型决定搜索 - 平台执行搜索 - 把搜索结果喂回模型 - 模型生成最终回答。你只需要一次 API 调用。
4.3 Responses API 也支持自定义函数
如果你有自己的工具(比如查数据库、调内部接口),Responses API 也支持 function 类型的工具。此时行为和 Chat Completions 类似——模型返回工具调用,你执行后回传结果:
response = client.responses.create(
model="gpt-4.1",
input="查一下订单 #12345 的状态",
tools=[{
"type": "function",
"function": {
"name": "query_order",
"description": "查询订单状态",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"]
}
}
}]
)
# 如果模型决定调用你的自定义函数,你仍然需要自己执行并回传
# 但可以利用 previous_response_id 简化状态管理
4.4 对比总结
Chat Completions + function calling:
你的代码: 调用API -> 收到tool_call -> 执行工具 -> 回传结果 -> 再调用API -> ...
你负责: 循环控制 + 工具执行 + 状态管理
Responses API + built-in tools:
你的代码: 调用API -> 收到最终结果
平台负责: 循环控制 + 工具执行 + 状态管理
Responses API + custom functions:
你的代码: 调用API -> 收到tool_call -> 执行工具 -> 回传结果(用 previous_response_id)
平台负责: 状态管理
你负责: 工具执行
5. 工具类型:function 不再是唯一选择
5.1 Chat Completions 的工具类型
在 Chat Completions API 中,tools 数组里的 type 字段只有一个值:"function"。所有工具都是你自己定义的函数,模型只负责决定调用哪个函数、传什么参数,实际执行由你的代码完成。
{
"tools": [
{ "type": "function", "function": { "name": "get_weather" } },
{ "type": "function", "function": { "name": "search_db" } }
]
}
虽然 OpenAI 后来推出了 gpt-4o-search-preview 等特殊模型来支持搜索,但那是通过特殊模型实现的,不是通过工具类型扩展。
5.2 Responses API 的工具类型
Responses API 引入了多种内置工具类型:
{
"tools": [
{ "type": "web_search" },
{ "type": "file_search", "vector_store_ids": ["vs_abc123"] },
{ "type": "code_interpreter" },
{ "type": "function", "function": { "name": "my_tool" } }
]
}
| 工具类型 | 说明 | 执行方 |
|---|---|---|
function | 自定义函数,和 Chat Completions 一样 | 你的代码 |
web_search | 联网搜索,模型可以搜索实时信息 | OpenAI 平台 |
file_search | 文件检索,基于向量数据库的 RAG | OpenAI 平台 |
code_interpreter | 代码解释器,在沙箱中执行 Python 代码 | OpenAI 平台 |
computer_use(预览) | 计算机操作,控制虚拟桌面 | OpenAI 平台 |
内置工具的关键特征:模型决定调用,平台自动执行,结果自动回传给模型。开发者无需介入中间过程。
6. 响应格式对比
6.1 Chat Completions 响应
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1677652288,
"model": "gpt-4o",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "北京今天晴,气温22度C。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 15,
"total_tokens": 35
}
}
6.2 Responses API 响应
{
"id": "resp_abc123",
"object": "response",
"created_at": 1753545899,
"status": "completed",
"model": "gpt-4.1-2025-04-14",
"output": [
{
"id": "msg_abc123",
"type": "message",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "北京今天晴,气温22度C。",
"annotations": []
}
]
}
],
"previous_response_id": null,
"usage": {
"input_tokens": 19,
"output_tokens": 10,
"input_tokens_details": { "cached_tokens": 0 },
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 29
}
}
6.3 结构差异
| 维度 | Chat Completions | Responses API |
|---|---|---|
| 顶层对象 | chat.completion | response |
| 回复位置 | choices[0].message.content | output[0].content[0].text |
| 内容类型 | 字符串 | output_text 类型的对象 |
| 状态字段 | 无 | status(completed/failed/in_progress) |
| 历史引用 | 无 | previous_response_id |
| 结束原因 | finish_reason(stop/length/tool_calls) | status + stop_reason |
| 推理统计 | 无 | output_tokens_details.reasoning_tokens |
| 注解/引用 | 无 | annotations(如搜索结果来源) |
7. 推理模型的特殊支持
Responses API 对推理模型(o3、o4-mini)有特殊优化。
7.1 推理令牌跨请求保持
推理模型在思考时会产生大量的"推理令牌"(reasoning tokens)。在 Chat Completions 中,每次请求都是独立的,推理过程无法复用。在 Responses API 中,通过 previous_response_id,平台可以缓存推理过程的 KV cache,后续请求复用之前的思考上下文:
# 第一轮:模型进行了深度推理
response1 = client.responses.create(
model="o3",
input="分析这个复杂的数学问题...",
reasoning={"effort": "high"}
)
# reasoning_tokens: 5000(模型思考了很多)
# 第二轮:基于之前的推理继续
response2 = client.responses.create(
model="o3",
input="如果条件改为X呢?",
previous_response_id=response1.id
)
# 平台复用了之前的推理上下文,不需要从头思考
7.2 推理努力控制
Responses API 提供了 reasoning.effort 参数,让你控制模型的思考深度:
response = client.responses.create(
model="o3",
input="1+1等于几?",
reasoning={"effort": "low"} # low / medium / high
)
这在 Chat Completions 中没有对应的能力。
8. 模型支持范围
Responses API 并非所有模型都支持,这是一个重要的限制。
8.1 支持 Responses API 的模型
推理模型: o3、o3-pro、o4-mini
对话模型: gpt-4.1、gpt-4.1-mini、gpt-4o、gpt-4o-mini
8.2 不支持的模型
GPT-3.5 系列、早期 GPT-4 版本(如 gpt-4-0613)等旧模型不支持 Responses API。用旧模型调用 /v1/responses 端点会直接报错。
8.3 为什么旧模型不支持?
不是因为平台不能给旧模型提供这些工具,而是因为旧模型没有被训练过如何可靠地驱动 agent loop 中的多轮工具调用。Responses API 的 agent loop 要求模型能够:准确判断何时需要调用工具、正确生成工具调用参数、理解工具返回结果并决定下一步动作。这些能力需要专门的训练,旧模型不具备。
9. 工程侧 vs 模型侧:能力的实现层次
Responses API 的能力是两层混合实现的,理解这一点对架构设计至关重要。
9.1 工程侧(Platform/Infrastructure)实现
以下能力由 OpenAI 的服务端基础设施提供,与模型本身无关:
状态管理:previous_response_id 机制。服务端存储对话历史,下次请求时自动拼接。模型本身不知道"状态"的概念,它每次看到的还是一个完整的 messages 序列。
内置工具的执行:web_search(去搜索引擎搜索)、file_search(去向量数据库检索)、code_interpreter(在沙箱中跑代码)。模型只负责"决定调用哪个工具、传什么参数",实际执行全部是平台完成的。
Agent Loop 编排:当模型输出一个工具调用时,平台自动执行工具、把结果喂回模型、让模型继续生成,直到模型输出最终文本。这个循环逻辑是工程侧编排的。
推理令牌缓存:对于 o3/o4-mini,平台缓存推理过程的 KV cache,下次请求时复用,避免重新计算。
9.2 模型侧实现
以下能力是模型权重中训练出来的:
Function Calling 决策:模型在训练时学会了"什么时候该调用工具、生成什么格式的调用参数"。
推理能力:o3 的 chain-of-thought 思考过程是模型内部的能力。
理解工具结果:模型需要理解工具执行的返回值,并据此生成最终回答。
9.3 用 Java 类比
模型 = 你写的 Service 层业务逻辑(核心决策能力)
Responses API 平台 = Spring 框架 + 中间件(事务管理、AOP、消息队列编排)
模型负责"思考和决策",平台负责"编排和执行"。模型说"我要搜索一下天气",平台就去真的搜索,然后把结果递回来。
10. 第三方厂商兼容性
10.1 Chat Completions:事实标准
Chat Completions API 已经成为行业事实标准。几乎所有模型厂商都提供兼容接口:
- DeepSeek:完全兼容
/v1/chat/completions - Google Gemini:提供 OpenAI 兼容层
- 阿里通义千问:兼容 OpenAI 格式
- 腾讯混元、百度文心、字节豆包:均兼容
开发者只需要改 base_url 和 api_key,就能在不同模型之间切换。
10.2 Responses API:极少数厂商跟进
截至目前,只有**阿里云百炼(通义千问)**明确提供了 Responses API 兼容接口。绝大多数厂商(DeepSeek、Google、腾讯、百度等)都没有跟进。
10.3 为什么大多数厂商不兼容 Responses API?
Chat Completions 是"纯模型调用",容易兼容:
客户端 -> 发 messages -> 模型推理 -> 返回 completion
本质上就是一个无状态的 RPC 调用,任何有模型推理能力的厂商都能实现。
Responses API 是"平台能力",兼容成本极高:
客户端 -> 发 input + tools -> 平台编排(状态存储 + 工具执行 + agent loop)-> 返回最终结果
要兼容 Responses API,厂商需要自己实现:服务端状态存储、搜索引擎集成(web_search)、向量数据库(file_search)、代码沙箱(code_interpreter)、Agent loop 编排逻辑、推理令牌的 KV cache 持久化。这些都是重基础设施投入。
用 Java 类比:
Chat Completions = JDBC 驱动接口
-> 任何数据库厂商都能实现 JDBC 驱动
Responses API = Spring Cloud 全家桶(服务发现 + 配置中心 + 网关 + 链路追踪)
-> 你不能说"我兼容 Spring Cloud"只是实现了一个接口
10.4 对开发者的影响
| 场景 | 建议 |
|---|---|
| 需要跨厂商切换模型 | 基于 Chat Completions + 自己实现 agent loop |
| 只用 OpenAI 模型,追求开发效率 | 直接用 Responses API |
| 用 OpenAI Agents SDK | 底层就是 Responses API,绑定 OpenAI 生态 |
| 用 LangChain / LlamaIndex 等框架 | 框架基于 Chat Completions 抽象,天然跨厂商 |
Responses API 本质上是 OpenAI 的平台锁定策略:你用了它的 built-in tools 和状态管理,就很难迁移到其他厂商。
11. Anthropic 的对应方案
Anthropic(Claude)没有提供类似 Responses API 的有状态 Agent 平台。它的策略是:
协议层:保持 Messages API 的简洁性,不做平台级编排。
工具生态:推出 MCP(Model Context Protocol)开放协议,让工具的定义和执行标准化,但工具执行仍然由客户端负责。
Agent 框架:通过开源的 Claude Code 等项目展示 Agent 模式,但 agent loop 在客户端运行。
对比:
OpenAI 的思路:把 Agent 能力做进平台(Responses API)
-> 开发者调一次 API 就能得到最终结果
-> 代价:平台锁定
Anthropic 的思路:保持 API 简洁 + 开放协议(MCP)
-> 开发者自己编排 agent loop
-> 优势:不锁定,工具生态可跨模型复用
12. 迁移指南:从 Chat Completions 到 Responses API
12.1 概念映射
| Chat Completions | Responses API | 说明 |
|---|---|---|
messages 数组 | input + previous_response_id | 输入方式变化 |
messages[0](system) | instructions | 系统提示独立出来 |
choices[0].message.content | output[0].content[0].text | 取回复的路径变化 |
finish_reason | status + output 结构 | 结束判断方式变化 |
n 参数 | 不支持 | Responses API 不支持多候选 |
| 无 | previous_response_id | 新增状态管理 |
| 无 | reasoning.effort | 新增推理控制 |
12.2 代码迁移示例
Before(Chat Completions):
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "你是一个助手"},
{"role": "user", "content": "你好"}
],
temperature=0.7,
max_tokens=1000
)
content = response.choices[0].message.content
After(Responses API):
response = client.responses.create(
model="gpt-4.1",
input="你好",
instructions="你是一个助手",
temperature=0.7,
max_output_tokens=1000
)
content = response.output[0].content[0].text
12.3 迁移时间线
OpenAI 已明确表示 Responses API 是未来方向,Chat Completions API 不会立即废弃但将逐步停止新功能开发。建议:新项目优先考虑 Responses API(如果不需要跨厂商),存量项目按需迁移。
13. 架构决策:什么时候用哪个?
13.1 选择 Chat Completions 的场景
- 需要支持多个模型厂商(DeepSeek、Claude、Gemini 等)
- 使用 LangChain、LlamaIndex 等跨模型框架
- 工具执行逻辑复杂,需要完全控制 agent loop
- 对延迟敏感,不想依赖平台的工具执行速度
- 需要
n > 1的多候选 generation - 团队中有人熟悉 OpenAI 协议生态
13.2 选择 Responses API 的场景
- 只用 OpenAI 模型,追求最快开发速度
- 需要内置工具(web_search、file_search、code_interpreter)
- 构建简单 Agent,不想自己写循环逻辑
- 需要服务端状态管理(多轮对话不想自己存历史)
- 使用 OpenAI Agents SDK
13.3 决策流程图
需要跨厂商切换模型?
|-- 是 -> Chat Completions + 自建 Agent Loop
|-- 否 -> 只用 OpenAI?
|-- 是 -> 需要内置工具(搜索/代码执行)?
| |-- 是 -> Responses API
| |-- 否 -> 两者皆可,Responses API 略优
|-- 否 -> Chat Completions(行业通用协议)
14. 总结
| 维度 | Chat Completions API | Responses API |
|---|---|---|
| 定位 | 通用模型调用接口 | Agent 构建平台接口 |
| 状态 | 无状态 | 有状态 |
| 工具执行 | 客户端负责 | 平台负责(内置工具) |
| Agent Loop | 开发者自己写 | 平台自动编排 |
| 跨厂商兼容 | 事实标准,几乎所有厂商兼容 | 仅 OpenAI + 阿里云百炼 |
| 模型支持 | 所有 OpenAI 模型 | 仅较新模型(gpt-4.1、o3 等) |
| 适合场景 | 灵活控制、多模型切换 | 快速构建 Agent、平台托管 |
| 学习价值 | 必须掌握(行业基础) | 了解趋势(OpenAI 生态专属) |
对于正在学习 AI Agent 开发的工程师,建议的学习路径是:先彻底掌握 Chat Completions + 手写 Agent Loop(理解底层原理),再了解 Responses API 如何将这些逻辑平台化(理解工程演进方向)。这样既有扎实的基础,又能在需要时快速切换到更高层的抽象。
参考来源
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)