OpenAI Responses API 是什么?

从"传纸条"到"打电话"——大模型 API 的一场底层升级,以及它背后的商业博弈


一、核心比喻:从"传纸条"到"打电话"

想象你要和一个超级聪明的助手(AI 模型)合作完成一项任务。

旧方式(Chat Completions API)= 传纸条

你每问一个问题,都要把从头到尾所有的聊天记录写在一张新纸条上递给助手:

  • 第 1 次纸条:“你好。”
  • 第 2 次纸条:“你好。帮我查一下天气。”
  • 第 3 次纸条:“你好。帮我查天气。好的,北京晴天。那上海呢?”

麻烦在哪:

  1. ——每次都要抄写所有历史,纸条越来越长
  2. 你自己管上下文——必须自己记住聊到哪了,确保纸条没漏
  3. 工具调用像接力赛——让助手"查天气再推荐衣服",你得自己编排:发查天气纸条 → 收结果 → 再发推荐衣服纸条

新方式(Responses API)= 打电话

你给助手打了个电话,建立了一条专线,对话是连续的:

  • 你:“你好。”
  • 助手:“你好。”
  • 你:“帮我查一下北京天气。”(助手自动去查)
  • 助手:“北京今天晴天。”
  • 你:“那上海呢?”(助手自动理解你在接着问)

