← 返回文章列表← Back to posts

让另一个 AI 来审你刚写的代码——/codex-audit 的设计与安装Let Another AI Audit Your Code — How /codex-audit Is Designed and Installed

用 OpenAI Codex 给 Claude 刚 commit 的代码做对抗式 review——拆解 threadId 多轮续跑、symmetric application、TDD 铁律等五个关键巧思,附手把手安装教程。Use OpenAI Codex as an adversarial reviewer for Claude's freshly committed code. Unpacks five key design insights — threadId-based multi-round continuation, symmetric application check, TDD discipline — plus a step-by-step install guide.

·17 分钟阅读min read

让另一个 AI 来审你刚写的代码——/codex-audit 的设计与安装

你刚让 Claude 写完一段代码,它跑了、测试也过了,commit 也打上了。你心里清楚这段代码十有八九还有坑——但让 Claude 自己回头审一遍,它大概率会告诉你「looks good to me」。因为它有 confirmation bias:它亲手写的代码,它看不见盲点。

/codex-audit 这个 slash command 做的事情只有一件——把 OpenAI 的 Codex 请来,当一个毫不客气的反方律师,把 Claude 刚 commit 的代码扒一遍,直到它说「没问题了」为止。

跑了两个月下来,这个命令已经是笔者每次 push 前的最后一道工序。本文把它的设计、五个关键巧思、以及怎么一步步装到你自己的 Claude Code 里,一次讲清。


一、为什么不是让 Claude 自己审自己

先回答这个最明显的问题。

你会发现,让刚写完代码的模型回头 review 自己写的东西,效果出奇的差。它会认真地读、认真地说出几条「建议」,但几乎都是无关痛痒的——变量命名可以更好、注释可以加一句、或者一些它根本没写错的地方被它"纠正"了一遍。

真正的 bug 它看不见。

这不是模型不够聪明的问题,是架构问题。一个模型在它的 context window 里已经装了:

  • 用户的需求
  • 它自己推理得出的设计
  • 它写下的代码
  • 它跑的测试
  • 它得出的"代码工作正常"的结论

让它再看一遍代码,它看到的不是"一段需要审查的代码",而是"我刚刚成功完成的任务"。它的注意力已经被前面建立的 narrative 锚定了——所有信息都会被它解读成"支持这个 narrative 的证据",这就是 confirmation bias 在 LLM 身上的体现。

解法简单粗暴:换一个没读过 commit message、不知道作者意图的模型来审。

这就是 /codex-audit 的全部动机。它请来的审查员是 Codex(OpenAI 的编程模型),不是 Claude——一个完全独立的 context,没有被刚才的 narrative 污染过。它读到的只是 git diff 和文件的最终状态,看到什么就说什么。

prompt 里也写得毫不客气:

You are doing an ADVERSARIAL code review. The committing agent has confirmation bias about its own work — your job is to find what it cannot see. Be harsh. Do not pad.

这句话是整个命令的灵魂。Codex 被明确告知:你是反方律师,不是温和的同事。

二、整个循环的骨架

拆开看,命令做的就是一条最朴素的 ReAct loop,只不过"工具"是另一个 LLM:

Step 0  准备 scope  —— 算出要审哪几个 commit,生成报告路径
Step 1  Round 1    —— 调 Codex 做首轮审计
Step 2  Triage     —— 按 🔴HIGH / 🟡MED / 🟢LOW 分桶
Step 3  TDD 修 bug —— 先写失败测试,再写代码
Step 4  Commit     —— 本轮修复打一个 commit
Step 5  判断       —— 未收敛 && rounds < 4 就继续
Step 6  Round N    —— 调 codex-reply 延续同一个线程
         ↑_________________________________↓
                    (回到 Step 2)
Step 7  写审计报告  —— docs/audits/YYYY-MM-DD-<sha>-<slug>.md
Step 8  汇报       —— 告诉用户跑了几轮、修了啥、报告在哪

这条 loop 没什么特别的——特别的是它里面藏的五个设计巧思。下面一个一个讲。

三、五个真正值钱的巧思

巧思 1:threadId 把多轮审计串成一段连续对话

Codex MCP 有两个工具:

  • mcp__codex__codex:第一轮调用,返回一个 threadId
  • mcp__codex__codex-reply:后续轮次调用,带上 threadId 延续对话

这个设计很关键。如果每轮都开新线程,Codex 每次都得从零读一遍代码,而且会把上一轮找过的问题重新找一遍——浪费 token,还会让你误以为"问题没修好"。

用 threadId 续跑之后,Codex 第二轮看到的 context 是:

上一轮我说了 ABC 三个问题 → 用户 commit 了 fix → 请审视新 commit

它自然就会把注意力从"找新问题"转向"检查这个 fix 是不是真修好了、有没有引入新 bug"。这是跨轮次分工的天然产物。

巧思 2:Round 1 发散、Round N 收敛,用两套不同的 prompt

