codex 提供方将映射模型的推理路由到你的 ChatGPT / Codex
订阅,而不是 API 密钥。它复用 Codex CLI 已写入
~/.codex/auth.json 的凭据,因此无需粘贴任何东西,也没有按 token 计费 —— 请求以你的 ChatGPT 账户进行认证,并由 codex CLI 所交谈的同一后端应答。
本页是端到端的设置。它链接到更深入的主题页面 (力度与上下文、模型发现、 提供方),而不是重复它们。
快速开始
让编码 agent 为你完成接入 —— shunt add 会打印该提供方的设置蓝图
(离线且只读;配置由 agent 编辑,该命令绝不会修改配置):
shunt add upstream codex --print | claude或者按照下面的手动步骤操作。
工作原理
codex 是一个内置的 kind = "responses" 提供方:shunt 将 Claude Code 的 Anthropic
Messages 请求转换为 OpenAI Responses API,发送到 ChatGPT 账户的 Codex 后端,
并将流式回复转换回来。三点使其成为“Codex”而非普通的 OpenAI:
| 方面 | 值 |
|---|---|
| 端点 | <base_url>/codex/responses |
| 认证 | 来自 ~/.codex/auth.json 的 ChatGPT OAuth,自动刷新 |
| Responses 方言 | Chatgpt 风格 —— 丢弃 codex 从不发送的参数(如 max_output_tokens),发送 store: false,往返传递加密的推理 |
该方言由 auth = "chatgpt_oauth" 决定,而非提供方名称。
当 Codex 账户组成池时,成功的后端响应还会把所报告的 x-codex-* 限流窗口填入管理后台的 Pool health。约 5 小时的窗口显示在 5h,约 7 天的窗口显示在 7d;不受支持的每日、每月窗口会被忽略。Codex 没有 7d_oi 对应项。所记录的窗口还会用于配额感知的池选择 —— 见 Codex 多账户。
1. 登录
用 Codex CLI 登录一次。shunt 读取并刷新它所写入的文件 —— 它不会 为 Codex 运行自己的登录。
codex login这会创建 ~/.codex/auth.json。如果该文件缺失、没有 token,或其刷新 token
已失效,shunt 会返回一个 authentication_error,提示你再次运行 codex login。
2. 提供方块(可选)
codex 是内置的 —— 你无需声明它。以下是完整的默认值;部分表
只覆盖你设置的键(配置映射深度合并):
[providers.codex]
kind = "responses"
base_url = "https://chatgpt.com/backend-api" # shunt 追加 /codex/responses
auth = "chatgpt_oauth" # 读取 + 自动刷新 ~/.codex/auth.json
# effort = "high" # 可选的默认推理力度(§4)
# count_tokens = "tiktoken" # 默认;"estimate" 表示退出常见覆盖:为所有 Codex 流量固定一个默认 effort,或设置
count_tokens = "estimate"。api_key_env / api_key_header 不适用于 chatgpt_oauth ——
凭据来自 auth 文件。每个键见 配置参考。
3. 将一个模型路由到 codex
请求的 model id 选取提供方。优先级:匹配的 [models.upstream_model] 条目 → 精确 [[routes]] →
[[route_prefixes]] → server.default_provider。
[[routes]]
model = "gpt-5.6-sol" # Claude Code 发送的 id(见下方 §4)
provider = "codex"
# upstream_model = "gpt-5.6-sol" # 可选:向上游转发一个不同的 slug
# effort = "high" # 可选:为该路由固定力度upstream_model 让 Claude Code 发送的 id 可以不同于后端接收的 slug —— 这是
发现别名 背后的机制,也是一种无需改动 Claude Code 环境
即可替换真实 slug 的方法。
4. 在 Claude Code 中选择模型
Claude Code 的 /model 选择器只认以 claude/anthropic 开头的发现 id,因此一个
裸的 gpt-* id 需要两条路径之一 —— 它们以 claude- 前缀分界,互不重叠:
claude-… 发现别名 |
非 claude- id(gpt-5.6-sol) |
|
|---|---|---|
通过发现进入 /model 选择器 |
✅ 自动列出,多个模型 | ❌ 被 Claude Code 丢弃 |
ANTHROPIC_CUSTOM_MODEL_OPTION |
❌ 不生效 | ✅ 加入选择器(一个 id) |
CLAUDE_CODE_MAX_CONTEXT_TOKENS 窗口 |
❌ 忽略 → 200k | ✅ 真实窗口 |
主要路径 —— 直接把 slug 加入选择器:
export ANTHROPIC_CUSTOM_MODEL_OPTION="gpt-5.6-sol"该 id 正是 shunt 路由所依据的,因此它必须通过匹配的 [models.upstream_model] 条目、[[routes]]
或 [[route_prefixes]] 规则来解析。这是推荐路径 —— 它是唯一也能让你设置准确上下文
窗口的路径。要改为在选择器中自动列出多个 Codex 模型,请使用一个 claude- 命名的
发现别名(接受 200k 窗口的取舍)。
让一个子 agent 用上 Codex slug
一个子 agent 可以运行在 Codex slug 上,而主会话仍留在 Claude。model: frontmatter
字段接受任意字符串(不同于 Agent/Task 工具的 model 参数,后者只接受
内置别名)。要将一个现有子 agent 指向 gpt-5.6-sol,编辑其
.claude/agents/<name>.md 并设置 model::
---
name: researcher
description: Deep research agent.
model: gpt-5.6-sol # 原为:sonnet(或缺省 → 继承)
---
<the agent's system prompt — unchanged>生成它时不带 model 覆盖(工具参数优先于 frontmatter)。解析顺序:
CLAUDE_CODE_SUBAGENT_MODEL > 工具 model > frontmatter > inherit。要强制每个子 agent
都用同一个 slug,设置 export CLAUDE_CODE_SUBAGENT_MODEL="gpt-5.6-sol"。
无论哪种方式,该 slug 都需要通过匹配的 [models.upstream_model] 条目、[[routes]] 或
[[route_prefixes]] 规则进行显式路由,并且由于是非 claude-,它遵从
CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1 和 CLAUDE_CODE_MAX_CONTEXT_TOKENS —— 窗口会自动
跟随 id。
将分层别名重映射到 Codex
除了添加一个自定义 id,你还可以将 Claude Code 的内置分层别名重新指向 Codex slug, 使整个会话的分层系统解析到你的 ChatGPT 订阅 (model-config 环境变量)。
| 环境变量 | 控制 |
|---|---|
ANTHROPIC_DEFAULT_HAIKU_MODEL |
haiku 别名以及后台“小而快”模型 |
ANTHROPIC_DEFAULT_SONNET_MODEL |
sonnet 别名 |
ANTHROPIC_DEFAULT_OPUS_MODEL / ANTHROPIC_DEFAULT_FABLE_MODEL |
opus / fable 别名 |
一个双层设置 —— haiku → gpt-5.6-luna,sonnet → gpt-5.6-sol:
export ANTHROPIC_DEFAULT_HAIKU_MODEL="gpt-5.6-luna"
export ANTHROPIC_DEFAULT_SONNET_MODEL="gpt-5.6-sol"
# 更好看的选择器标签(_NAME/_DESCRIPTION 配套项在网关上有效)
export ANTHROPIC_DEFAULT_SONNET_MODEL_NAME="GPT-5.6-Sol"
export ANTHROPIC_DEFAULT_SONNET_MODEL_DESCRIPTION="ChatGPT/Codex Sol via shunt"
export ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME="GPT-5.6-Luna"
export ANTHROPIC_DEFAULT_HAIKU_MODEL_DESCRIPTION="ChatGPT/Codex Luna via shunt (background tier)"# shunt.toml —— 两个解析后的 id 都需要一条路由
[[routes]]
model = "gpt-5.6-luna"
provider = "codex"
[[routes]]
model = "gpt-5.6-sol"
provider = "codex"现在在 /model 中选择 Sonnet 会通过 Codex 运行 gpt-5.6-sol,而每个后台/haiku 任务
运行 gpt-5.6-luna —— 解析后的 id 正是 shunt 路由所依据的,因此不需要
ANTHROPIC_CUSTOM_MODEL_OPTION。
5. 推理力度
用 Claude Code 的常规控制项设置力度(/effort、/model 滑块、--effort)。
shunt 将其映射到 Responses 的 reasoning.effort,对不支持 max 的 slug 将
max → xhigh 折叠(只有 gpt-5.6 和 gpt-6 系列支持)。
完整优先级和力度表:力度与上下文。
Fast 模式
Codex CLI 的 /fast 开关并不改变模型或力度——它发送的是 Responses API 的顶层字段
service_tier: "priority",这一档位被称为“Fast”(以更高的用量换取更快的响应)。shunt 把同一个
开关暴露为配置键,与 effort 完全一致,可在提供方级别和路由级别设置:
[[routes]]
model = "gpt-5.6-sol"
provider = "codex"
# service_tier = "priority" # 可选:启用 Codex 的“Fast”模式可接受的值:fast(旧式别名,会被规范化为 priority)、priority、flex 或 default
(仅客户端使用的哨兵值,从不发送到线上)。默认关闭,只有在显式配置时才会发送;与 effort 一样,
路由级别的值胜过提供方级别的默认值——包括显式设为 default 的路由,它会让该路由退出提供方级别的
priority/flex 档位,而不是继承它。完整的键参考:配置参考。
Codex CLI 本身把 gpt-6-sol 和 gpt-6-luna 默认设为 Fast(priority),因为它们的
models.json 条目设置了 default_service_tier。这是后端不会应用的客户端默认值,因此在本指南配置的
Claude Code 路由上,除非你设置 service_tier = "fast",这些模型都以标准档位运行。
连接到 shunt 的 Codex CLI 则不同:该端点原样转发请求,因此 CLI
会保留它自己发送的档位。
最终发送到线上的档位也会通过 Codex CLI 的 x-codex-routing-hint 头回传给后端,格式为
model=<upstream model>;tier=<tier>(未发送档位时只有 model=<upstream model>)。shunt 与 Codex CLI
一样,只在 ChatGPT OAuth 路径上发送这个头——HTTP 请求中作为请求头,WebSocket 传输中作为握手头。
经由前缀路由或 default_provider 时,upstream 模型就是客户端自己的 model 字符串,因此该头以防御方式
构造:只有看起来合理的 slug(非空、不超过 128 字节、只含 ASCII 字母/数字以及 - _ . : / +)
才会发送,否则只丢弃该头,请求照常发出。
6. 上下文窗口
Claude Code 为映射的 id 将其上下文栏固定标定为 200k。gpt-5.6-sol 的真实窗口
是 372k(gpt-5.5 是 272k),因此为一个非 claude- id 提高它:
export CLAUDE_CODE_MAX_CONTEXT_TOKENS=372000它是全局的(每个会话一个值),将其设置得大于真实窗口会导致
prompt is too long 溢出反复折腾 —— 请把它匹配到你映射模型中最小的真实窗口。
shunt 会重写该溢出,使 Claude Code 自动压缩并重试,但每次往返
都是浪费的延迟。详情、实测边界以及 count_tokens 行为见:
力度与上下文。
完整示例
shunt.toml:
[server]
bind = "127.0.0.1:3001"
default_provider = "anthropic"
[providers.codex]
effort = "high" # 可选:为所有 Codex 流量固定 high 力度
[[routes]]
model = "gpt-5.6-sol"
provider = "codex"Shell(shunt 和 Claude Code 都带这些运行):
codex login # 一次性
./target/release/shunt run # 启动网关
export ANTHROPIC_BASE_URL=http://127.0.0.1:3001
export ANTHROPIC_CUSTOM_MODEL_OPTION="gpt-5.6-sol" # 加入 /model 选择器
export CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1 # 让力度滑块触达 Codex
export CLAUDE_CODE_MAX_CONTEXT_TOKENS=372000 # gpt-5.6-sol 的真实窗口从 /model 选择 gpt-5.6-sol。会话中的其他一切仍原样流向 Anthropic;
只有映射模型的推理由你的 ChatGPT/Codex 订阅应答。
网页搜索
Claude Code 内置的 网页搜索 无需额外设置即可通过 Codex 路径工作。启用后,Claude Code 会发送托管的
web_search_20250305 工具,shunt 将其注册为 Responses API 的托管 web_search 工具,因此搜索会在
后端真正执行,而不是作为一次未完成的工具调用被退回。
- 域名过滤器会一并传递 —— Claude Code 的
allowed_domains/blocked_domains会成为 Responsesweb_search的filters。 - 适用于
codex(ChatGPT)与openai(标准 Responses)提供方。 - xAI / Grok 路由不支持 —— Grok 的 Responses API 只接受函数工具,因此 shunt 会在那里丢弃托管的网页
搜索工具;网页搜索请使用
codex或openai路由。
工具搜索
Claude Code 的 工具搜索 —— 延迟 MCP / LSP 工具的 schema,仅在需要时通过 ToolSearch 工具揭示,
从而不让模型把上下文花在从不调用的工具上 —— 可以通过 Codex 路径工作。在客户端启用它:
export ENABLE_TOOL_SEARCH=true当 base URL 不是第一方 Anthropic 主机时,Claude Code 会禁用其乐观式工具搜索,而 shunt 并非第一方主机。
因此若不设置此标志,从第一轮起每个工具的完整 schema 都会发送到上游,该功能形同虚设(仍能工作,但没有任何
节省)。客户端自身的约定是:如果你的代理会转发 tool_reference 块,就设置
ENABLE_TOOL_SEARCH=true —— shunt 正是这样做的。
启用后,shunt 只对已确认支持该协议的上游,把工具搜索映射到 OpenAI Responses API 自身的原生、客户端执行
的 tool_search 协议,其余所有情况都保留 #43 文本 shim:Claude Code 的 ToolSearch 工具变为
tool_search(execution: "client")工具,其 tool_use 变为 tool_search_call,而 tool_reference
结果变为一个 tool_search_output 条目,以结构化 JSON 携带已加载工具的完整 schema,附加在 input 的
末尾。这一点很重要,因为另一种做法 —— 把被揭示工具的 schema 折回请求的 tools 数组 —— 会在每次揭示时
使缓存的提示前缀失效:tools 正是这个可缓存前缀的一部分,shunt 每一轮都会依据客户端历史重新推导它,数组
一旦增长,就会迫使后端从工具边界开始重新处理整段对话。原生协议只以追加方式扩展 input 历史,tools
保持不变,因此缓存前缀在每次揭示后都能存活。
- 使用
codex与openai内置提供方的默认(原生)行为无需改动shunt.toml——ENABLE_TOOL_SEARCH这一层纯粹是 Claude Code 的环境变量。 - 适用于所有
kind = "responses"的提供方;某个提供方默认走原生还是走 shim,取决于其上游主机 —— 见下文 原生协议。 - 不延迟的工具(以及上文的托管
web_search工具)始终会被转发;仅可延迟的工具才会被渐进揭示。
原生协议
要求 —— 不受支持的组合会静默回退到 #43 文本 shim,不会报错。该 shim 仍会把每个尚未揭示的延迟工具排除在
tools 数组之外,但一旦 Claude Code 揭示了某个工具,shim 就会把它的完整 schema 渲染为 tool_reference
文本,并且把该工具重新加入 tools 数组以便模型能够调用它 —— 此后该 schema 会被发送两次,并且每次揭示
都要承担上文所述的缓存失效代价:
- 上游必须是标准 OpenAI 或 ChatGPT/Codex 风格的 Responses 后端。xAI / Grok 路由始终保留 shim。
- 路由到的模型必须是 gpt-5.4 及以上(
gpt-5.4、gpt-5.5,或gpt-5.6系列)。精确 sluggpt-6-astra、gpt-6-sol、gpt-6-luna、gpt-6.1-sol也符合条件。更早的 slug (gpt-5.2及以下)无论tool_search如何设置都会保留 shim。 - Claude Code 一侧仍然需要
ENABLE_TOOL_SEARCH=true—— 这个标志只改变 shunt 如何 把该功能转译到 上游,不改变 Claude Code 是否延迟工具本身。
tool_search 在 [providers.<name>] 下是一个三态设置。未设置(默认,“auto”)时,只对已验证支持
tool_search 条目的宿主 —— ChatGPT/Codex 后端(内置 codex 提供方)和 api.openai.com(内置 openai
提供方)—— 解析为原生协议,而对其他所有 OpenAI 兼容端点(包括指向 LiteLLM、vLLM、OpenRouter 或自托管代理
的自定义 kind = "responses" 提供方)解析为文本 shim:大多数第三方 Responses 后端并未实现 tool_search
条目,若在那里自动启用原生协议,轮次本身会直接失败,而不是优雅降级。这些原生形状已针对 ChatGPT/Codex 后端
在 gpt-5.6 上做过实时探测验证(2026-07-13,
pleaseai/shunt#86),而且 tool_search 已被记录在公开的
OpenAI Responses API 文档中,适用于 gpt-5.4+ 模型。
要把已确认实现该协议的自定义端点加入原生路径,设置 tool_search = true —— 上述风格/模型要求仍然适用:
[providers.my-litellm]
kind = "responses"
base_url = "https://litellm.internal/v1"
tool_search = true若某个默认(或经过 opt-in)会走原生路径的提供方需要强制使用文本 shim,设置 tool_search = false:
[providers.codex]
tool_search = false故障排查
| 症状 | 原因 / 修复 |
|---|---|
ChatGPT auth not found; run codex login |
没有 ~/.codex/auth.json(或 $CODEX_AUTH_FILE 错误)。运行 codex login。 |
ChatGPT auth tokens missing |
auth 文件处于 ApiKey 模式 —— 那是 openai 提供方。用 ChatGPT 账户重新 codex login。 |
400 … not supported when using Codex with a ChatGPT account |
你用了 gpt-*-codex slug。使用一个已授权的非 -codex slug。 |
Model not found <slug> |
客户端版本门控或一个未授权的 slug —— 通过 models.json 确认。 |
gpt-* id 上力度滑块被忽略 |
设置 CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1,或是某个路由/提供方的 effort 覆盖项胜出。 |
| 上下文栏读数过高 / 过早压缩 | 设置 CLAUDE_CODE_MAX_CONTEXT_TOKENS;发现别名无法接收它 —— 请用一个非 claude- id。 |
| Grok 路由上网页搜索无结果 | xAI/Grok 的 Responses API 不支持网页搜索,shunt 会丢弃该工具。网页搜索请使用 codex 或 openai 路由。 |
| 工具搜索无效 / 每轮都发送全部工具 schema | 设置 ENABLE_TOOL_SEARCH=true —— Claude Code 在非第一方 base URL 背后默认禁用工具搜索。shunt 会转发 tool_reference 块并按需揭示延迟的 schema。 |
| 工具搜索不收回上下文(仍在为 shim 的缓存失效代价买单) | 检查风格/模型门控 —— 原生 tool_search 需要标准 OpenAI/ChatGPT-Codex 风格和 gpt-5.4+ 模型;不受支持的组合会静默回退到 shim。若两项门控都满足,但你用的是自定义 OpenAI 兼容端点(LiteLLM、vLLM、OpenRouter、自托管),它不会自动启用 —— 确认该端点实现了 tool_search 条目后设置 tool_search = true。若是已知宿主(codex/openai),确认你没有把 tool_search 设为 false;见上文 工具搜索 → 原生协议。 |
更多内容见完整的 故障排查 参考。