news 2026/5/28 3:13:57

多协议适配管线:Responses API ↔ Chat Completions 翻译层设计与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多协议适配管线:Responses API ↔ Chat Completions 翻译层设计与实现

一、为什么需要多协议翻译

客户端生态的碎片化

AI 编程工具生态中,不同客户端各自为政,催生了三种互不兼容的 API 协议:

  • Claude Code→ 使用 Chat Completions 协议

  • Codex CLI→ 使用 Responses API 协议

  • Anthropic SDK→ 使用 Messages 协议

三个客户端,三种协议,但上游服务只提供 Chat Completions 一种接口。这就像一个插座要适配三种不同标准的插头,硬接只会短路。

传统方案的痛点

面对这种局面,直觉方案各有短板:

  • 跑两个代理:codex-proxy 做协议翻译 + mimo-proxy 做推理缓存 → 运维复杂度翻倍,排查问题时要在两个代理之间来回跳转

  • 改客户端代码:侵入式修改上游开源项目 → 维护成本巨大,上游一更新就得重新适配

  • 单代理只支持一种协议:为了兼容多客户端不得不部署多个实例 → 资源浪费,且共享缓存等能力无法复用

设计目标

基于以上痛点,确立了三个核心目标:

  1. 单代理,多协议入口:一个服务同时暴露三种协议的端点

  2. 统一缓存推理内容:无论请求从哪个协议入口进来,reasoning 都走同一套缓存逻辑

  3. 上游只对接 Chat Completions:对外多协议,对内统一出口,降低维护成本


二、整体架构

text