Round 1 的 prompt 是发散式清单——让 Codex 从 8 个维度广撒网:

  1. Security issues (injection, path traversal, auth bypass, secret leak)
  2. Concurrency / race conditions
  3. Error paths that silently swallow failures
  4. Schema / input validation gaps
  5. Edge cases tests missed
  6. Type-safety holes
  7. UX / DX issues
  8. Anything else

Round N 的 prompt 变了形态——不是再撒一次网,而是三个聚焦问题:

  1. Did my fixes introduce new bugs?(回归类)
  2. Did I miss any edge cases you implicitly assumed?(完整性类)
  3. Symmetric application——fix 是否对称应用到 error path / fallback / 兄弟函数?

第 3 条是这个命令最值钱的单点设计,下一小节专门讲。

巧思 3:symmetric application——从 dogfood 里学出来的铁律

笔者最初写这个命令时,Round N 的 prompt 跟 Round 1 几乎一样——只是换了句话"请再看一遍"。结果跑了几次发现一个规律:

Round N+1 找到的问题,有相当比例长这样——"你修了 happy path,忘了 error path"。

具体的真实 case:

  • 你把用户输入做了 sanitize、但 stderr 打的错误消息里仍然打印了原始的攻击字符串
  • 你在 CLI 的 single-shot 路径加了 validator、但 REPL 路径没加
  • 你给 success 分支加了 structured logging、但 catch 块还在用 console.log

这些都是同一类错误:fix 只打在了一个地方,但漏洞其实散布在多个对称位置。

于是 Round N 的 prompt 被改造成显式提示 Codex 去找这种对称性:

When a fix hardens ONE code path, check whether the SAME protection was applied to:

  • Error branches / catch blocks of the same function
  • Fallback paths (default values, degraded modes)
  • Sibling functions doing similar operations
  • stderr warning paths (not just stdout happy paths)
  • Other entry points reaching the same helper (CLI vs REPL, API vs direct call)

一句 prompt 的修改,让 Round N 的 finding 质量直接上了一个台阶。这是整个命令里最"从实战学出来"的一笔。

巧思 4:双重停机条件

Loop 什么时候停?两条线同时拉着:

MAX_ROUNDS = 4
STOP_PATTERNS = ["converged", "no findings", "nothing found", "no issues"]
  • 软停机:Codex 自己说 "converged" 就立刻停——尊重模型的判断
  • 硬停机:跑满 4 轮强制停——防止审计陷入死循环

这是 agent 设计里一个常见的组合:既不剥夺模型的 halt 决定权,也不给它无限 token。4 轮这个数字不是拍脑袋的——dogfood 记录里,绝大多数情况在 2-3 轮收敛,极少越过 4 轮。

巧思 5:TDD 作为硬护栏

TDD_REQUIRED = true — every fix must be test-driven

每个 fix 必须先写一个会失败的测试证明 bug 存在、再写代码让它过。这条规则解决的不是"代码质量"——是"审计循环的收敛性"问题。

想象一下:如果 Claude"修"了一个 bug 但其实没真正修到,下一轮 Codex 会再次发现它——循环就卡住了。TDD 的 failing test 是唯一能证明"这个 bug 的出现通道已经关掉了"的硬证据。没有这条铁律,4 轮跑完都不会收敛。

四、Dogfood 记录:两个真实 case

命令的 markdown 文件末尾内嵌了一张验证记录表,这也是个不常见但很聪明的做法——把自己的"生产事故后复盘"和代码放在一起:

日期 场景 Scope 跑了几轮 发现 是否收敛
2026-04-10 Case A 一个已"4 轮 converged"的 commit 3 5 个(3 MED + 2 LOW) ✅
2026-04-10 Case B 植入了 4 个故意 bug 的新 feature 3 13 个(2 HIGH + 7 MED + 4 LOW) ✅

Case A 的启示:一个之前在 continuation thread 里 4 轮都说"converged"的 commit,换个 session 新开一轮审计,还是能找到 5 个真 bug。这说明——

"Converged" 不是永久状态——它只在一个 reviewer context 里成立,换个 session 就可能发现遗漏。

关键代码路径应该周期性地 re-audit,不要因为上次审过就豁免。

Case B 的启示:故意植入的 4 个 bug,Codex 抓到了 3 个(漏了一个时区显示问题)。但它同时还发现了 10 个 bug 是笔者根本没有故意植入的——包括 2 个 HIGH 级别的终端注入漏洞。

用"是否抓到我植入的 bug"来判断审计质量是错的。审计的真正价值在于它能帮你找到你不知道自己犯了的错。


五、手把手安装

下面是完整的安装流程,三部分:

第一步:放置命令文件

# 1. 建立 commands 目录(已有就跳过)
mkdir -p ~/.claude/commands

# 2. 下载或拷贝 codex-audit.md 到这里
# 如果你有我的原文件:
cp /path/to/codex-audit.md ~/.claude/commands/

