Responses 差异
与 OpenAI 官方 Responses API 对齐,并额外提供同路径的 WebSocket 传输和会话压缩端点。差异集中在流式结束方式、非流式响应少一个便捷字段、平台扩展字段、个别模型上托管工具的模拟方式。
支持清单
✅ 按官方语义支持(行为不同处在说明里加注);⊘ 不支持(说明写明实际发生什么)。
| 特性 | 状态 | 说明 |
|---|---|---|
| 顶层字段 | ||
model |
✅ | 填模型名称,以 /v1/models 返回为准 |
input |
✅ | 字符串或输入条目数组,至少一项 |
instructions |
✅ | 原样发给模型 |
tools / tool_choice |
✅ | 字符串与对象写法都收 |
temperature / top_p / max_output_tokens / stop / seed / parallel_tool_calls |
✅ | 原样发给模型 |
reasoning |
✅ | effort 七档 + none(见总览页);summary 原样发给模型 |
text.format |
✅ | text / json_schema / json_object 三种 |
store / previous_response_id / background |
✅ | 原样发给模型 |
metadata / truncation / service_tier / prompt_cache_key / user / include / conversation / top_logprobs / safety_identifier |
✅ | 原样发给模型 |
max_tool_calls |
✅ | 平台扩展:托管工具调用预算,平台自己消费,见下文 |
stream_options |
⊘ | 不携带;usage 由平台计量后放在终态事件里 |
| 输入条目(input[] 里) | ||
message |
✅ | 文本或内容块数组 |
| 无 type 简写 | ✅ | {role, content},按 message 处理 |
function_call / function_call_output |
✅ | 函数调用往返;function_call 缺 call_id 时用 id |
reasoning |
✅ | 思考历史(summary + encrypted_content) |
compaction |
✅ | 压缩结果回填为输入,见下文压缩端点 |
| 内容块(message.content[] 里) | ||
input_text / output_text |
✅ | 文本 |
input_image |
✅ | image_url / file_id / file_data |
input_file |
✅ | file_id 或内联 base64 |
output_image |
✅ | URL |
| 工具类型 | ||
function |
✅ | strict 标记保留 |
| 托管工具 | ✅ | web_search、file_search、computer_use_preview、code_interpreter——平台侧执行;个别模型上模拟为普通函数,见下文 |
mcp |
⊘ | 返回 400,见总览页 |
| 响应形态 | ||
| 流式 SSE | ✅ | 没有 [DONE] 结束标记,见下文 |
| 非流式 JSON | ✅ | 完整 Response 对象;没有 output_text 便捷字段,见下文 |
| WebSocket | ✅ | 同路径升级,见下文「WebSocket 传输」 |
| 压缩 | ✅ | POST /v1/responses/compact,内容与 id 两种写法都收,见下文 |
与官方的差异
流式没有 [DONE] 结束标记
官方的流以 data: [DONE] 结束;平台的流以终态事件(response.completed / response.incomplete / response.failed)结束并关闭,不再补 [DONE]。从 Chat 迁移的客户端不要等这个标记。
返回(流的最末一帧,之后流直接结束)
event: response.completed
data: { "type": "response.completed", "response": { … } }
非流式响应没有 output_text 字段
官方 HTTP 响应本来就没有 output_text——那是官方 Python SDK 的便捷属性。自己解析 HTTP 响应的客户端从 output[] 里取文本。
返回(节选)
{
"id": "resp_…",
"output": [
{
"type": "message",
"role": "assistant",
"content": [ { "type": "output_text", "text": "你好,Franca" } ]
}
],
"usage": { … }
}
文本在 output[] 里 type 为 message 的条目中,取其中的 output_text 块。
max_tool_calls:托管工具调用预算
限制托管工具在一次请求里的调用次数。这是平台的扩展字段,由平台自己消费,不发给模型;取值须为 ≥ 1 的整数,不写时默认 8。预算按已执行的调用次数计:一轮并行发起的多个调用整批执行,可能一次花掉甚至超出剩余预算;预算用尽后的下一轮由平台强制收尾作答,强制收尾仍发起新调用则请求失败。Messages 接口收同一种写法(见Messages 兼容说明)。
请求
{
"model": "your-model",
"input": "查一下今天北京的天气",
"tools": [{ "type": "web_search" }],
"max_tool_calls": 5
}
压缩端点与平台编码
POST /v1/responses/compact 按官方语义可用:把长会话压成一条 compaction 条目,下一轮放进 input 续接。返回的 encrypted_content 是平台自己的编码(franca.v1. 前缀),只在平台内有效。
请求
{
"model": "your-model",
"input": [ …完整会话… ]
}
返回(output 节选)
{
"id": "resp_…",
"output": [
{ "type": "compaction", "id": "cmp_…", "encrypted_content": "franca.v1.…" }
]
}
把 OpenAI 官方的压缩结果(gAAAAA… 开头)发到平台会返回 400,报错说明原因;压缩结果不跨平台。
个别模型上托管工具按普通函数模拟
声明了托管工具而该模型只支持普通函数时,平台把托管工具改写成改名函数发给模型,调用仍在平台侧执行;客户端看到的输出条目仍是官方格式。
请求
{
"model": "your-model",
"input": "搜索一下今天的新闻",
"tools": [{ "type": "web_search" }]
}
返回(output 节选,仍是官方格式)
[
{ "type": "web_search_call", "id": "ws_…", … },
{ "type": "message", … }
]
WebSocket 传输
Responses 端点支持 WebSocket:连接 wss://api.model-r.com/v1/responses(与 HTTP 同路径),升级时带同样的 Authorization: Bearer …。每条消息是纯文本 JSON,连接寿命 60 分钟。
- 并行会话:
response.create可带stream_id(1–256 个字符)。同一个 stream_id 的请求按先后顺序执行,不同的 stream_id 并行。通道正忙时新的请求立刻收到lane_busy错误,不排队。 - 事件格式:每个服务端事件是一条 JSON 文本消息,没有 event: 行、没有 [DONE];都带
sequence_number(连接内从 0 递增),带了 stream_id 的会话会回显它。
发送(一条文本消息)
{
"type": "response.create",
"model": "your-model",
"input": "你好",
"stream_id": "task-1"
}
收到(每个事件一条消息)
{ "type": "response.created", "sequence_number": 0, "stream_id": "task-1", … }
{ "type": "response.completed", "sequence_number": 42, "stream_id": "task-1", … }
出错时
{
"type": "error",
"error": { "type": "invalid_request_error", "code": "lane_busy", "message": "…" },
"status": 400,
"stream_id": "task-1",
"sequence_number": 7
}
- 边界:单条消息与 HTTP 一样上限 16MB;并行通道至多 16 条;读得太慢的连接会被关闭(代码 1011)而不是无限堆积;可安全重连的关闭码为 1001 / 1005 / 1006 / 1011 / 1012 / 1013 / 1015。
- 会话与重连:
store:false的会话存在连接上(最多 32 条响应,按访问顺序淘汰),连接结束就没有了——重连后用previous_response_id续接会得到previous_response_not_found。要跨连接续会话,每轮发送完整输入(包括encrypted_content);长会话可先用压缩端点缩短。