Claude Code ──→ /v1/chat/completions ──┐ Codex CLI ──→ /v1/responses ──→┤ Anthropic SDK──→ /v1/messages ──→┤ ├──→ reasoning 注入 → Chat Completions → 上游 仪表盘 ──→ /api/* ──→┘

请求进入代理后,经过一条三层处理流水线

  1. 协议翻译层:将 Responses API 或 Anthropic Messages 协议的请求翻译为 Chat Completions 格式

  2. Reasoning 注入层:统一调用inject_reasoning,为每条消息补全推理内容

  3. 上游转发层:通过stream_proxy完成流式或非流式的向上游转发

三层各司其职,协议差异被封印在翻译层内部,后续链路无感知。


三、Responses API 翻译核心

请求翻译:extract_messages

Responses API 的input数组包含三种 item 类型,需要一一映射:

原始类型翻译后
type: "message"role: userrole: assistant
type: "function_call"合并为一条assistant+tool_calls[]
type: "function_call_output"role: tool

几个关键处理细节:

  • 连续 function_call 合并:当多条 function_call 连续出现时,合并为同一条 assistant 消息,tool_calls 按序排列——这是 Chat Completions 协议对多工具调用的标准表示

  • instructions → system message:将 Responses API 顶层的系统指令字段映射为 Chat Completions 的 system 角色消息

  • 消息重排:确保tool消息紧跟在对应的assistant消息之后,避免上游因消息顺序不当而拒绝请求

  • Schema 字段清理:剔除additionalPropertiesstrict等 Chat Completions 不兼容的字段,防止校验报错

流式响应翻译:stream_responses_sse

这是整个翻译层最精细的部分——需要将 Chat Completions 返回的 SSE 事件块,实时重组为 Responses API 规定的事件序列。

纯文本路径的事件序列:

text

response.created → response.in_progress → response.output_item.added (type=message) → response.content_part.added → response.output_text.delta (×N 次增量) → response.output_text.done → response.content_part.done → response.output_item.done → response.completed

工具调用路径的事件序列:

text

response.output_item.added (type=function_call) → response.function_call_arguments.delta (×N 次增量) → response.function_call_arguments.done → response.output_item.done → response.completed

每一个 delta 事件都精确对应 Chat Completions chunk 中的内容增量,下游客户端完全感知不到中间经过了一层协议转换。


四、Anthropic Messages 翻译核心

请求翻译:extract_anthropic_messages

Anthropic 的 Messages 协议在结构上与 Chat Completions 有显著差异,映射关系如下:

Anthropic 字段Chat Completions 字段
system(顶层字段)role: system
content[].type: textrole: assistant+content
content[].type: tool_useassistant+tool_calls[]
content[].type: tool_resultrole: tool
tools[].input_schematools[].function.parameters

Anthropic 将文本、工具调用、工具结果全部平铺在content数组中,而 Chat Completions 是按角色分层的。翻译层需要完成这种“扁平 → 分层”的结构转换。

流式响应翻译:stream_anthropic_sse

Anthropic 的流式事件同样有其独特的事件类型序列:

text

message_start → content_block_start (type=text) → content_block_delta (text_delta ×N 次增量) → content_block_stop → content_block_start (type=tool_use) → content_block_delta (input_json_delta ×N 次增量) → content_block_stop → message_delta → message_stop

每个content_block对应一段独立的内容块(文本或工具调用),块内通过 delta 事件逐步传递增量内容,块之间通过 start/stop 事件明确边界。


五、统一 Reasoning 缓存

架构上最优雅的一点在于:无论请求从哪个协议入口进来,最终都汇入同一条缓存链路

  • 协议翻译层将各类请求统一转成 Chat Completions 格式

  • 随后与原生 CC 路由走完全相同的inject_reasoning逻辑

  • 无需为 Responses API 或 Anthropic 单独维护缓存代码

  • save_reasoning在流结束时统一触发,将本轮推理内容持久化

这种“翻译先行,缓存统一”的设计,让新增一个协议入口的成本降到最低——只需实现翻译层,缓存能力自动复用。


六、模型路由:上游调度

每个上游服务声明一个模型标识,实现请求的精准分发:

yaml

upstreams: - name: "DeepSeek" model: "deepseek-chat" url: "https://api.deepseek.com/v1" - name: "MiMo" model: "mimo-v4" url: "https://api.mimo.com/v1"

路由逻辑简洁明确:请求中的model字段与上游配置精确匹配,未命中时自动回退到活跃上游。配合 SQLite 持久化的上游列表,模型的新增和切换都可以在线完成,无需重启。


七、错误透传设计

代理层刻意去掉了内部的自动重试循环,采用“透明代理”的错误处理哲学:

  • 上游返回 503 → 原样返回 503 给下游

  • 下游客户端(Claude Code、Codex CLI 等)各自按自己的指数退避策略重连

  • 不吞错误、不包装错误信息、不修改状态码

  • 流式请求中发生错误时,抛出UpstreamError→ 路由层捕获 → 以原始状态码响应客户端

这样做的好处是:客户端看到的是“直连上游”的错误行为,不会因为代理的额外重试而引入超时累积或重复请求,也避免了“代理层重试成功但客户端已超时断开”的尴尬局面。


八、代码结构概览

文件职责
src/responses.pyResponses API 请求翻译 + 流式响应事件映射
src/anthropic_translate.pyAnthropic Messages 请求翻译 + 流式响应事件映射
src/routes.py路由注册 + 请求分发(按路径指向不同翻译层)
src/proxy.pyreasoning 注入与缓存 + 流式转发核心逻辑
src/upstreams.py上游模型路由 + SQLite 持久化上游列表

每个模块职责单一,协议翻译逻辑与核心代理逻辑完全解耦,新增协议只需增加翻译文件并注册路由。


九、总结

这套多协议翻译管线实现了三个“统一”:

  • 统一入口:一个代理同时承载三种协议的端点,彻底告别多代理运维的噩梦

  • 统一缓存:外来请求协议各不相同,但在推理缓存层面殊途同归,一份代码服务所有入口

  • 统一出口:上游始终只对接 Chat Completions,内部复杂度对外部完全透明

流式事件映射做到了位,下游客户端感知不到代理的存在。模型路由让一个代理同时服务多个供应商,而错误透传设计保证了代理不成为链路中的“黑盒”。整个方案的核心思路可以概括为一句:协议差异是入口的事,缓存和转发是所有人的事

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 3:13:30

大家都在电脑上安装了openclaw了吗?

我没在自己电脑上装openclaw,买了个Linux云服务器,2核2G运行内存,完全够用了,主要OpenClaw权限太大,用云服务器不会影响到本地文件的安全,玩起来没啥负担。 LLM用的是Minimax M2.5和Qwen 3.5Max&#xff0…

作者头像 李华
网站建设 2026/5/28 3:13:20

高匿代理如何隐藏真实 IP:TCP/IP 协议与 HTTP 头深度解析

很多人知道高匿代理能隐藏 IP,但不清楚技术细节:数据包如何改写?协议头如何清洗?为什么普通代理会暴露痕迹?本文从 TCP/IP 底层到 HTTP 应用层,拆解高匿代理 “隐身” 的完整技术流程,让你彻底看…

作者头像 李华
网站建设 2026/5/28 2:57:05

别只盯着模型!TensorRT+C++部署后,推理时间忽快忽慢?试试这3个系统级调优(附NVIDIA官方建议)

TensorRTC部署后推理时间波动的系统级调优指南引言在工业级AI应用部署中,我们常常遇到一个令人困惑的现象:明明使用相同的模型、相同的硬件配置,推理时间却会出现难以解释的波动。这种不稳定性可能导致实时系统出现延迟峰值,影响整…

作者头像 李华
网站建设 2026/5/28 2:50:59

OpenClaw 环境搭建|Windows 零代码部署方案

OpenClaw 一键安装包|可视化部署,简化环境配置流程 ✨适配系统:Windows10/11 64 位 当前版本:v2.7.5(虾壳云版) ✨核心优势:全程可视化操作,不用命令行、不用手动配置 Python/Node.…

作者头像 李华
网站建设 2026/5/28 2:47:33

推荐1款简单实用的免费软件,Windows 必备!

聊一聊对于我们这些对电脑不懂的。又经常使用电脑的,不知道怎么对电脑进行优化。这时候就需要工具来帮我们实现。今天给大家分享一款系统优化工具。软件介绍WiseCare365 Pro这是一款好用的系统工具,用过的人都知道。电脑每天运行都会产生垃圾&#xff0c…

作者头像 李华