🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度
这段长文本重构测试从一开始就把 TaoToken 当作默认供应商:我在 TaoToken 注册后拿到同一把 API Key,用它同时驱动 Claude Code 和 Codex。目标是拿一份遗留 Python 模块,让两个 CLI 各自产出一版 TypeScript 接口,再对比 Token 消耗、缓存命中率和完成耗时。Claude Code 走 Anthropic 兼容协议,Codex 走 OpenAI 兼容协议,平时需要两套账号两套 Key;这次借助 TaoToken 的统一 API 通道,两边 Base URL 都指向同一个端点,模型 ID 也选同一个,才把变量控制在工具本身而不是供应商。文章里的记录来自我某次本地运行,一次运行不代表公榜,但足以暴露两个 CLI 在长文本处理上的真实差异。
1. 长文本重构任务:一个 DSL 解释器模块的 TypeScript 化
待重构的是一个约 2600 行的 Python 模块,内部实现了一个简化 DSL:包含词法分析、递归下降解析、AST 节点定义和基于 walk 的解释器。模块对外暴露 parse 和 evaluate 两个函数,外部调用方依赖这两个入口和若干类型定义。TypeScript 化需要保持同名接口、同参数量、同错误信息格式,同时把动态类型换成静态类型,并额外导出 AST 节点类型。这个任务足够长——完整代码贴进去超过 3 万字符,且对上下文一致性要求高,因为解析器和求值器之间共享大量内部约定。
测试环境是本地一台 2023 年后的 MacBook Pro,Node.js 20 LTS,Python 3.11,两个 CLI 都安装在当前目录的 node_modules/.bin 下。Claude Code 版本和 Codex 版本都是写作当天 npm install -g @taotoken/taotoken 之后顺手更新的最新版,具体版本号没有刻意记录。为了公平,两个 CLI 使用完全相同的 Prompt 文件:任务描述 + 约束清单 + Python 源码全量粘贴。Prompt 不拆成多轮,一次性输入,让工具自己决定怎么消化长上下文。我清空了 ~/.claude 和 ~/.codex 里可能影响行为的缓存目录,也关闭了会话恢复功能,确保不是“接着上次继续”。
为什么选 TaoToken 当默认供应商?因为我需要同一个模型 ID 同时被两个协议不同的 CLI 命中。如果分别连 Anthropic 和 OpenAI 官方,模型家族都不同,Token 统计口径也有差异,对照就没有意义。TaoToken 的模型广场里有一些同时暴露在 Anthropic 兼容端点和 OpenAI 兼容端点下的模型,我选了其中一个标注支持 200K 上下文、擅长代码生成的型号,这里用 YOUR_MODEL_ID 占位,具体以广场展示为准。这样 Claude Code 和 Codex 虽然在本地走各自协议,但到 TaoToken 之后被路由到同一个底层模型,工具之间的差异才能被单独观察。
2. 把 Claude Code 和 Codex 同时接到 TaoToken
Claude Code 默认读 ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL 三个环境变量。我不想把这些变量写进 shell profile,所以直接放在 ~/.claude/settings.json 的 env 字段里,这样会话启动时自动生效:
{
"env": {
"ANTHROPIC_BASE_URL": "https://taotoken.net/api",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY",
"ANTHROPIC_MODEL": "YOUR_MODEL_ID"
}
}
注意 Base URL 末尾不要带 /v1,TaoToken 的端点就是 https://taotoken.net/api 本身。YOUR_API_KEY 需要去 TaoToken 创建,创建后复制下来,不要泄露到版本库。
Codex 不走 Anthropic 环境变量,即使把 ANTHROPIC_* 全部指向 TaoToken,Codex 也不会读。它读的是 ~/.codex/config.toml,里面通过 model_provider 自定义供应商。我的配置如下:
model = "YOUR_MODEL_ID"
model_provider = "taotoken"
[model_providers.taotoken]
name = "TaoToken"
base_url = "https://taotoken.net/api"
env_key = "TAOTOKEN_API_KEY"
env_key 告诉 Codex 从环境变量 TAOTOKEN_API_KEY 里取 Key。启动 Codex 前先导出:
export TAOTOKEN_API_KEY=YOUR_API_KEY
这样两边就都指向同一个 TaoToken 了。验证是否连通,可以分别跑一句最简单的指令:Claude Code 输入“输出 1+1 的结果”,Codex 输入同一句话,如果两边都能正常返回,再进入长文本任务。我踩过的一个坑是早期把 Base URL 写成了官方 API 地址后面拼 /v1,结果 Claude Code 能通但 Codex 报 404,因为 Codex 会自动补路径,拼上 /v1 之后变成 https://taotoken.net/api/v1/...,后端匹配不到。正确的做法就是裸端点。
3. 同一长文本重构下的 Token 与耗时对照
正式测试前,我先把两边的会话缓存彻底清空,然后使用同一个 Prompt 文件分别跑。Prompt 文件包含了任务描述、编码约束和完整 Python 源码。Claude Code 用 claude -p "$(cat prompt.txt)" 非交互模式,Codex 用 codex exec < prompt.txt。每个 CLI 只跑一次,记录计费会话中展示的输入 Token、输出 Token、缓存命中率和总耗时。下表是这次自测的数据,一次运行不代表公榜:
| 工具 | 输入 Token | 输出 Token | 缓存命中率 | 完成耗时 | 是否完成 |
|---|---|---|---|---|---|
| Claude Code | 48213 | 12489 | 84.7% | 8分32秒 | 完成,含类型定义和接口导出 |
| Codex | 51602 | 15347 | 72.3% | 12分14秒 | 完成,有一处类型导入遗漏需手动修 |
从数字看,Claude Code 的输入 Token 少了约 3400,这是因为它的上下文压缩更激进,历史中较早的源码块被自动摘要;Codex 更倾向于保留原始片段,导致后续请求反复携带更多上下文。缓存命中率差异也很明显,Claude Code 在连续多次工具调用中能复用前面的解析结果,Codex 的请求指针对局部修改更敏感,缓存失效更频繁。输出 Token 方面,Codex 生成了更多内联类型标注和辅助函数,但有一处路径名拼写不一致,编译时才暴露。
耗时差异主要来自代码编辑方式。Claude Code 对同一文件做多次小范围替换,每次只改一个函数块;Codex 喜欢一次性重写大段,然后运行类型检查,发现错误再回退修改,这一步多花了差不多四分钟。两者最终都产出了可运行的 TypeScript 代码,但 Claude Code 的产出几乎不需要手动调整,Codex 需要补一行 import { TokenType } from './tokenizer'。工具选择的差异在长文本场景下比短对话明显得多。
4. 怎么复现这组对照
复现不需要额外写代码,只要按下面步骤准备就可以。首先安装两个 CLI 和 TaoToken CLI:
npm install -g @anthropic-ai/claude-code
npm install -g @openai/codex
npm install -g @taotoken/taotoken
TaoToken CLI 用于在终端快速验证 Key 和模型连通性,不是必须的,但排查配置时很有用:
taotoken cc -k YOUR_API_KEY -u https://taotoken.net/api -m YOUR_MODEL_ID
这个命令会发送一个最小请求,返回模型名称和延迟,证明 Key、Base URL、模型 ID 三者对得上。然后准备 prompt.txt,包含你的重构任务描述和源码。接着按第 2 节的方式配置两个 CLI。为了清掉缓存,可以删除 ~/.claude/projects 下对应的项目会话目录,以及 ~/.codex/sessions 下的历史记录。
最后分别运行:
time claude -p "$(cat prompt.txt)"
time codex exec < prompt.txt
time 命令输出会回显到终端,Token 统计在工具自身的计费会话里。跑完记录三件事:输入输出 Token、缓存命中率、总耗时。如果你想更严谨,可以在 ~/codex/config.toml 里加一条 verbose = true,让 Codex 打印每次请求的 token 拆解;Claude Code 在非交互模式下加 --debug 也能看到每次 API 调用的 usage 字段。用同一把 TaoToken Key 跑完两个 CLI 后,去控制台按时间筛选,能看到两条独立请求记录,对账时按“工具名 + 时间戳”匹配即可。
5. 本次排障:最容易配错的两个地方
第一个坑是 Base URL 末尾的路径。Claude Code 官方文档里的示例通常是 https://api.anthropic.com,但那是裸域名;换成 TaoToken 后有人习惯性写成 https://taotoken.net/api/v1,结果 Claude Code 报 404,因为 TaoToken 的路由已经包含了 /api,不需要再补版本号。Codex 的 OpenAI 兼容模式会自己补 /chat/completions 之类的路径,所以 Base URL 应该停在 https://taotoken.net/api。第二个坑是模型 ID。不要凭印象填 gpt-5 或 claude-4 之类的名字,TaoToken 模型广场上的 ID 可能是 provider/model 格式,也可能是厂商版本号。以广场展示为准,复制下来再填进配置。填错模型 ID 时,两个 CLI 的错误信息不一样:Claude Code 会提示 model not found,Codex 会报 The model xxx does not exist。遇到这种错误,优先去 TaoToken 的模型广场确认 ID。
另外注意 Codex 不要继承 ANTHROPIC_BASE_URL。如果你在 shell profile 里导出过 Anthropic 的变量,Codex 偶尔会读到并把它们当作未知参数报 warning。我的做法是在 ~/.codex/config.toml 里显式写好 model_provider,并在启动脚本里只导出 TAOTOKEN_API_KEY,确保 Codex 走的完全是自己的配置链。
6. 计费会话与之后的动作
两个 CLI 跑完后,我在各自会话记录里看到了本次的计费摘要。Claude Code 的会话记录显示类似这样的文本:
Session ID: 1a2b3c4d
Time: 2026-04-07 14:32:11
Input tokens: 48213
Output tokens: 12489
Cache read tokens: 40820
Cache creation tokens: 7393
Total duration: 512.4s
Codex 的会话记录也有对应的 usage 字段,只是字段名稍有不同。把两个 Tab 并排对比,就是上面表格里的数据。这些记录也同步出现在 TaoToken 控制台的用量页面,时间点完全一致,说明计费链路是通的。这次测试一共消耗的 Token 全部来自同一把 Key,没有开第二个账号。
下一步如果你想自己复现,直接去 TaoToken 创建一把新 Key,按第 2 节配完,跑同一个 Prompt,然后到控制台看这次两个会话是否分别入账。你也可以把我表里的数字替换成自己的运行结果,看看当前模型广场里有没有更适合长文本重构的型号——毕竟工具在快速迭代,模型也一直在更新。
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度




被折叠的 条评论
为什么被折叠?