# 或者从 gist 拉:
curl -sL https://gist.githubusercontent.com/felix5127/ef2881be26b6d127303f17ce676f905d/raw/codex-audit.md \
  -o ~/.claude/commands/codex-audit.md

装在 ~/.claude/commands/ 是用户级,在任何项目里都能用 /codex-audit。如果你只想在特定项目启用,改放到项目根目录的 .claude/commands/。

第二步:配置 Codex MCP

编辑 ~/.claude.json(没有就新建),在 mcpServers 里加入 Codex 的一段:

{
  "mcpServers": {
    "codex": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@openai/codex", "mcp-server"],
      "env": {}
    }
  }
}

⚠️ 如果你已经配了别的 MCP server,不要覆盖整个文件——只在现有的 mcpServers 对象里追加 codex 键即可。

这个配置的好处是不需要预装任何东西:npx -y 会在第一次调用时自动拉下 @openai/codex 包、启动 MCP server。相比要 brew install 的方案省心得多。

第三步:准备 OpenAI 认证

Codex 需要能调 OpenAI 模型。两种方式任选:

方式 A:用 ChatGPT 订阅(推荐)

# 先单独装一次 codex CLI 走登录流程
npx @openai/codex

# 第一次会自动打开浏览器走 OAuth
# 登录后 token 存在 ~/.codex/auth.json,MCP server 会自动读

方式 B:用 API key

# 把 API key 放进环境变量
export OPENAI_API_KEY=sk-...

# 或者写进 mcp.json 的 env 字段里
# "env": { "OPENAI_API_KEY": "sk-..." }

第四步:重启 Claude Code

让它重新加载 MCP 配置。

第五步:第一次试跑

随便找个 git 项目,保证 git status 干净(没有未提交的修改),然后:

/codex-audit

默认会审 HEAD。第一次跑会看到 Claude 向你汇报:

  • 准备审的 commit 范围
  • 调 Codex 的过程
  • Codex 返回的 findings 分桶
  • 每个 HIGH/MED finding 的 TDD 修复过程
  • 最终的审计报告路径

一次完整的 4 轮审计,在一个 ~500 行的 feature 上通常跑 5-10 分钟,消耗一定 token。适合 push 前最后跑一次——尤其是安全敏感、并发、IO、类型边界相关的代码。


六、使用示例

几种常见用法:

# 审最近一个 commit(HEAD)
/codex-audit

# 审最近 3 个 commit 作为一个整体
/codex-audit HEAD~3..HEAD

# 审某个具体的 commit
/codex-audit abc123f

# 指定 feature 标签(会出现在报告文件名里)
/codex-audit --feature cli-resume

跑完后你会得到两样东西:

  1. 几个 fix commit——每轮真找到问题就打一个,所有修改都带 TDD
  2. 一份 markdown 审计报告——躺在 docs/audits/YYYY-MM-DD-<sha>-<slug>.md

报告不会自动 commit、也不会自动 push。这两件事交给你自己决定——/codex-audit 永远只做"审"这一件事,不碰 publish 类操作。


七、什么时候用 / 什么时候不用

值得跑的场景:

  • Push 前对一段刚写完的 feature 做最后检查
  • 安全敏感代码(处理用户输入、权限、加密、文件路径)
  • 并发代码、事务代码、有文件/数据库 IO 的路径
  • 周期性 re-audit 核心代码路径——"converged"不是永久保质期
  • 你自己也觉得心里不踏实的任何 commit

不值得跑的场景:

  • 纯文档、配置文件修改
  • Trivial 修复(typo、注释调整)
  • Prototype 阶段、明知道要推翻重写的代码
  • 已经跑过 CI 且逻辑简单到没必要 adversarial review 的改动

不合适的场景:

  • 你没有 OpenAI API key 或 ChatGPT 订阅——那就没法用 Codex,这个命令核心价值失效
  • Repo 里有大量敏感信息不能传给第三方模型——Codex 会读代码内容,等于把代码发给 OpenAI

八、一句话总结

/codex-audit 做的事情可以浓缩成一句:

用 threadId 串起最多 4 轮对抗式审计,每轮按 TDD 修 HIGH/MED、bundle LOW 到同文件 fix 里、显式检查 symmetric application 查漏,跑到 Codex 说"converged"或跑满 4 轮就停,把所有证据写成报告、不自动 push。

它最值得学的不是"用 Codex 审代码"这件事本身,而是三条元设计:

  1. 跨模型对抗——用一个没读过 commit message 的独立 context 绕过 confirmation bias
  2. Dogfood → 规则 → prompt 的学习闭环——把踩过的坑(如 symmetric application)回注到 reviewer 的 prompt 模板里
  3. 软停机 + 硬停机并存——既尊重模型的判断,又留一条兜底的安全线

这三条在你写任何 agent command / skill 时都通用——不止做 code review,做文档审查、设计评审、自我测试都套得上。


相关链接: