首页
/ CC Switch 本地路由实战:让 Codex 通过 Anthropic Messages 上游运行 Claude 模型

CC Switch 本地路由实战:让 Codex 通过 Anthropic Messages 上游运行 Claude 模型

2026-09-06 16:29:24作者:申梦珏Efrain

本文基于 CC Switch 3.17.0 及以上版本(Anthropic Messages 上游自 3.17.0 引入)。当你的密钥只能访问 Anthropic Messages 协议(/v1/messages)的 Claude 家族中转网关或企业内部网关时,Codex 无法直接连接——因为新版 Codex CLI 只讲 OpenAI Responses API。本文完整讲清楚 CC Switch 如何用一条本地路由打通这个缺口:Codex 保持发送 Responses 请求,路由将请求体转换为 Anthropic Messages 发给上游,再把 JSON/SSE 响应(含推理内容、工具调用、图片)转换回 Responses 结构。读完并按步骤操作后,你可以用 Codex 的交互方式运行任意 Claude 模型,并理解其底层转换链的实现原理。

Codex provider form for a Claude gateway

为什么需要本地路由

Codex CLI 面向 OpenAI Responses API 设计;而各类 Claude 家族中转网关与企业内部网关暴露的是 Anthropic Messages 协议。两种协议的请求体、流式事件和响应结构完全不同——把网关地址直接写进 Codex 配置,只能得到对 /responses 的 404 响应。

这个功能瞄准的场景是:你手上只有一个 /v1/messages 端点——比如某 Claude 家族中转网关的密钥,想以 Codex 的交互方式跑 Claude 模型;或者公司出于合规原因禁用了 Claude Code 客户端、只保留了被许可的 Claude 网关,模型可用、缺的只是一个合规客户端,Codex 正好可以补上这个位置。

CC Switch 的方案是让 Codex 始终与本地路由对话、继续发送 Responses API 请求;路由检测到当前供应商是 Anthropic 格式后,把请求转换为 Anthropic Messages 转发给上游,再把响应转换回 Codex 能理解的 Responses 结构返回。

转换链共四步:

  1. Codex 被接管后,本地配置被写为 base_url = "http://127.0.0.1:15721/v1",且 wire_api = "responses" 被强制保留。
  2. 供应商的 anthropic 上游格式告知路由:真实上游说的是 Anthropic Messages 协议。
  3. 路由把 /responses 重写为 /v1/messages,并把 Responses 请求体转换为 Anthropic 请求体。
  4. 上游返回后,路由把 Anthropic 的 JSON 或 SSE 转换回 Responses 的 JSON/SSE——推理内容(extended thinking)、工具调用、图片都在转换范围内。

从源码结构看,这条链的核心是 transform_codex_anthropic.rs:文件头注释明确说明它是 transform_responses.rs 的镜像方向——后者做"Anthropic 请求 → Responses 请求",本模块做"Responses 请求 → Anthropic 请求、Anthropic 响应 → Responses 响应"。调用入口在 forwarder.rscodex_responses_to_anthropic 分支。

前置条件

先备好三样东西:

  • 已安装且能正常启动 CC Switch(3.17.0 或更高版本);
  • 已安装 Codex CLI 并至少运行过一次,使 ~/.codex/ 目录结构存在;
  • 一个能访问 Anthropic Messages 协议端点(/v1/messages)的 API 密钥——来自某 Claude 家族中转网关或企业内部 Claude 网关;端点地址与鉴权方式以网关文档为准。注意:部分供应商把 Claude API 限定为"仅限 Claude Code 使用",此类密钥经由 Codex 调用可能报错——不确定时先咨询供应商。

由于 Codex 页签目前没有内置 Anthropic 预设,以下步骤走 Custom Configuration 路径——从头到尾只需填四五个字段。

Needs routing marker in the Codex provider list

第一步:添加 Codex 供应商

打开 CC Switch,切到顶层 Codex 页签,点右上角加号新增供应商,保持默认的 Custom Configuration,填写:

  • Provider Name:任意名称,例如 Claude Gateway
  • API Key:你的网关密钥。真实密钥只保存在 CC Switch 中,转发时由本地路由注入,永不进入 Codex 的 live 配置(auth.json 里只有占位符)。
  • API Request URL:只填网关的服务根地址,例如 https://claude-gateway.example.com。带不带尾部 /v1 都可以——路由会自动向 /v1/messages 发请求,不要自己拼 /v1/messages(如果网关文档给的是完整 messages URL,可以打开旁边的 Full URL 开关原样粘贴)。地址栏下方的黄色提示"compatible with OpenAI Response format"是写给直连 Responses 场景的通用文案;选了 Anthropic 格式后按本指南填写即可。
  • Default Model:填一个网关能识别的 Claude 模型 id,例如 claude-sonnet-5;以网关文档中的模型名为准。