方便在哪:

  1. 轻松——不用每次重复历史,只需记住一个"通话 ID"(previous_response_id
  2. API 自动管上下文——叫"有状态"
  3. 工具调用像吩咐下属——一句话"查天气再推荐衣服",助手自己内部完成整套流程,结果一次性给你

一句话总结

Chat Completions 是"无状态"的——每次请求独立,上下文全靠你维护。
Responses API 是"有状态"的——服务端帮你记住对话,你只需给个 ID。


二、关键变化对比

特性 旧方式(Chat Completions) 新方式(Responses API)
核心概念 消息(Messages) 响应(Response)
上下文管理 你自己负责,每次手动拼接历史 API 自动负责,通过 previous_response_id 关联
工具调用 手动循环,你写代码处理每一步 内建能力,模型自主完成工具调用链
类比 传纸条 打电话

三、四个核心问题拆解

问题 1:数据都存在服务器上,隐私安全怎么办?

是的,但这是"临时会话缓存",不是永久存储。

  • API 会在服务器上保留你的对话状态一段时间(几分钟到几小时),让你能通过 ID 继续对话
  • 不等于拿去训练模型——企业级 API 通常承诺不用 API 数据改进模型
  • 风险仍在——任何数据离开设备都有理论泄露风险

建议:

  • 高度敏感信息(医疗记录、商业机密)→ 不要在 API 调用中明文传输
  • 普通业务场景 → OpenAI 的安全措施足够

问题 2:服务端管上下文,能省 Token 吗?

能,而且是大头。

  • 旧方式:第 10 次请求要把前 9 轮全部内容作为 messages 发送,Token 消耗巨大
  • 新方式:只需发最新消息 + previous_response_id,服务端自动拼接

打个比方:

  • 旧方式 = 每次写信都把以前所有信复印一份一起寄
  • 新方式 = 只写新信,信封上写"请接续我上次的信(编号:12345)",邮局自动把两封信放一起处理

注意:服务端推理时仍然要把完整上下文送进模型,所以服务端成本没降,降的是你的传输量和客户端拼装复杂度

问题 3:previous_response_id 是全局唯一还是每次不同?

每次响应都不同,形成链式结构。

  • 第 1 次请求(无 ID)→ 返回 resp_A
  • 第 2 次请求(带 resp_A)→ 返回 resp_B
  • 第 3 次请求(带 resp_B)→ 返回 resp_C

形成链条:resp_A → resp_B → resp_C → ...

它不是固定不变的"房间号",而是指向上一封回信的引用指针,每一轮都产生新的唯一指针。

问题 4:能不能修改历史?

不能直接改,但有三招"曲线救国":

方法 1:伪造分支历史(最常用)

自己本地维护消息列表,修改后不用 previous_response_id,把修改后的完整列表作为初始上下文发新请求,产生全新对话链。

  • ✅ 完全控制权
  • ❌ 回到手动管理,失去省 Token 优势
方法 2:系统指令覆盖

每次请求注入强力指令:“忽略我之前关于 X 的说法,现在 Y 才对。”

  • ✅ 简单快捷
  • ❌ 不算真修改,只是覆盖模型理解
方法 3:等官方功能

未来 API 可能提供更精细的会话编辑功能。


四、各厂商支持情况(2026 年中视角)

第一梯队:原生支持 OpenAI Responses API

厂商 端点 代表模型 状态管理能力
OpenAI 官方 /v1/responses GPT-5 系列、o3/o4-mini 原生全量支持
阿里云百炼 /compatible-mode/v1/responses Qwen3-Max/Plus/Flash 服务端存 7 天,真支持
百度千帆 /v2/responses DeepSeek-V4、GLM-5、Qwen3 有 store 机制
火山方舟 /responses(新版默认) 豆包大模型 store 可控,部分小模型不支持
腾讯云 TokenHub Responses 兼容模式 GLM-5.2、Kimi K2.7、DeepSeek-V4 部分受限,非全量原生

第二梯队:协议转换层"伪支持"

  • LiteLLM、Vercel AI Gateway、NovAI 等把 /v1/responses 翻译成 /v1/chat/completions
  • previous_response_id 在服务端不生效
  • ❌ 内置工具不会真触发
  • ✅ 形状看起来像 Responses

第三梯队:自己推一套等价协议

厂商 协议 特点
Anthropic(Claude) Messages API + Managed Agents 无状态 + cache_control 前缀缓存,不走 previous_response_id
Google(Gemini) Interactions API previous_interaction_id,状态留 55 天(付费)/ 1 天(免费)

快速判断"真支持"的方法

厂商文档写"OpenAI Responses 兼容"≠ 原生支持。要看有没有明说 previous_response_id 服务端有效期——百炼写 7 天、千帆写 store 机制,才是真的。


五、为什么很多厂商不跟 Responses?

误解澄清:不是"为了省硬件"

  • Responses API 比 Chat Completions 慢 2-3 倍
  • 相同对话长度下 Token 账单几乎没降,服务端还要多做状态重建
  • 真正省 Token 的是 Prompt Cache 命中,跟"谁管状态"无关

结论:支持 Responses 服务端成本反而上升,厂商没有"省硬件"的动机。

真正原因有三:

原因 1:Chat Completions 已是事实标准,换轨成本极高

Chat Completions 是无状态 RPC,任何有推理能力的团队周末就能对齐。Responses 要求服务端有:

  • 响应对象生命周期管理(ID 生成、TTL、压缩)
  • 内置工具运行时(web_search / code_interpreter / 沙箱)
  • 多步 Agent Loop 编排

这不是改个 endpoint,是把"应用层 Agent 框架"下沉到基础设施。

原因 2:各家在推自己的"Responses"
厂商 自己的有状态方案 为什么不兼容 OpenAI
Anthropic Managed Agents + cache_control schema 私有命名,跟了 = 承认 OpenAI 是标准制定者
Google Interactions API 自家推理链表示法(thoughts block),硬塞会丢语义
原因 3:锁定与反锁定(最深层)

Responses 把三样东西绑死在服务端:

  • 对话状态(previous_response_id
  • 工具执行(官方沙箱)
  • 推理链(加密存服务端,客户端看不到)

用得越深,迁移成本越高。兼容 Responses = 帮 OpenAI 修护城河


六、Open Responses:开源社区的"开放标准"反击

是什么?

2026 年 1 月正式亮相的 Open Responses,是把 OpenAI Responses 形状抽出来的开放规范

  • 发起:OpenAI 捐出 2025-03 Responses API 形状做底子
  • 共建:Hugging Face 主导,OpenRouter、Vercel、LM Studio、Ollama、vLLM 等跟进
  • 治理:openresponses.org + GitHub openresponses/openresponses,带合规测试工具

和 OpenAI 闭源版的关键区别

维度 OpenAI 原生 Responses Open Responses
状态管理 强制服务端托管 默认无状态,可选有状态
推理链 只吐 summary + 加密内容 三级:原始思维链 / 加密 / summary
版本机制 隐式 请求头 OpenResponses-Version: latest
内置工具 必须用官方沙箱 区分内部工具(沙箱)和外部工具(MCP)

和 MCP 的关系:各管一段,不抢地盘

  • MCP(Model Context Protocol)= 工具连接标准,无状态,用 handle 参数化
  • Open Responses = Agent 推理/多轮调度标准,可无状态可可选有状态

两者叠加:

  • 本地跑 Ollama/LM Studio → 无状态 Open Responses + MCP 工具
  • 云端百炼/OpenAI → 有状态 + 内置沙箱工具

进度(2026-07)

  • ✅ HF 空间已路由 Kimi/Qwen 通过 Open Responses
  • ✅ LM Studio 0.3.39+ 本地 /v1/responses 兼容
  • ✅ Ollama 近期构建支持
  • ❌ DeepSeek 官方仍只给 Chat Completions
  • ❌ Anthropic 不实现 Responses 形状
  • ⚠️ 治理弱于 HTTP——没有 IETF 级中立组织背书

七、实战代码示例:同一段代码在三个模型间零改动切换

场景设定

假设我们要做一个"旅行助手 Agent":

  1. 先问用户想去哪
  2. 让模型自己调用天气查询工具
  3. 根据天气推荐穿搭
  4. 多轮对话持续追问

我们用 Open Responses 网关(如 Hugging Face 的 evalstate 路由),在 GPT-5.1 / Qwen3-Max / Kimi-K2 之间切换——只改一行 model 名称,其余代码完全不动

完整 Python 示例

"""
Open Responses 跨模型零改动切换示例
====================================
只需改 model 字段,同一段代码在 GPT-5.1 / Qwen3-Max / Kimi-K2 间切换
"""

import httpx
import json

# ============================================================
# 只需改这里 —— 切换模型只换一行
# ============================================================
# MODEL = "gpt-5.1"           # OpenAI 官方
# MODEL = "qwen3-max"         # 阿里百炼(通过 Open Responses 网关)
MODEL = "kimi-k2"            # Moonshot Kimi(通过 Open Responses 网关)

# 网关端点(统一走 Open Responses 协议)
ENDPOINT = "https://evalstate-openresponses.hf.space/v1/responses"
API_KEY = "your-api-key"

# ============================================================
# 第 1 轮:发起对话 + 定义工具
# ============================================================
request_1 = {
    "model": MODEL,
    "instructions": "你是一个旅行助手,需要查询天气后给用户推荐穿搭。",
    "input": "我明天要去北京出差,带什么衣服合适?",
    "tools": [
        {
            "type": "function",
            "name": "get_weather",
            "description": "查询指定城市天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名"}
                },
                "required": ["city"]
            }
        }
    ],
    # Open Responses 特有:控制推理深度
    "reasoning": {"effort": "medium"},
    # 版本声明(Open Responses 开放规范头)
    "headers": {
        "OpenResponses-Version": "latest"
    }
}

