面向正在学习 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 APIPOST /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 APIPOST /v1/responses):

{
  "model": "gpt-4.1",
  "input": "帮我搜索一下今天北京的天气",
  "instructions": "你是一个有帮助的助手",
  "tools": [{ "type": "web_search" }],
  "previous_response_id": "resp_abc123"
}

2.2 关键差异一览

维度Chat CompletionsResponses API
端点POST /v1/chat/completionsPOST /v1/responses
输入格式messages 数组(完整对话历史)input(当前输入)+ previous_response_id(引用历史)
系统提示放在 messages 中,role: "system"独立的 instructions 字段
状态管理无状态,客户端自己维护历史有状态,服务端存储对话历史
工具类型function(自定义函数)function + web_search + file_search + code_interpreter
工具执行客户端执行内置工具由平台自动执行
Agent Loop客户端自己写循环平台自动编排循环
响应对象chat.completionresponse
回复位置choices[0].message.contentoutput[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_searchfile_searchcode_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文件检索,基于向量数据库的 RAGOpenAI 平台
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 CompletionsResponses API
顶层对象chat.completionresponse
回复位置choices[0].message.contentoutput[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_urlapi_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 CompletionsResponses API说明
messages 数组input + previous_response_id输入方式变化
messages[0](system)instructions系统提示独立出来
choices[0].message.contentoutput[0].content[0].text取回复的路径变化
finish_reasonstatus + 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 APIResponses API
定位通用模型调用接口Agent 构建平台接口
状态无状态有状态
工具执行客户端负责平台负责(内置工具)
Agent Loop开发者自己写平台自动编排
跨厂商兼容事实标准,几乎所有厂商兼容仅 OpenAI + 阿里云百炼
模型支持所有 OpenAI 模型仅较新模型(gpt-4.1、o3 等)
适合场景灵活控制、多模型切换快速构建 Agent、平台托管
学习价值必须掌握(行业基础)了解趋势(OpenAI 生态专属)

对于正在学习 AI Agent 开发的工程师,建议的学习路径是:先彻底掌握 Chat Completions + 手写 Agent Loop(理解底层原理),再了解 Responses API 如何将这些逻辑平台化(理解工程演进方向)。这样既有扎实的基础,又能在需要时快速切换到更高层的抽象。


参考来源

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