然后展开 Advanced Options,把 Upstream Format 从默认的 Responses (native) 改为 Anthropic Messages (routing required)

Advanced options for the Anthropic upstream

选中 Anthropic Messages 后,下方出现三个配套字段:

  • Auth field:决定哪个请求头携带 API 密钥到上游,两者只发其一——按网关文档选择。
    • ANTHROPIC_AUTH_TOKEN (Authorization):发送 Authorization: Bearer <key>。这是默认值,绝大多数 Claude 家族中转网关使用它。
    • ANTHROPIC_API_KEY (x-api-key):发送 x-api-key: <key>。部分遵循 Anthropic 原生头约定的网关要求此值。选错通常表现为 401 / 403。
  • Emulate Claude Code client:默认关闭。仅当网关或其上游把使用限定为"Claude Code 专用"时开启;启用后它会仿造 User-Agent、anthropic-betax-app 请求头,并在系统提示第一行注入 Claude Code 身份标识。普通网关不需要开。在 forwarder.rs 中可以看到对应实现:codex_impersonate_claude_code 为真时调用 prepend_claude_code_system_prompt 改写请求体。若开启后仍被拒绝,见 FAQ。
  • Max output tokens:Anthropic 协议的 max_tokens 是必填项。当 Codex 请求未携带输出上限时,路由回退到保守的 8192,可能截断长回答或深度推理(表现为回答不完整、stop_reason=max_tokens)。遇到截断就在此把它提到模型的真实上限——但不要超过,否则上游直接 400。

源码中这一回退值就是常量 DEFAULT_CODEX_ANTHROPIC_MAX_TOKENS

// Anthropic requires max_tokens; fall back to this default only when the
// Codex request omits max_output_tokens (rare — Codex normally sends it).
// Kept conservative so a low-output-ceiling model or relay does not hard-400
// on the fallback (a too-high default 400s and is non-retryable); 8192 is
// accepted by every current Claude model and virtually all gateways.
const DEFAULT_CODEX_ANTHROPIC_MAX_TOKENS: u64 = 8192;

值得注意的细节:在供应商层面配置的 Max output tokens 优先级更高——forwarder.rs 中,若供应商 meta 里的 max_output_tokens > 0,会先注入请求体的 max_output_tokens,覆盖请求自带的值和默认值;这样 thinking 预算的钳制也能针对真实上限计算余量。

同一区域的 Model Mapping 可选:每行填一个网关能识别的模型 id(如 claude-opus-4-8claude-sonnet-5claude-haiku-4-5-20251001),CC Switch 会据此生成模型目录,让 Codex 的 /model 菜单能列出它们;留空也可以,此时 Codex 只用默认模型。

保存供应商后,卡片上会出现 Needs Routing 标记——这类供应商只在本地路由运行时才能工作。

第二步:开启本地路由并接管 Codex

进入设置页的 Routing 页,展开 Local Routing,完成两个开关:

  1. 打开 Routing Master Switch 启动本地服务(首次开启会弹出确认对话框)。默认地址是 127.0.0.1:15721(端口可在代理面板中修改,与 用户手册 4.1 的说明一致)。
  2. Routing Enabled 下打开 Codex。若只想让 Codex 走路由,Claude 和 Gemini 可以保持关闭(多个应用路由可同时启用,见 用户手册 4.2)。

Enabling Codex takeover on the local routing page

接管后,CC Switch 把 Codex 的 live 配置指向本地路由:base_url = http://127.0.0.1:15721/v1auth.json 中只放占位符。真实的 Claude 密钥留在 CC Switch 的供应商配置里,转发时由本地路由按你选择的 Auth field 注入。

这一步的写入逻辑在 codex_config.rs 中:update_codex_toml_fieldtoml_edit 语法保持地改写 config.tomlbase_urlwire_api 会写入当前 model_provider 对应的 [model_providers.<current>] 段(而非顶层字段),测试用例 base_url_writes_into_correct_model_provider_section 验证了这一点——这也是"接管后 Codex 仍在用 Responses 协议"的直接体现:wire_api = "responses" 被强制写回并保留。

第三步:切换供应商并重启 Codex

回到 Codex 供应商列表,点击 Claude 供应商的 Enable。若路由没在运行,CC Switch 会提示"This provider uses Anthropic Messages API format, requires the routing service to work properly. Start routing first."——回到第二步打开即可。

切换后重启当前 Codex 终端会话:config.toml 与模型目录是在 Codex 进程启动时读取的,运行中的进程不保证热加载。