resp_1 = httpx.post(
    ENDPOINT,
    headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
    json=request_1,
    timeout=60
).json()

print("=== 第 1 轮响应 ===")
print(f"Response ID: {resp_1['id']}")
print(f"输出: {json.dumps(resp_1['output'], ensure_ascii=False, indent=2)}")

# 保存 ID 用于续接
prev_id = resp_1["id"]

# ============================================================
# 第 2 轮:续接对话(只发新消息 + previous_response_id)
# ============================================================
request_2 = {
    "model": MODEL,
    "input": "那如果改去广州呢?",
    "previous_response_id": prev_id,   # ← 关键:链式续接
    "tools": [{"type": "function", "name": "get_weather", ...}]  # 同上
}

resp_2 = httpx.post(ENDPOINT, ...).json()
prev_id = resp_2["id"]

# ============================================================
# 第 3 轮:用户追问细节
# ============================================================
request_3 = {
    "model": MODEL,
    "input": "广州有什么推荐的餐厅吗?",
    "previous_response_id": prev_id,
    "tools": [{"type": "function", "name": "search_restaurants", ...}]
}

如果换成 Chat Completions,同样的功能要写多少?

"""
同样的功能,用 Chat Completions 要这么写(伪代码对比)
==================================================
"""
messages = [
    {"role": "system", "content": "你是一个旅行助手..."},
    {"role": "user", "content": "我明天要去北京出差,带什么衣服合适?"}
]

# 第 1 轮
resp = openai.chat.completions.create(model="gpt-5.1", messages=messages, tools=[...])
messages.append(resp.choices[0].message)  # 手动追加助手回复

# 如果模型要调工具 → 你得自己检测 tool_call → 自己执行 → 自己把结果塞回 messages
if resp.choices[0].message.tool_calls:
    for tc in resp.choices[0].message.tool_calls:
        result = execute_tool(tc.function.name, tc.function.arguments)  # 你自己写
        messages.append({"role": "tool", "content": result, "tool_call_id": tc.id})
    # 再发一次请求拿最终回复
    resp = openai.chat.completions.create(model="gpt-5.1", messages=messages)

