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);长会话可先用压缩端点缩短。