进入 Codex 后可以逐步验证:

  • 若配置了模型映射,用 /model 查看 Claude 模型是否出现在菜单中;未配置映射时 Codex 直接用默认模型。
  • 发送一个小问题,观察设置 → Routing 页的 "Current Provider" 从 "Waiting for first request..." 变为你的 Claude 供应商,"Total Requests" 开始增长。
  • 在用量面板中,这些请求的模型名如实显示为 claude-*,可按供应商筛选、核对 token 用量。

能力细节与已知限制

  • Prompt 缓存自动生效:转换桥按 Anthropic 惯例注入标准 5 分钟 prompt 缓存标记(系统提示、工具定义、对话历史),长对话不会每轮全价重发——无需任何配置。对应源码是 forwarder.rs 中转换完成后调用 cache_injector::inject,注入器会处理 system 字符串转数组与断点预算。
  • 推理与工具无损:extended thinking 内容经桥接后原样往返;多轮工具调用、图片输入、PDF 输入均完整转换。实现上有个精巧之处:Anthropic 带签名的 thinking/redacted-thinking 块会被 Base64 编码后藏进 Responses 的 reasoning.encrypted_content 字段(前缀 ccswitch-anthropic-thinking-v1:),见 transform_codex_anthropic.rs,使 Codex 在下一轮工具请求中能够原样回放签名思考块。
  • 支持 [1m] 长上下文标记:当默认模型或映射中的模型 id 以 [1m] 结尾(如 claude-sonnet-5[1m]),路由会剥离该后缀并自动加上对应的 1M 上下文 beta 头(context-1m-2025-08-07),前提是网关支持该能力。剥离与置位的代码在 forwarder.rs:因为上游模型名回写可能重新带上 [1m],所以最终请求体上还会再剥离一次。
  • Web search 不可用:在 Anthropic 上游模式下,Codex 内置的 web_search 被刻意禁用——转换层无法为 Anthropic 端点翻译该工具,禁用可避免向模型展示一个必然失败的工具。
  • 截断如实上报:上游在输出上限处停止或流被中断时,Codex 看到的是 "incomplete" 而非伪装的成功,便于发现并调大 Max output tokens。

另外从源码可以补充一个转换细节:Codex 的 reasoning.effort 会被映射为 Anthropic thinking 的 token 预算,见 effort_to_thinking_budget——minimal/low → 2048medium → 8192high → 16384xhigh/max/ultra → 24576;未识别的值返回 None,即不启用 extended thinking(避免误吞 temperature/top_p)。回归测试 test_request_default_max_tokens_leaves_output_headroom 还验证了预算钳制逻辑:默认 8192 上限配 high 档位时,预算被钳到 4096,至少给可见回答留出 4096 余量。

FAQ

上游返回 401 或 403

十有八九是 Auth field 与网关要求不匹配:按网关文档在 ANTHROPIC_AUTH_TOKEN (Authorization)ANTHROPIC_API_KEY (x-api-key) 之间切换重试(多数网关用默认的 Bearer)。同时确认密钥本身有效且有余额。

Codex 报 404 或找不到 /responses

通常是 Codex 路由接管没开,或手动把网关地址写进了 Codex——Anthropic 协议的上游没有 /responses 端点,那样必 404。检查 ~/.codex/config.toml 中当前供应商的 base_url 是否指向 http://127.0.0.1:15721/v1

上游返回 404(路由已开启)

检查 API Request URL:它应该是网关的服务根地址,而不是带其他协议路径(如 /chat/completions)的地址。网关路径不常规时,用 Full URL 开关直接粘贴完整 messages 端点。

回答经常被截断

这是默认 8192 输出上限在起作用。在供应商表单 Advanced Options 的 Max output tokens 调大(别超过模型/网关真实上限),保存后重试。

/model 不显示 Claude 模型

确认模型映射已添加条目,且保存供应商后重启过 Codex——模型目录不会被运行中的进程热加载。默认模型若不在映射中,菜单不会列出它,但直接请求仍可用。

Web search 不工作

设计如此,见"能力细节与已知限制"。需要联网搜索的任务请切回 Responses/Chat 格式的供应商。

报错说使用被限制为 Claude Code

部分供应商把 Claude API 限定给 Claude Code 客户端,经由本链路的 Codex 调用会被拒。尝试打开 Advanced Options 的 Emulate Claude Code client;仍报错则说明限制在供应商侧强制执行——咨询供应商你的密钥能否在 Claude Code 之外使用。普通网关请保持该开关关闭。

合规提示

在"公司禁用客户端但保留网关"的场景使用本方案前,建议先确认这符合所在组织的具体政策——被禁的究竟是特定客户端还是某种使用方式,各地不同。使用第三方中转网关时,请阅读目标网关在计费、合规与数据留存方面的条款。

参考资料

该功能源自社区贡献(PR #5071),感谢 @yeeyzy。

登录后查看全文
热门项目推荐
相关项目推荐