在同一个开源仓库上用 4 个真实任务各跑两遍,实测质量持平(均通过),但 Codex 单任务成本 $0.074 vs Claude Code $0.181,相差 2.4 倍。
大多数"Codex vs Claude Code"比较都引用的是厂商的基准测试数据,或者一个被反复复制粘贴的第三方 token 数值。很少有人公布具体的任务内容、提示词或提交记录,因此这些数字无法被验证。我们做了这个枯燥的版本:在同一个固定的开源仓库上运行四个真实任务,每个 CLI 各跑两次,无头模式,以下是具体的命令、提示词和数据,并提供原始数据供下载。测试时间为 2026-10-06,Claude Code 2.1.291(claude-opus-5-5)和 Codex CLI 0.160.0(gpt-6.1-sol),使用默认模型和默认 effort 级别。
质量:平局。全部 16 次运行均通过了目标检查,四次评审均捕捉到了植入的 3 个 bug,且无误报。
成本:Codex 胜出。按 API 列表价格,每个通过任务 Claude Code 花费 $0.181,Codex 仅需 $0.074,便宜 2.4 倍,且在每一个任务上都更便宜。
速度:接近。Claude Code 在 bug 修复和功能添加上更快,重构持平,Codex 在代码评审上胜出,因为 Claude Code 选择对卡死的正则表达式进行压力测试。
价格来自 2026-10-06 的官方页面:claude.com/pricing、ChatGPT Plus 订阅(Codex 用)及 OpenAI API 定价。
复现基准测试所需的一切都在原始数据压缩包中(180 KB):四个提示词、隐藏的验收测试、运行和检查脚本、16 次运行中每次的完整 JSON 转录录以及计算后的指标。
仓库为 python-humanize/humanize(MIT):src/ 下 1,725 行 Python,约 860 个测试约 7 秒跑完,固定在 commit 785e5dcc0d0308ad0dff3f6cc0faa7085ad0375b。每次运行都会获取起始 commit 的全新 git worktree 和独立的 virtualenv,确保各运行之间互不干扰。
评审 commit 添加了一个 parse_size() 函数,即 naturalsize() 的逆函数,外加 12 个通过且规避了所有 bug 的测试。要重现它,请将以下内容追加到 src/humanize/filesize.py(顶部已有 import re),并从 humanize/init.py 导出:
_SIZE_PATTERN = re.compile(r"^\s*(-?(?:\d+)+(?:\.\d+)?)\s*([A-Za-z]*)\s*$")
def parse_size(value: str) -> int:
"""Parse a size written by `naturalsize` back into a number of bytes."""
match = _SIZE_PATTERN.match(value)
if match is None:
msg = f"invalid size: {value!r}"
raise ValueError(msg)
number, unit = float(match.group(1)), match.group(2)
if unit in ("", "B", "Byte", "Bytes"):
return int(number)
if unit in suffixes["decimal"]:
return int(number * 1000 ** (suffixes["decimal"].index(unit) + 1))
if unit in suffixes["binary"]:
return int(number * 1024 ** suffixes["binary"].index(unit))
msg = f"unknown unit: {unit!r}"
raise ValueError(msg)
三个植入的 bug:
逻辑:二进制分支漏了 + 1,所以 parse_size("1.0 KiB") 返回 1。
边界情况:int() 会截断浮点乘积,所以 parse_size("8.2 MB") 返回 8199999。
安全:嵌套量词 (?:\d+)+ 会指数级回溯。parse_size("1" * 24 + "!") 在我们机器上耗时 2.6 秒,每多加一位数字时间翻倍:对不可信输入构成拒绝服务攻击。
git clone https://github.com/python-humanize/humanize && cd humanize
git worktree add --detach ../run-1 785e5dcc0d0308ad0dff3f6cc0faa7085ad0375b
cd ../run-1
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e '.[tests]' pytest
两条命令,提示词文本相同,默认模型和 effort,无需授权:
# Claude Code 2.1.291
env -i HOME="$HOME" PATH="$PATH" IS_SANDBOX=1 \
claude -p "$PROMPT" --output-format stream-json --verbose \
--dangerously-skip-permissions \
--setting-sources project,local --strict-mcp-config --no-session-persistence < /dev/null
# Codex CLI 0.160.0
env -i HOME="$HOME" PATH="$PATH" \
codex exec --json --dangerously-bypass-approvals-and-sandbox \
--ignore-user-config --skip-git-repo-check -C "$WORKTREE" "$PROMPT" < /dev/null
几个参数值得一说:
env -i、--setting-sources project,local、--strict-mcp-config 和 --ignore-user-config 将我们的个人设置、插件、MCP 服务器和模型覆盖排除在运行之外,确保两个 CLI 都使用默认配置。
stream-json 输出完整转录;其最后一个事件与 --output-format json 的结果对象相同(usage、total_cost_usd、duration_ms、turns)。
我们的 VM 以 root 身份运行,而 Claude Code 在 root 身份下除非 IS_SANDBOX=1 声明机器是可处置的,否则会拒绝 --dangerously-skip-permissions。该拒绝是一个合理的默认行为。
这些都是工作流运行器在无人值守步骤中输入的相同无头调用(claude -p、codex exec、关闭授权提示),因此这些数字描述的是 CI 和定时任务场景,而非交互式聊天。
每个提示词末尾都加了这行相同的话:"项目 virtualenv 已在 .venv 中准备就绪:运行测试用 .venv/bin/python -m pytest -q。仅在此仓库内工作。不要 commit。" 四个完整提示词如下:
[Bug fix]
Fix this bug, reported against this repository (humanize):
`intword()` decides whether rounding pushed a value up into the next magnitude with:
if not largest_ordinal and rounded_value * power == powers[ordinal + 1]:
For values above ~10**22, `rounded_value * power` is evaluated in floating point and no longer
equals the exact `powers[ordinal + 1]`, so the carry is skipped and the number is rendered against
the lower magnitude:
>>> import humanize
>>> humanize.intword(10**24 - 1)
'1000.0 sextillion' # expected '1.0 septillion'
>>> humanize.intword(10**27 - 1)
'1000.0 septillion' # expected '1.0 octillion'
The same happens at 10**30 and 10**33.
Add a regression test.
[Feature]
Add two keyword-only parameters to `humanize.natural_list` (src/humanize/lists.py):
- `conjunction: str = "and"`: the word placed before the last item.
`natural_list(["a", "b", "c"], conjunction="or")` returns `"a, b or c"`.
- `max_items: int | None = None`: when set and the iterable has more than `max_items` items, keep
the first `max_items` items and replace the rest with "N more", joined with the conjunction.
`natural_list(["a", "b", "c", "d"], max_items=2)` returns `"a, b and 2 more"`;
`natural_list(["a", "b", "c", "d"], max_items=1)` returns `"a and 3 more"`. When the iterable has
`max_items` items or fewer, the output is the same as without the parameter.
- `max_items` lower than 1 raises `ValueError`.
- The default behavior must not change. Update the docstring (with examples) and add tests.
[Refactor]
Refactor, with no behavior change: move `scientific()` and `metric()` out of
src/humanize/number.py into a new module src/humanize/notation.py, together with the helpers and
constants only they use.
- `humanize.scientific`, `humanize.metric`, `humanize.number.scientific` and
`humanize.number.metric` must keep working.
- Helpers still needed by number.py must not be duplicated.
- The new module must appear in the API documentation (docs/ and mkdocs.yml) like the other modules.
- Do not modify the existing tests; the whole test suite must pass.
[Code review]
You are reviewing a pull request. The change under review is the last commit of this repository
(see `git show HEAD`).
Review it for correctness, edge cases, security and performance. Report each problem as a numbered
list: file and line, severity (high, medium or low), what is wrong, and a concrete input that
demonstrates it. Only list real problems. Do not modify any file.
评审提示词末尾没有测试行,因为评审者不应该改动任何文件。
通过与否按上述检查标准判定,由脚本在每次运行后执行,不由 agent 自身判断。
从启动到退出的墙上时间。16 次运行分两波进行,每波 8 个并行任务运行在 4 vCPU 的 VM 上,这可能为两侧的测试密集型运行增加几秒。
Token 数量取自各 CLI 报告:Claude Code 的结果事件(未缓存输入、缓存写入、缓存读取、输出)和 Codex 的 turn.completed 事件(输入、缓存输入、输出;推理 token 计入输出,每次运行 16 到 225 个)。
变更行数,来自在隐藏测试复制进去之前的 git diff --shortstat。
API 等效成本,按 2026-10-06 的官方列表价格计算。Claude Opus 5.5:每百万输入 token $4,缓存读取 $0.20,输出 $20,缓存写入按 5 分钟有效期 $5 或按 1 小时有效期 $8(为输入价格的 2 倍)。Claude Code 在每次运行中都以 1 小时有效期写入缓存,我们的数值与 CLI 自身的 total_cost_usd 精确到分一致。GPT-6.1 Sol:每百万输入 token $2,缓存输入 $0.10,输出 $10(缓存写入按 $2.50 计费,但 Codex 报告无缓存写入)。
"API 等效"很重要。使用 API 密钥你支付的就是这些金额。而订阅 Claude Pro 或 ChatGPT Plus 则是固定费用,同样的 token 消耗从你的用量限额中扣除。
这个任务藏了一个陷阱:helper _format_not_finite 被两个模块共用,所以简单移动会产生循环导入。四次运行找到了三种不同的解法:
Claude Code(两次运行):notation.py 从 number.py 导入这个 helper,而 number.py 通过模块级 __getattr__ 重新导出 metric 和 scientific。这能工作,但重新导出的名字对自动补全不可见,静态检查器也无法类型推断。
Codex,第一次运行:number.py 在文件顶部从 notation.py 导入,而 notation.py 在函数体内导入这个 helper。
Codex,第二次运行:把 helper 移到一个新的私有模块 _number.py,由两者共同导入。四种方案中结构最干净的,代价是多了一个没人要求过的文件。
四次运行全部通过了所有检查。Claude Code 这次多付了 2.9 倍费用,主要是因为输出量多一倍,每次运行还写入了 20k tokens 的缓存。
我们本以为这是某个智能体能拉开差距的地方。结果并非如此:每次审查都找到了 ReDoS、缺失的 + 1 和浮点截断,每个都附有复现输入,没有一个误报。
差异在于风格。Codex 正好返回了三个发现,每个都用短超时探测。Claude Code 则通过运行代码验证每一个结论,统计了影响范围(99,999 个从 0.01 kB 到 999.99 kB 的值中有 590 个结果错误),还补充了我们未植入的有效问题:naturalsize() 产生的 GNU 风格后缀如 2.9K,而 parse_size() 无法解析;超长输入会抛 OverflowError,但文档字符串承诺的是 ValueError;以及无法被重新解析的本地化输出。在第二次运行中,它还启动了一个后台 ReDoS 探测(30,000 位数字),等待后将其终止,这就是那次运行耗时 160 秒的原因。它还两次都将二进制 bug 定级为"高",而 Codex 一次说"高",一次说"中"。
我们的每日 pull request 审查模板每天早晨都会运行这类审查;以上数据表明,Codex 步骤在植入 bug 这部分的价格只有三分之一。
钱花在哪里才是有意思的:
Claude Code:56% 的成本是缓存写入($0.80),32% 是输出($0.46),12% 是缓存读取。它几乎不发送未缓存的内容(8 次运行共 90 tokens),但每次运行写入 8k 到 22k tokens 到 1 小时缓存中,按每百万 $8 计费。对于一次性无头运行,该缓存很少能回本。
Codex:65% 的成本是未缓存输入($0.38),19% 是输出,17% 是缓存输入。它读取更多、调用更多工具,但这些 token 每一个都更便宜,而且输出量只有一半。
截至 2026-10-06 的官方计划:
来源:claude.com/pricing、Claude Code with Pro or Max、Codex pricing。
哪个更便宜?按任务计,Codex 比 Claude Code 便宜 1.8 倍到 3.3 倍(我们四个任务的结果)。按 API 价格推算,100 个类似任务在 Claude Code 约花费 $18,Codex 约 $7.40。一个无人值守的作业每周工作日运行 20 个这样的任务(约每月 440 个)花费约 $80 对 $33。对于定时任务(如每周依赖更新或夜间分类)来说,这是预算决策的关键。
哪个先达到限额?在 $20 计划下哪个先触达?我们的数据无法回答:16 次运行中没有一次触达限额,两家厂商也没有将限额换算成 token 数。我们能说的是,Claude Code 每个任务消耗的 API 等效价值大约是两倍。如果两家厂商都将 $20 计划对应到相近的美元计算价值(未公开),Claude Code 会更早达到限额。
需要对对设计本身获得第二意见而不只是找 bug 的审查。它每次审查多发现 2 到 3 个有效问题,且每个都通过运行验证。
人类在旁边等待的简短、明确的任务。在 bug 修复和功能任务上,它的中位数快了 7 到 18 秒,原因是将读取和测试运行批处理到更少的工具调用中。
已订阅 Claude Max 的团队,因为按 token 计费不适用,唯一的成本就是限额。
任何无人值守、按 token 计费的任务:CI、定时任务、批量审查。同样的通过率,整体便宜 2.4 倍。
专注的审查——只想要 bug 不要别的:三个发现,无误报,费用不到 $0.05。
重构,谨慎使用:它的两次运行产生了最常规的模块结构,但 n=2 不是趋势。
从这个证据看,没有。在四个日常任务上,两个领先的 CLI 产生了相同质量的代码,有时甚至逐行相同。区分它们的是价格和详细程度,两者都随每次模型更新而变动。诚实的答案是:在你自己的代码库上、用你自己的任务、在每次模型变动时去测量。
"大多数人两个都用"出现在每篇对比文章中,通常后面跟着一段你从一个终端粘贴到另一个终端的交接日志。更清晰的分工依据结果:把每种任务类型路由到实测表现更好的智能体,让工作流来处理交接。
在 SideHub 中,工作流是由你本地机器上的智能体运行的一系列步骤,每个步骤可以设置自己的 CLI 提供者(claude、codex、gemini 或 copilot)。以下是一个用 Claude Code 实现、Codex 审查的草图:
format: sidehub.workflow/v1
name: Implement, then cross-review
defaultProvider: claude
parameters:
- { name: issue, label: Issue number, type: string, required: true }
steps:
- name: Implement the issue
prompt: |
Read GitHub issue #{{inputs.issue}} with `gh issue view`, implement it on a new branch
and run the test suite. Do not push.
- name: Review the diff
provider: codex
inputsFrom: ["1"]
prompt: |
Review the uncommitted diff of this repository for correctness, edge cases, security and
performance. List each problem with file, line, severity and a reproducing input.
每个步骤作为独立的运行执行,有自己的 CLI、耗时、退出码以及从 CLI 转录本读取的 token 用量,你可以在任何地方跟随它,包括手机。这意味着你可以用自己的代码库重新运行这个对比,看到每个步骤的成本,而不是信任一篇博客文章——包括这篇。模板库中有现成的工作流可以起步,比如夜间 issue 分类,这是一个每次运行成本累加起来更便宜的那个智能体大放异彩的典型定时任务。
样本量小。每 CLI 每任务两次运行。耗时 160 秒的那次审查运行表明,单次运行可以让中位数移动很多。
单一代码库、单一语言、小任务。一个测试快速的整洁 Python 库,任务耗时 30 秒到 3 分钟不等。在大型代码库中长时间、模糊的任务可能会让两个智能体拉开更大差距。
可能存在污染。bug 修复来自 2026-09-16 提交的一个公开 pull request。一次 Codex 运行逐字逐句复现了上游修复,可能是能力也可能是记忆。
我们植入的 bug。我们编写了审查 diff,所以它的 bug 可能比真实 bug 更容易被发现。
仅默认设置。默认模型和 effort,无项目指令文件。更高的 effort 设置、其他模型或经过调优的 CLAUDE.md / AGENTS.md 会改变数据。
并行运行。4 个 vCPU 上同时运行 8 个任务会让两侧的墙上时间增加几秒。
价格已过时。API 价格和计划限额为 2026-10-06 的数据,Claude Code 选择 1 小时缓存是其主要成本来源。任一方的变动都会改变比率。
在四个日常任务上,Codex(gpt-6.1-sol)和 Claude Code(claude-opus-5-5)表现同样出色:16 次运行全部通过,所有植入的 bug 都被发现,无误报。Codex 按 API 价格每个任务便宜 1.8 倍到 3.3 倍;Claude Code 在小型编程任务上略快,写的审查也更详尽。在每次运行成本会累加的地方用 Codex,在你需要深度或快速答案的地方用 Claude Code,并在你自己的代码库上重新运行这四个任务:命令和提示词都在上面。
在我们的基准测试中,两个 CLI 都分别两次通过了全部四项任务(Bug 修复、功能开发、重构、代码审查),并在每次审查中都捕获了全部三个植入的 Bug。Codex 在 API 价格上便宜了 1.8 到 3.3 倍;Claude Code 给出了更长的审查报告,并包含了额外有效的发现。
在我们测量的每一项任务上,都是 Codex 更便宜。按 2026-10-06 的官方 API 列表价格,Codex(gpt-6.1-sol)每次通过任务的平均成本为 $0.074,而 Claude Code(claude-opus-5-5)为 $0.181。在 $20 套餐下则采用固定费用,差异体现在用量限制的消耗上。
这取决于 token 的类型。Claude Code 读取的输入 token 更少(八次运行中为 993k 对比 1.18M),因为其输入几乎全部来自 prompt 缓存,但它生成的输出 token 多出一倍(23.2k 对比 11.1k)。Claude Code 的输出和缓存写入定价也更高,这正是成本差距的来源。
从我们的数据无法回答这个问题:16 次运行中没有一次触及限制。OpenAI 估算在 Plus 上的 GPT-6.1 Sol 每 5 小时可发送 15 到 160 条本地 Codex 消息。Anthropic 未公布 Pro 的消息数量,只披露了一个滚动 5 小时窗口,以及 Claude 和 Claude Code 之间共享的周限制和限额。
两者非常接近。Claude Code 在 Bug 修复(中位数 35 秒对 42 秒)和功能开发(36 秒对 54 秒)上更快,重构持平(各 59 秒),而 Codex 在审查上胜出(39 秒对 96 秒),因为有一次 Claude Code 运行花了 2 分钟对某个挂起的正则表达式进行压力测试。
两者都找到了所有植入的 Bug,且没有误报。Codex 以三分之一的成本精确返回了三个 Bug;Claude Code 通过运行代码验证了每个发现,并添加了有效的设计建议(GNU 后缀、溢出、本地化输出)。在实现方面,两者的代码几乎相同且都通过了测试,所以选择取决于价格和速度。
可以,而且有效的分工是按任务类型而非按心情。在 AGENTS.md 中维护共享规则,让两者读取相同的约定,然后根据各自的优势分配任务步骤,例如一个负责实现,另一个负责审查。配置工作流运行器来按步骤选择 CLI,可以省去在终端间复制粘贴的麻烦。
可以:claude -p 和 codex exec 都能在没有 TTY 的情况下完整运行提示词,并输出机器可读的格式(stream-json 和 JSONL)。无人值守运行需要禁用权限提示,Claude Code 使用 --dangerously-skip-permissions,Codex 使用 --dangerously-bypass-approvals-and-sandbox(或沙箱模式),因此应在一次性的工作树、容器或 VM 中运行。
它们是各自 AI 智能体在启动时加载的项目指令文件:CLAUDE.md 用于 Claude Code,AGENTS.md 用于 Codex(及其他多个代理)。一个代码库可以同时服务两者:将规则放在 AGENTS.md 中,然后让 CLAUDE.md 用 Claude Code 的 @AGENTS.md 语法将其导入。
Codex 是 OpenAI 的编码 AI 智能体,以开源的 Codex CLI 形式运行在终端中,也作为 IDE 扩展和 ChatGPT 云任务提供;这些都共享你的 ChatGPT 套餐配额。Claude Code 是 Anthropic 的对应产品,位于终端、IDE 扩展、桌面应用和网页中。本基准测试比较的是两个 CLI 的无头模式。
Gemini CLI 是 Google 的开源终端 AI 智能体,具备无头的 gemini -p 模式和 GEMINI.md 指令文件。我们未将其纳入本基准测试;计划另行开展 Gemini CLI 与 Claude Code 的专项比较。
反复出现的话题包括用量限制(对 Opus 限制很快触达的抱怨)、Codex 更简洁直接、Claude Code 更详尽健谈,以及许多人两者都付费。这些都是印象而非测量数据,所以我们自己进行了基准测试。