🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度
1. 任务与环境:一个 42 文件 Swift 仓库的 async/await 重构
同一台 Mac 上,Claude Code 和 Codex 都能读仓库、改文件、跑测试,但真拿一个 Swift 仓库做 async/await 重构时,Token 账单和完成时间差得并不小。为了把变量压到最少,我这次不换供应商,先去 TaoToken 拿一把 Key,再把 https://taotoken.net/api 分别填进两个工具的 Base URL,跑同一个仓库、同一套 Prompt,记录完成时间、请求次数和 Token 总量。
这次选的仓库是我维护的一个 iOS 网络层,代码量不算大,但调用点分散,适合观察工具如何读上下文、如何分批改文件。仓库里有 42 个 Swift 文件,8 个测试文件,大约 6800 行。网络请求、缓存、重试、错误映射都写在里面,现有实现大量使用 completion handler。重构目标很明确:把 NetworkClient 的完成回调改成 async throws,更新调用点和测试,保持对外行为不变,不引入新依赖,不顺手改业务逻辑。
任务开始前,我把仓库 clone 到本地临时目录,基于同一个 commit 建了 refactor/async-await 分支。两个工具各跑一轮,跑完就重置回基线 commit,再换另一个工具。这样仓库状态、Prompt、模型 ID、Key、Base URL 都一致,只有 Claude Code 和 Codex 本身在变。AI 工具只生成或解释命令,真正的 git、swift test、文件修改都由我在本地执行,结果再贴回对话。生产仓库和线上机器没有接入,也不适合接入。
记录指标分成四项:完成时间、请求次数、输出 Token、总 Token。完成时间从第二轮 Prompt 发出开始算,到测试通过或人工确认失败为止。请求次数按工具实际发起的模型调用轮次统计,连续工具调用算多次。Token 用量从两边会话的用量信息里抄下来,输入和输出分开记。测试结果只记 swift test 是否通过,不把通过率、覆盖率、公榜分数混进来。
这里先说明数字口径:本文不含 SWE-bench、Arena、LiveCodeBench 等排行分数,也没有引用公榜快照。下面出现的耗时和 Token 都只是我本地一次运行的结果,换机器、换仓库、换模型 ID、换 Prompt 写法都会变,不代表任何官方基准。
环境如下:MacBook Pro M2 Pro,32GB 内存,macOS 本地终端,Swift 工具链按仓库自带版本跑。两个工具都通过本地命令行启动,网络出口不做额外代理,只把 Base URL 指向统一网关。模型 ID 从模型广场复制,不凭记忆写。为了减少缓存差异,两个工具都从空会话开始,历史记录清掉,仓库副本重新 clone。
1.1 为什么选 async/await 重构做对照
completion handler 改 async/await 是一个典型的仓库级小任务。它不像“生成一个登录页”那样单文件就能完成,也不像大型迁移那样跑几天。它需要工具做四件事:先读仓库结构,再定位回调入口,然后批量修改调用点,最后跑测试确认。每一步都会烧上下文,也能看出工具是倾向一次性读很多文件,还是反复小步请求。
Swift 的并发检查还会让工具面对一些编译器错误:@escaping 闭包不能直接 await,actor 隔离可能报错,测试里的期望需要改成 async 测试。这些问题不会在第一次回答里全部暴露,工具需要根据我贴回的测试输出继续调整。请求次数和 Token 总量因此比单轮问答更有参考价值。
我不想把任务设得太脏。仓库里没有混编 Objective-C,没有复杂宏,也没有脚本生成代码。这样对照出来的差异更容易归因到工具策略,而不是语言边界。另一个考虑是测试成本低,swift test 在本地几十秒能跑完,不会把等待测试的时间算成工具思考时间。
1.2 第一次跑之前先定基线
两个工具开跑前,我先在本地跑了一次 swift test,确认基线是绿的。然后记下当前 commit,方便后面重置。命令如下:
git clone <your-swift-repo> swift-async-refactor
cd swift-async-refactor
git checkout -b refactor/async-await
swift test
基线测试通过后,我把仓库路径分别交给 Claude Code 和 Codex。这里不把仓库路径写进任何公开配置,也不让工具自动提交或推送。每轮结束后,我只保留 diff 和测试输出,不保留工具自己生成的中间脚本。这样做是为了下一次复现时能回到干净状态。
2. 同一把 TaoToken Key 分别接 Claude Code 与 Codex
拿 Key 的入口在官网,注册后进控制台创建 API Key。模型广场里能看到当前可用的模型 ID,复制哪个就填哪个,不要靠猜。接口 Base URL 固定写 https://taotoken.net/api,末尾不要加 /v1。这一步两个工具共用同一套 Key 和 Base URL,TaoToken 在这里只做统一供应商,不参与被评测。
Claude Code 的配置有两种写法。临时用环境变量最直接:
export ANTHROPIC_BASE_URL="https://taotoken.net/api"
export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY"
export ANTHROPIC_MODEL="YOUR_MODEL_ID"
如果想让每次启动都生效,可以写 ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "https://taotoken.net/api",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY",
"ANTHROPIC_MODEL": "YOUR_MODEL_ID"
}
}
这里的 YOUR_MODEL_ID 以模型广场为准,不要从旧文章里抄一个已经下线的 ID。配置完成后,先在仓库目录外启动一次 Claude Code,发一句简单对话,确认通道能通,再进仓库跑重构任务。这样能把“Key 或 Base URL 错”与“仓库任务失败”分开。
Codex 的配置不要套 Claude Code 的环境变量。它读的是 ~/.codex/config.toml,自定义供应商要单独写 provider。一个可用结构如下:
model = "YOUR_MODEL_ID"
model_provider = "taotoken"
[model_providers.taotoken]
name = "TaoToken"
base_url = "https://taotoken.net/api"
env_key = "TAOTOKEN_API_KEY"
wire_api = "chat"
然后在当前 shell 里设置:
export TAOTOKEN_API_KEY="YOUR_API_KEY"
codex
注意 Codex 的 base_url 同样不带 UTM,也不带 /v1。这里的 wire_api 以 Codex 当前文档和实际连通结果为准,如果启动时报协议不匹配,先换回官方默认 provider 确认 Codex 本身正常,再改回自定义 provider。不要把 ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN 写进 Codex 配置,两个工具的变量名不同。
如果同时装了 CC Switch,可以把它当成切换器:新增自定义供应商,填 Base URL、Key、模型 ID,保存后切到该供应商,再启动对应工具。CC Switch 本身不改变工具行为,只是省去手改配置文件。切换后最好重启终端或至少重开工具进程,避免旧环境变量残留。排查时先看 echo $ANTHROPIC_BASE_URL 和 cat ~/.codex/config.toml,确认两边没有互相污染。
命令行方式也可以作为备选。项目提供了 CLI,安装后可以把 Claude Code 的接入参数一次带进去:
npm install -g @taotoken/taotoken
taotoken cc -k YOUR_API_KEY -u https://taotoken.net/api -m YOUR_MODEL_ID
这条命令里的 -u 同样只写 https://taotoken.net/api,不要加 UTM,也不要加 /v1。Codex 不走这条 CLI,仍然读 ~/.codex/config.toml。两种入口都指向同一个统一网关,Key 也共用同一把。
配置完成后,我会在轻量对话里确认三件事:模型能返回文本、返回的模型标识与广场一致、控制台能看到这次调用。确认完再开始仓库任务,避免把配置错误算进重构耗时。
3. 两轮 Prompt 与命令:先出计划,再改本地分支
这次没有让工具一上来就改文件,而是拆成两轮。第一轮只做只读分析,第二轮才允许改本地工作区。这样做有两个好处:一是能看清工具在计划阶段读了多少文件,二是如果第一轮就理解错仓库结构,可以立刻停掉,不用等到改完再回滚。
3.1 第一轮 Prompt:只读计划
第一轮 Prompt 原文如下,两个工具使用同一份:
你正在一个 Swift 仓库中工作。先不要改文件。
请扫描 Sources 和 Tests,找出所有基于 completion handler 的网络调用,
给出 async/await 重构计划,列出要改的文件、风险点和验证命令。
所有命令只输出,不要替我执行。不要碰生产配置,不要提交,不要推送。
Claude Code 和 Codex 都会读仓库,但读法不同。Claude Code 倾向先把目录树和关键文件一起拉进上下文,再给出一个分阶段计划;Codex 更常先列少量文件,然后按调用链逐步展开。这里不评价谁更聪明,只看 Token 和请求次数怎么变。第一轮结束后,我把计划复制到本地笔记,不直接让它进入第二轮。
第一轮还要求工具输出验证命令。比如:
swift build
swift test
rg "completion" Sources
rg "URLSession" Sources
这些命令由我本地执行,输出再贴回对话。工具不直接连生产库,也不执行发布、部署、数据库写入之类动作。如果工具在计划里写了自动提交或强推,我会删掉再进第二轮。
3.2 第二轮 Prompt:改本地分支并等测试结果
第二轮 Prompt 也保持同一份:
按你上一步的计划执行重构。只改本地工作区文件。
把 completion handler 改为 async throws,更新调用点和测试。
每完成一组文件就给出验证命令,由我本地执行。
不要提交,不要推送,不要改 CI 配置。
第二轮开始前,我会确认当前分支是 refactor/async-await,工作区干净。两个工具都从同一个基线 commit 开始,避免前一个工具留下的 diff 影响后一个。Claude Code 跑完后,我会先跑一次 swift test,把失败输出贴回去让它继续修;Codex 同理。只有测试通过,才把这一轮记为完成。
实际跑下来,Claude Code 在第一轮读了更多测试文件,计划里直接标出了 NetworkClientTests 里需要改的异步等待。Codex 第一轮更细碎,先确认 NetworkClient 的公开方法,再问是否需要保留旧回调。我回答“保留旧 API 作为过渡,但新增 async 版本”,然后它继续。两边最终都完成了重构,但过程差异直接反映在请求次数上。
3.3 本地执行和回贴结果
工具生成的命令不会自动执行。我本地跑完 swift test 后,把失败摘要贴回对话。例如:
Test Case '-[NetworkClientTests testFetchUser]' failed:
error: 'async' call in a function that does not support concurrency
工具看到这个错误后,继续生成下一批修改。这里有个安全边界:仓库如果是生产库,先切成只读副本或临时分支;数据库、服务器、CI 密钥不要进上下文。AI 只能生成或解释命令,执行动作由本地人完成。这个边界不影响本次 Token 对照,反而让两轮 Prompt 更接近真实开发流程。
4. 对照表:完成时间、请求次数与 Token 总量
下面是本地一次运行的结果。两个工具使用同一把 Key、同一个 Base URL、同一个模型 ID,仓库副本相同,Prompt 相同,测试命令相同。数字来自会话用量信息,记录时间以第二轮 Prompt 发出为起点。
| 工具 | 模型 ID | 完成时间 | 请求次数 | 输入 Token | 输出 Token | 总 Token | swift test |
|---|---|---|---|---|---|---|---|
| Claude Code | 广场复制的同一 ID | 18m42s | 47 | 1,284,000 | 92,400 | 1,376,400 | 通过 |
| Codex | 广场复制的同一 ID | 22m10s | 63 | 1,510,000 | 78,900 | 1,588,900 | 通过 |
这张表只代表一次本地运行,不代表公榜,也不代表两个工具的普遍水平。仓库大小、Prompt 写法、模型 ID、缓存策略、网络延迟都会影响结果。我把它列出来,是为了给同一台机器上的对照提供一个可复现起点,而不是给工具排名。
先看完成时间。Claude Code 快了不到四分钟。差距不算大,主要来自第一轮计划阶段:它一次读了更多文件,第二轮改调用点时少了几轮来回。Codex 在第二轮更谨慎,每改一个文件就要求跑一次 swift build,所以请求次数多了 16 次,时间也拉长。这里没有谁一定更好,只有这次任务下的策略差异。
再看 Token。输入 Token 都远大于输出 Token,原因是仓库文件、测试输出、错误日志反复进入上下文。Claude Code 输入 128 万左右,输出 9 万多;Codex 输入 151 万左右,输出 7 万多。Codex 输出更少,但输入更多,总 Token 反而高了约 21 万。请求次数多不直接等于 Token 多,关键看每次请求塞了多少上下文。
如果把这张表当成选型依据,至少要再跑两三个仓库,换一次 Prompt 粒度,换一次模型 ID。单次结果只能说明:在这次 Swift async/await 重构里,两个工具都能完成任务,Token 消耗都在百万级输入范围内,差异主要来自读上下文和工具调用轮次。成本换算请以 官网 展示为准,不要拿旧截图里的折扣价直接乘。
4.1 请求次数为什么差这么多
Claude Code 的 47 次请求里,第一轮计划大约占 9 次,第二轮修改和测试修复占 38 次。它会把多个相关文件放在同一次请求里,所以单次输入大,但轮次少。Codex 的 63 次请求里,第一轮计划占 14 次,第二轮每完成一组文件就请求一次验证,测试失败后又分文件回贴,轮次自然上去。
这个差异对 Token 的影响不是线性的。一次塞十个文件,输入 Token 会涨,但少了九次系统提示和对话历史重复计费。小步请求看起来每次很轻,累计起来反而可能更贵。实际账单要看输入、输出、缓存命中和模型价格,不能只数请求次数。
4.2 完成质量怎么记
两个工具都通过了 swift test,但我还人工看了 diff。检查点包括:旧 completion API 是否保留、错误类型是否被错误吞掉、@MainActor 更新是否还在主线程、测试是否只是把断言删掉。Claude Code 的 diff 更集中,NetworkClient.swift 一次改完,调用点分两批更新。Codex 的 diff 更碎,但每个小改动都有对应测试命令记录。
质量记录没有做成分数,因为这次只有一个仓库,打分很容易变成主观偏好。可复现的硬指标只有完成时间、请求次数、Token 总量和测试结果。软指标如 diff 可读性、是否保留旧 API、是否解释风险,建议读者自己在本地跑一遍再判断。
5. 复现与排障:Base URL、模型 ID、CC Switch 和 401/404
复现这张对照表不需要复杂环境。准备一台能跑 Swift 的机器,一个本地仓库副本,一把 Key,两个工具各配一次,然后按第 3 节两轮 Prompt 跑。关键是控制变量:同一个 commit、同一个分支、同一个模型 ID、同一套 Prompt、同一套测试命令。每跑完一个工具,重置回基线,再跑另一个。
5.1 复现步骤
第一步,打开 控制台 创建 Key,并到模型广场复制模型 ID。第二步,Claude Code 写 ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL;Codex 写 ~/.codex/config.toml,不要混用变量。第三步,本地 clone 仓库,建临时分支,跑基线 swift test。第四步,跑第一轮只读 Prompt,保存计划。第五步,跑第二轮修改 Prompt,本地执行测试并把结果贴回。第六步,记录完成时间、请求次数、输入输出 Token。
如果你用 CC Switch,新增自定义供应商时填 Base URL 和 Key,模型 ID 从广场复制。切换后重开终端,再启动对应工具。CC Switch 只是配置入口,不替你执行仓库命令,也不改变 Token 统计口径。
5.2 本篇配置错怎么排
401 通常表示 Key 没填对、Key 已删、或者环境变量没被工具读到。Claude Code 先看 echo $ANTHROPIC_AUTH_TOKEN,再看 ~/.claude/settings.json 是否被当前项目配置覆盖。Codex 看 TAOTOKEN_API_KEY 是否 export 成功,以及 config.toml 里的 env_key 是否同名。
404 常见原因是 Base URL 写成了 https://taotoken.net/api/v1,或者只写了域名没写 /api。正确写法是 https://taotoken.net/api,末尾不带 /v1,也不加 UTM。Claude Code 的 ANTHROPIC_BASE_URL 和 Codex 的 base_url 都按这个填。
模型不存在或模型无权限,一般是 ANTHROPIC_MODEL 或 model 填了广场里没有的 ID。回模型广场复制一次,不要手打。Codex 报 provider 不存在,检查 model_provider 和 [model_providers.taotoken] 是否对应。Claude Code 启动后仍走旧通道,检查 shell 里是否有旧的 ANTHROPIC_BASE_URL 残留,重启终端最省事。
5.3 不要接到生产库
这次任务只读本地副本,工具生成的命令由我执行。真实团队里,生产库、生产机、数据库、CI 密钥不要直接交给 AI 工具执行。可以让工具生成迁移脚本、SQL、测试命令,但执行动作留在本地或隔离环境。结果贴回对话,再让它解释和改下一步。这个边界不降低 Token 对照的价值,反而更接近可审计的开发流程。
6. 用同一把 Key 复现对照表
如果你想把第 4 节的表换成自己仓库的数字,先在 模型对话 确认模型广场里的 ID 与配置一致,再拿同一把 Key 跑 Claude Code 和 Codex。长期做这类仓库重构,可以看 Coding Plan;Key 在 控制台 创建;Claude Code 与 CC Switch 的三件套配置对照 接入文档。本次两轮 Prompt、Base URL 和 Token 记录表都可以直接复用,换掉仓库路径就能再跑一次。
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度




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



