Skip to content

ChatGPT / Codex

通过复用 ~/.codex/auth.json 将 Claude Code 推理路由到你的 ChatGPT/Codex 订阅 —— 认证、模型 slug、力度和上下文窗口。

Updated View as Markdown

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 会成为 Responses web_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 系列)。精确 slug gpt-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;见上文 工具搜索 → 原生协议。

更多内容见完整的 故障排查 参考。

Navigation

Type to search…

↑↓ navigate↵ selectEsc close