# 第 2 轮 → 你要把整个 messages 数组(含所有历史)再发一遍
messages.append({"role": "user", "content": "那如果改去广州呢?"})
resp = openai.chat.completions.create(model="gpt-5.1", messages=messages)  # 全量重传!

# 第 3 轮 → 再全量重传...messages 越来越长,Token 越来越多

两种写法差距一目了然

维度 Chat Completions Open Responses
第 3 轮发送的数据量 全量 messages(含前 2 轮全部内容) 1 条新消息 + 1 个 ID 字符串
工具调用编排 你写 while 循环 + if 判断 API 内部自动完成
切换模型 改 model 名 + 祈祷格式兼容 改 model 名,协议统一
历史修改 直接改 messages 数组 需伪造分支(见第三节方法 1)
推理链可见 无(模型直接给结果) 可选 reasoning.content 看思维链

哪些字段在闭源 Responses 里会被拒?

字段 OpenAI 闭源 Responses Open Responses
reasoning.content(原始思维链) ❌ 返回 encrypted_content,你解不了 ✅ 开源模型可直接吐原始推理过程
vendor:xxx 扩展前缀 ❌ 未知字段直接 400 报错 ✅ 规范允许厂商自定义扩展
store: false(关闭服务端存储) ⚠️ 部分支持,但默认强制存 ✅ 默认无状态,store 可选开关
previous_response_id 跨模型续接 ❌ 只能在同模型内续接 ✅ 理论上可跨模型(同网关内)
MCP 外部工具引用 ❌ 只认官方内置工具 ✅ 明确区分内部/外部工具

最典型的踩坑场景:

# 你想看 Kimi-K2 的推理过程
request = {
    "model": "kimi-k2",
    "input": "9.11 和 9.9 哪个大?请逐步推理。",
    "reasoning": {"content": "full"}  # ← 要原始思维链
}

# 走 OpenAI 官方端点 → 400 错误:"reasoning.content is not supported"
# 走 Open Responses 网关 → 正常返回,output 里带完整推理步骤

八、与 HTTP/JS 的类比总结

你之前的比喻非常精准,下面是精确对应:

你的比喻 LLM API 圈对应
HTTP 1.1 长期不换 Chat Completions 仍是事实标准,Open Responses 不废它,并列存在
JS 原始版 → TS 是用户多了才推 OpenAI Responses(闭源)→ Open Responses(开源扩展),用的人多了才由社区抽规范
不强制升级 Open Responses 头里 Version: latest,老字段保留,新增字段带 vendor:xxx 前缀
微软推 TS ≠ 官方标准 OpenAI 推闭源 Responses,HF+社区推 Open Responses 做"中立版"

最大区别: HTTP 有 IETF 中立组织管,Open Responses 还挂在社区治理,离真正中立差一步。


九、选型决策树

你的需求是什么?
│
├─ 跨模型可移植 + 自己控状态
│  → Chat Completions + 客户端拼历史 + Prompt Cache
│
├─ 只钉 OpenAI / 百炼 Qwen3 + 要用内置工具
│  → Responses API(闭源版)
│
├─ Claude 长程 Agent
│  → Messages API + cache_control + 自建或 Managed Agents
│
├─ Gemini 多步研究
│  → Interactions API
│
└─ 开源模型本地跑 + 想要 Responses 形状
   → Open Responses(LM Studio / Ollama / vLLM)

十、核心要点速记

  1. Responses API = 有状态 API,用 previous_response_id 链式关联对话
  2. 省的是传输 Token,不是推理 Token——服务端成本反而上升
  3. 数据存服务端是临时缓存,非永久存储,但敏感数据仍建议不明文传
  4. 不能直接改历史,但可伪造分支 / 指令覆盖
  5. 大多数厂商不跟不是省硬件,是商业博弈——拒绝被 OpenAI 锁定
  6. Open Responses 是社区版的开放标准,默认无状态,兼容 MCP,2026 年正在铺开
  7. Chat Completions 短期内不会死——它是事实标准,就像 HTTP 1.1 一直活着
  8. 代码层面:改一行 model 名就能跨模型切换,是 Open Responses 最实用的价值

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