Responses API 走中转站:和 Chat Completions 的六处差异
input 代替 messages、instructions 代替 system、输出是 item 数组而不是 choices;以及中转站最容易漏做的两件事。
Responses API 是 OpenAI 较新的接口,路径是 /v1/responses,不是 /v1/chat/completions。它和 Chat Completions 不是"同一个东西换个名字",数据结构差别很大。中转站对它的支持普遍晚于 Chat Completions,也更容易做半套。
一、六处核心差异
| 概念 | Chat Completions | Responses |
|---|---|---|
| 输入 | messages | input(字符串或 item 数组) |
| 系统提示 | system 消息 | instructions |
| 输出 | choices[0].message.content | output 数组里的 message item |
| 输出上限 | max_tokens / max_completion_tokens | max_output_tokens |
| 工具定义 | tools[].function | tools[] 扁平结构 |
| 流式事件 | choices[0].delta | 具名事件(response.output_text.delta 等) |
二、最小请求
{
"model": "gpt-4.1-mini",
"instructions": "你是简洁的助手。",
"input": "用一句话解释 DNS 解析。",
"max_output_tokens": 200
}
input 可以直接是字符串,这是 Responses 最方便的地方——单轮对话不需要包成 messages 数组。
三、输出的解析
{
"id": "resp_abc",
"object": "response",
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{"type": "output_text", "text": "DNS 把域名翻译成 IP。"}
]
}
]
}
要拿文本,得遍历 output,找 type == "message" 的项,再遍历 content,找 type == "output_text"。不能像 Chat Completions 那样直接取 choices[0].message.content。
如果代码里写死了后者,换成 Responses 后会拿到 undefined——不报错,输出空白。
四、中转站最容易漏做的两件事
1. 流式事件的转换
Responses 的流是具名事件,例如:
event: response.output_text.delta
data: {"type":"response.output_text.delta","delta":"DNS"}
event: response.completed
data: {"type":"response.completed","response":{...}}
支持不到位的站点会把这些事件拍平成 Chat Completions 的 choices[0].delta,或者干脆只发 response.completed 一个事件。前者会让客户端的 Responses 解析器收不到事件类型,后者等于没有流式。
验证方法:stream=true,数一下收到的 event: 行有几种类型。只有一种就是假的。
2. 工具调用的结构
Responses 的工具定义是扁平的:
{"type":"function","name":"get_weather","parameters":{...}}
而 Chat Completions 是嵌套的:
{"type":"function","function":{"name":"get_weather","parameters":{...}}}
如果站点直接把后者的结构透传给 Responses 端点,请求会 400。反过来,如果你的代码按 Responses 写好了,走一个只支持 Chat 的中转站,也会失败。
五、Responses 特有的能力
previous_response_id:可以把上一轮的 response id 传进来,服务端自动带上历史。省 token,但也意味着你的对话状态存在服务端。- 内置工具:
web_search、file_search等可以直接在tools里声明,不用自己实现。 store:控制是否保留这次 response 供后续引用。
中转站对这三个的支持情况差别很大。previous_response_id 依赖服务端存储,很多站点直接不支持;内置工具需要站点自己代理对应的后端服务,支持率更低。
建议:如果你的应用依赖这三项,先单独验证,不要假设"支持 Responses"就等于"支持全部特性"。
六、验证清单
- [ ]
/v1/responses返回 200 - [ ]
input传字符串能工作 - [ ]
instructions生效(对比有无系统提示的输出差异) - [ ]
max_output_tokens真的截断 - [ ] 输出能按
output[].content[].output_text解析 - [ ] 流式有多个具名事件
- [ ] 工具调用结构正确
- [ ]
previous_response_id是否支持(如需要)
本站检测台的 OpenAI Responses 协议会检查端点可达性、参数遵守和错误形状;流式和工具在当前版本对 Responses 记 SKIP,不会假装通过。
七、要不要迁
Responses 的优势是内置工具和服务端状态,适合做 Agent。劣势是新、中转站支持不齐、生态工具少。
如果你的应用只是简单对话,Chat Completions 更稳;如果你要用内置工具或 previous_response_id,再考虑迁移,并且一定要先验证中转站是否真的实现了这些能力。