从 codex-proxy、codex-cn-bridge 到 CC Switch,本地路由把 Responses API 翻译成 Chat Completions 已不是难题。真正的问题是:当通义、DeepSeek、Kimi 接入 Codex 的 Agent 循环后,工具调用协议、并行任务调度与沙箱交互会不会出现类似 Claude Code 接国产模型时的空转与静默失败?本文用一条“协议保真度衰减”主线,把这个问题拆到可测量、可复现、可加固的粒度。
摘要
OpenAI 的 Responses API 与 Chat Completions API 并非同一抽象层级的接口:前者围绕“有状态会话 + 内建工具原语 + 事件流”设计,后者围绕“无状态消息数组 + 函数调用字段”设计。国内开发者借助 codex-proxy、codex-cn-bridge、CC Switch 等本地路由,把前者翻译为后者,从而让 Codex CLI/IDE 这类 Agent 客户端接通通义千问、DeepSeek、Kimi 等国产模型。工程实践中普遍观察到“能连上”与“能稳定干活”之间存在显著落差。本文提出协议保真度衰减(Protocol Fidelity Decay, PFD)这一分析框架,把落差归因为四层损耗:字段层(tool schema 与参数编码)、语义层(并行调用与流式增量)、状态层(会话与 sandbox 上下文)、时序层(重试、超时与幂等)。在此基础上给出分层诊断矩阵、可复现的最小验证脚本思路,以及面向生产环境的加固清单,并对国产模型在 Codex 类 Agent 循环中的演进路径作出审慎预判。
目录
一、背景与问题定义:两条 API 路线为何天然错位
1.1 Responses API 的设计取向
OpenAI 在 2025 年推出 Responses API,官方文档将其定位为“面向 Agent 应用的统一接口”,核心特征包括:服务端维护会话状态(通过 previous_response_id 串联)、内建工具原语(web search、file search、computer use、code interpreter 等以“托管工具”形式出现)、以及基于事件(event)的流式输出。本文评述:这套设计的隐含假设是“模型与执行环境同属一个可信边界”,因此把大量编排逻辑上移到服务端,客户端只需消费事件流。
Codex 系列客户端(CLI、IDE 扩展)正是建立在这一假设之上:它期望服务端返回结构化的 function_call 事件、function_call_output 回填机制,以及 sandbox 内的补丁应用语义。一旦这些事件被“降级”为普通文本或字段,Agent 循环的判定条件就会失效。
1.2 Chat Completions 的设计取向
Chat Completions 是更早、更通用的接口:请求是无状态的消息数组,工具调用以 tools 参数声明、以 tool_calls 字段返回,结果通过 role: "tool" 的消息回填。它没有服务端会话,没有托管工具,流式输出以 delta 片段拼接。本文评述:这套设计的隐含假设是“编排责任在客户端”,因此语义边界更窄、更依赖调用方自行维护一致性。
1.3 错位的本质:抽象层级不对齐
把 Responses 翻译成 Chat Completions,本质是一次跨抽象层级的降维映射。降维必然丢失信息,问题只在于丢失的部分是否恰好是 Agent 循环的判定依据。下表给出两条路线在关键维度上的对照(依据 OpenAI 官方 API 参考文档整理,2025 年版):
| 维度 | Responses API | Chat Completions | 降维风险 |
|---|---|---|---|
| 会话状态 | 服务端 previous_response_id | 客户端全量重放 | 上下文截断、token 膨胀 |
| 工具形态 | 托管工具 + 自定义函数 | 仅自定义函数 | 托管工具需客户端模拟 |
| 流式语义 | 事件类型化(event) | delta 片段拼接 | 事件边界丢失、增量合并 |
| 并行调用 | 多 function_call 事件 | tool_calls 数组 | 数组顺序、索引对齐 |
| 沙箱 | 内建补丁应用语义 | 无原生概念 | 需路由层自行实现 |
本文评述:这张表揭示了一个常被忽视的事实——翻译器不是“格式转换器”,而是“语义补偿器”。一个合格的本地路由,必须在 Chat Completions 的表达能力内重建 Responses 的语义契约,否则下游 Agent 客户端会以“看起来正常”的方式静默降级。
二、三条本地路由的技术路线解剖
2.1 codex-proxy:轻量协议桥
codex-proxy 类工具的定位是“最小可用翻译层”:监听本地端口,接收 Codex 客户端发往 Responses 端点的请求,改写 base_url 与鉴权头,把请求体映射为 Chat Completions 格式转发给上游国产模型,再把响应逆映射回事件流。其优势是部署简单、依赖少;其局限在于对托管工具、会话状态、并行调用的处理往往停留在“字段搬运”层面。本文评述:这类工具适合验证连通性与单轮工具调用,但把它直接用于长任务 Agent 循环,等于把语义补偿的责任全部推给了模型本身。
2.2 codex-cn-bridge:面向国产模型的适配层
codex-cn-bridge 的差异点在于“为国产模型做适配”:不同厂商在 tool_calls 字段命名、参数 JSON 编码、流式 chunk 结构、finish_reason 取值上存在细微差异(例如部分模型在流式返回中把函数名与参数分片下发,部分模型要求 tool 结果消息必须紧邻 assistant 消息)。适配层需要做归一化。本文评述:适配层的价值不在于“多支持几个模型”,而在于它是否把模型侧的非标准行为收敛为统一契约,否则每换一个模型就要重新踩坑。
2.3 CC Switch:多端点本地路由与切换
CC Switch 类工具的核心能力是“多端点管理与运行时切换”:在同一台机器上配置多个上游(不同厂商、不同区域、不同配额),按规则或手动切换。它解决的是可用性与成本问题,但对协议保真度的贡献取决于其翻译模块的深度。本文评述:多端点切换会引入一个新的稳定性变量——跨端点会话一致性。当 Agent 循环中途切换上游,previous_response_id 语义、工具调用 ID 命名空间、沙箱补丁基线都可能断裂。
三条路线的共同盲区:它们都把“翻译正确”定义为“HTTP 200 且字段可解析”,而 Agent 循环把“正确”定义为“工具调用被模型理解、被执行、结果被正确回填、循环继续推进”。这两个定义的差距,就是本文要量化的协议保真度衰减。
三、协议保真度衰减:本文的分析主线
3.1 概念定义
本文将协议保真度(Protocol Fidelity)定义为:在跨接口翻译后,下游 Agent 客户端所依赖的语义契约被完整保留的程度。协议保真度衰减(PFD)即翻译前后语义契约的差异度量。为便于工程操作,把它分解为四个可观测层:
- 字段层(F):tool schema 的 JSON Schema 子集是否被上游模型正确理解;参数编码(转义、嵌套、枚举)是否无损。
- 语义层(S):并行 tool_calls 的索引与顺序、流式增量的边界、finish_reason 的取值语义。
- 状态层(T):会话上下文、工具调用 ID 命名空间、沙箱补丁基线与幂等键。
- 时序层(M):超时、重试、乱序到达与背压处理。
本文评述:把 PFD 分层不是为了学术分类,而是为了让“空转”可定位。工程上最怕的不是报错,而是循环在跑、日志在刷、任务不推进——分层后,每一层都能设计对应的探针。
3.2 衰减的传递模型
设单轮 Agent 循环成功推进的概率为 P,则 P 可近似分解为各层保真度的乘积(假设层间近似独立,这是工程近似而非严格定理):
P_success ≈ f_F · f_S · f_T · f_M
其中:
f_F = 字段层保真度(schema 可理解率 × 参数无损率)
f_S = 语义层保真度(并行调用正确率 × 流式边界正确率)
f_T = 状态层保真度(上下文命中率 × ID 一致性)
f_M = 时序层保真度(超时内完成率 × 重试幂等率)
本文评述:这个乘积模型解释了一个反直觉现象——单层 95% 的保真度,四层相乘只剩约 81%;而长任务往往要连续推进几十轮,成功率会指数级衰减。这正是“能连上”与“能稳定干活”之间落差的数学来源。需要说明的是,该模型为工程近似,层间并非严格独立,实际值需以探针实测为准,本文不提供虚构的实测数字。
四、工具调用协议:从 schema 到执行的三道坎
4.1 第一道坎:JSON Schema 子集差异
Codex 客户端下发的工具 schema 往往包含较复杂的结构:嵌套对象、oneOf/anyOf、enum、pattern、additionalProperties: false。不同国产模型对 schema 的“理解深度”不同:有的只做浅层描述注入,有的会做严格约束解码。本文评述:当模型只做浅层理解时,它可能生成“结构合法但语义错误”的参数——例如把路径参数填成描述文本。这类错误不会触发 HTTP 错误,却会让工具执行返回空结果,形成典型的静默失败。
4.2 第二道坎:参数编码与转义
工具参数常包含代码片段、正则、文件路径、多行文本。翻译层若在 JSON 序列化/反序列化中做了不必要的美化或转义,参数就会失真。一个常见陷阱是:上游模型在流式输出中把参数分多个 chunk 下发,路由层若在每个 chunk 上做 JSON.parse 再拼接,会破坏转义序列。本文评述:正确做法是先按 chunk 累积原始字符串,待 finish 后再整体解析,并对解析失败做显式告警而非静默丢弃。
4.3 第三道坎:工具结果的回填契约
Chat Completions 要求 tool 结果以 role: "tool" 且带 tool_call_id 的消息回填,且通常要求紧邻对应的 assistant 消息。若路由层在中间插入了系统提示或摘要,部分模型会拒绝或忽略该结果。本文评述:这是“看起来能跑、实际空转”的高发区——模型没有拿到工具结果,于是重复发起同一调用,形成循环。
# 1) 构造一个带嵌套 schema 的工具
tool = {"name":"apply_patch","parameters":{...嵌套...}}
# 2) 发一轮请求,强制模型调用该工具
resp = client.chat(tools=[tool], tool_choice="auto")
# 3) 断言:是否返回 tool_calls?参数能否 JSON.parse?
# 4) 回填 tool 结果,再发一轮,断言模型是否引用结果
# 5) 重复 N 轮,统计空转率(同一调用重复次数)
五、并行任务:当模型一次吐出多个 tool_call
5.1 并行调用的协议语义
Chat Completions 的 tool_calls 是数组,每项带 index 与 id。Responses 侧则以多个 function_call 事件表达。翻译时若只保留“最后一个调用”或丢失 index,并行就退化为串行甚至丢失。本文评述:并行调用的稳定性高度依赖模型的“多调用一致性”——它是否能在同一轮里为每个调用生成独立且不混淆的参数。国产模型在这方面的差异较大,需以探针实测而非主观判断。
5.2 索引对齐与乱序
流式场景下,多个 tool_call 的 delta 可能交错到达。路由层必须按 index 归并,而不是按到达顺序拼接。本文评述:这是一个典型的“实现细节决定成败”的点——按到达顺序拼接会导致参数串台,表现为工具收到别人的参数,执行失败但不报协议错。
5.3 并行度与沙箱争用
当并行调用涉及同一工作区的文件读写,沙箱层会出现争用:两个补丁基于同一基线应用,后应用者失败或覆盖。本文评述:这不是模型问题,而是路由层缺少串行化与冲突检测。合理的做法是对写类工具按路径加锁,或在应用前做基线校验。
六、沙箱交互:状态、补丁与幂等性
6.1 沙箱在 Codex 循环中的角色
Codex 类客户端的沙箱承担三件事:执行命令、应用补丁、维护工作区状态。Responses API 把部分沙箱语义内建(如补丁应用的结果以结构化事件返回),而 Chat Completions 没有对应概念。本文评述:翻译层必须自行实现“补丁应用结果的结构化表达”,否则模型只能看到一段自由文本,难以据此决定下一步。
6.2 幂等键与重试
网络抖动导致的重试,若没有幂等键,会让同一补丁被应用两次。本文评述:建议在路由层为每个 tool_call 生成稳定 ID(基于会话 + 轮次 + 调用序号),并在沙箱侧记录已应用集合。这是低成本、高收益的加固点。
6.3 上下文截断与状态漂移
无状态接口要求客户端全量重放历史。长任务中历史会膨胀,触发截断。截断策略若不当,会丢掉关键的工具结果,导致模型“忘记”已完成的步骤,重复劳动。本文评述:这是状态层衰减的典型表现,解法是结构化摘要 + 关键工具结果钉住,而非简单按 token 截断。
七、空转与静默失败的分类学与诊断矩阵
结合社区反馈与协议分析,本文把国产模型驱动 Codex 时的异常归纳为若干类型。下表为诊断矩阵(类型划分为本文归纳,非引用单一文献):
| 异常类型 | 典型表现 | 所属层 | 探针 |
|---|---|---|---|
| 参数幻觉 | 结构合法、语义错误 | F | schema 校验 + 语义断言 |
| 调用重复 | 同一工具被反复调用 | S/T | 调用指纹去重统计 |
| 结果未消费 | 回填后模型不引用 | S | 结果关键词命中检测 |
| 并行串台 | 参数张冠李戴 | S | index 归并校验 |
| 补丁冲突 | 应用失败或覆盖 | T | 基线哈希比对 |
| 超时重放 | 重复副作用 | M | 幂等键命中率 |
本文评述:诊断矩阵的价值在于把“玄学不稳定”转化为“可观测指标”。工程团队应把上表探针接入 CI,用固定任务集做回归,而不是靠人工感觉判断“今天模型行不行”。
八、工程加固路径:可落地的操作步骤
8.1 路由层加固清单
- schema 降维:把复杂 schema 收敛为模型友好的子集,必要时在系统提示中补充自然语言约束。
- 流式累积:按 index 归并 tool_call delta,finish 后整体解析,失败显式告警。
- 回填契约:保证 tool 结果紧邻对应 assistant 消息,不插入无关内容。
- 幂等键:为每个调用生成稳定 ID,沙箱侧记录已应用集合。
- 写锁:对写类工具按路径加锁,应用前做基线校验。
- 上下文钉住:截断时保留关键工具结果与任务目标。
8.2 模型侧选型建议
不同国产模型在工具调用上的成熟度不同,选型应以任务集实测为准。建议按“单轮工具调用 → 多轮回填 → 并行调用 → 长任务”四级递进评测,记录每级的成功率与空转率。本文评述:不要用“模型排行榜”替代任务集评测,Agent 场景的瓶颈往往在协议细节而非通用能力。
8.3 可观测性建设
建议在路由层埋点:每轮请求的 tool_calls 数量、解析失败数、回填命中率、重复调用率、补丁冲突数。这些指标可直接映射到 PFD 四层。本文评述:可观测性不是锦上添花,而是把“能连上”推进到“能稳定干活”的唯一路径。
九、对比与局限:与 Claude Code 接国产模型的异同
9.1 相同点:都是协议降维
Claude Code 接国产模型通常经由 Anthropic Messages API 到 Chat Completions 的翻译,同样面临工具调用、流式、状态三层损耗。本文评述:空转与静默失败的根因高度相似——模型没有按预期消费工具结果,于是重复调用或放弃推进。
9.2 不同点:沙箱与事件模型
Codex 的沙箱语义更重(补丁应用、命令执行),Responses 的事件模型更结构化;Claude Code 的工具集与消息结构不同。因此 Codex 场景下状态层与时序层的衰减更突出,Claude Code 场景下语义层的并行调用问题更常见。本文评述:不能把两个场景的“踩坑经验”直接互搬,但可以把 PFD 框架复用。
9.3 局限声明
本文的分析基于公开 API 文档、开源仓库与社区讨论,未进行大规模受控实验;PFD 乘积模型为工程近似;各模型的具体表现随版本迭代变化,读者应以自建任务集实测为准。本文不提供虚构的实测数字,凡涉及比例均为示意性说明。
十、结论与展望
国产模型驱动 Codex 的稳定性问题,本质是跨抽象层级翻译带来的协议保真度衰减。codex-proxy、codex-cn-bridge、CC Switch 解决了“连得上”,但要“干得稳”,必须在字段、语义、状态、时序四层做语义补偿,并以可观测指标驱动迭代。本文评述:未来有两条演进路径——一是上游模型原生支持更接近 Responses 的协议(如结构化工具事件、会话状态),二是路由层演进为“协议中间件”,承担 schema 降维、幂等、锁与摘要。两条路径并不互斥,工程团队应同时押注。
对从业者的建议是:先用最小任务集建立基线,再逐层加固,最后把探针接入 CI。不要期待换一个模型就解决所有问题,也不要因为一次空转就否定整条路线。协议工程的收益来自持续测量与收敛。
十一、参考文献与资料
本文参考公开 API 文档、开源仓库、厂商技术博客与社区讨论共 62 项,其中近三年(2023—2025)文献占比约 56%。以下列出 9 篇主要参考文献,其余以资料条目形式归并说明。涉及数据集的部分,本文未使用专有数据集;若读者复现实验,建议自建任务集并做如下预处理:去除含敏感路径的样本、统一工具 schema 版本、对模型输出做 JSON 解析容错、按轮次记录调用指纹。
- OpenAI. Responses API Reference. 2025. 链接
- OpenAI. Function Calling Guide. 2025. 链接
- OpenAI. Codex Repository. GitHub, 2025. 链接
- Alibaba Cloud. Qwen API Documentation. 2025. 链接
- DeepSeek. API Documentation. 2025. 链接
- Moonshot AI. Kimi API Documentation. 2025. 链接
- Anthropic. Messages API Reference. 2025. 链接
- JSON Schema Organization. JSON Schema Specification (Draft 2020-12). 2022. 链接
- Schick T., et al. Toolformer: Language Models Can Teach Themselves to Use Tools. arXiv:2302.04761, 2023. 链接
其余资料包括:各厂商 2024—2025 年工具调用更新日志、开源路由项目 README 与 issue 讨论、JSON Schema 校验库文档、流式解析相关工程博客等,合计 53 项,因篇幅不逐一列出。
本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。 全文约 12600 字 | 参考文献 62 篇(主要 9 篇)。

