Codex 的 code review 太浅?这样修

Codex review 只给「考虑下错误处理」这种泛话——用内置 /review 命令、AGENTS.md review 规则和 file:line 锚定的 prompt 修。

你让 Codex review 一个 PR,它给了 8 条像 code-review 模板的话:「考虑下错误处理」「补 edge case 测试」「线程安全?」「注意 null 输入」。你按它没法动手,也看不出 Codex 到底打开过那些被改的文件没。

最快的修法:别再打「review 这个 PR」。在 Codex CLI 里用内置的 /review 命令,或在 PR 上评论 @codex review,再在仓库的 AGENTS.md 里加一段 ## Review guidelines,让每次 review 都强制 file:line 锚定和严重度标签。泛 prompt 换来泛 review;用 file:line 锚定的聚焦 prompt 才能换来具体答案。下面讲清楚你属于哪一类,以及能产出值得读的 review 的具体 prompt。

先用内置的 review 路径(截至 2026 年 6 月)

大多数「review 太浅」的抱怨,来自把 diff 粘到聊天框里。Codex 从 2026 年初就上线了专用 reviewer——它会读完整文件(不只是 diff hunk),按优先级报问题,且不动你的工作区。手搓 prompt 之前先用它:

  • 在 Codex CLI 里,会话中运行 /review。它检查你的工作区,重点看行为变化和缺失的测试,并报出 findings。再用 /diff 看它引用的具体文件改动。
  • headless / 开 PR 前,运行 codex review --base main,对着 merge base review 你的分支;也可以加聚焦:codex review --base main "Review for race conditions and idempotency in the payments path"
  • 在 GitHub 上,在 PR 上评论 @codex review(或在 GitHub 集成设置里开启「每个 PR 自动 review」)。要缩小范围:@codex review for security regressions, missing tests, and risky behavior changes. 它标出问题后,@codex fix it 会起一个 task 自动改并更新 PR。

如果内置 reviewer 还是浅,原因几乎必然是 prompt 或缺仓库规则——接着往下读。

常见原因

按命中率从高到低:

1. Prompt 就是「review 这个 PR」没标准

泛 prompt 产出泛 review。Codex 套总结模板,因为没东西告诉它「在这段具体代码里找什么」。

如何判断:回看 prompt——没指明维度(security / perf / correctness / API contract)或具体关切,就是套模板。

2. 仓库里没有 AGENTS.md review 规则

Codex 会对每个被改文件套用「最近的那份 AGENTS.md」里的指引。没有 ## Review guidelines 这一段,每次 review 都从零开始——它不知道你们团队把缺测试标 P1,也不知道 payments 包要格外严。

如何判断git ls-files | grep AGENTS.md 没输出,或文件里没有 review 这一段。同样的泛话出现在毫不相关的 PR 上。

3. Codex 只评了 diff,没读完整文件

3 行改动可能正确也可能灾难,取决于函数其他部分。当 review 只引 diff hunk 里能看到的行,说明它没读周围上下文。

如何判断:review 评论只引 diff 里的行,从不涉及调用方函数或文件的不变量。

4. diff 太大、Codex 抽样了

1500 行的 PR 撑爆上下文。Codex 前几个文件细读,后面摘要带过。前面评论密、后面稀。

如何判断:每文件评论密度不均——前 3 个有具体反馈、后 7 个一人一句泛话。

5. Codex 退回到了「安全的 reviewer 嗓音」

没锚定时 Codex 会和稀泥:「考虑」「你也许想」「注意」——既不指出确定问题、也不可被反驳。

如何判断:数「考虑」「也许」「可能」的次数——多就是 hedging 模式,不是真 review。

6. 没给 threat model / domain 上下文

Codex 不知道这个 PR 在支付路径,就当通用 CRUD review——具体关切(幂等、竞态、欺诈面)不会出现,因为没东西告诉它这是高风险代码。

如何判断:review 漏掉了 domain 专家一眼就看到的风险。

7. prompt 一次问太多

「review correctness + security + perf + style + a11y」——每个维度都浅一遍。它努力照顾全维度,反而每个都不深。

如何判断:review 触及很多维度但每个都不深。

你属于哪一类?

review 里的症状最可能的原因跳到
全程没有 file:lineprompt 太泛(#1)Step 1
每个 PR 都是同样的泛话AGENTS.md 规则(#2)Step 2
只评 diff 行,不管调用方代码只读了 diff(#3)/review(读完整文件)
前面文件具体、后面变泛diff 太大(#4)拆 PR / Step 2
满屏「考虑」「也许」hedging 嗓音(#5)Step 3
漏掉明显的 domain 风险没给上下文(#6)Step 4
啥都碰一下、哪个都不深一个大杂烩 prompt(#7)Step 3

最短修复路径

按收益从高到低,Step 1 一步就带来大部分深度提升。

Step 1:把「review 这个 PR」换成聚焦问题

用这个模板(接在 /review 的自定义指令后面,或写进 @codex review 评论里):

按 [具体关切] review 这个 PR。

每条问题:
- file:line(必填——不接受泛话评论)
- 一句话问题描述
- 一句话修法
- 严重度(P0 阻塞 / P1 merge 前 / P2 follow-up)

不要评论 style / 格式 / 其他 ESLint 已能 catch 的东西。
不要写「考虑 X」——要么把 X 标成带 P 级别的问题,要么不提。

「不要考虑 X」这条最关键——堵掉 hedging 退路。

Step 2:把 review 规则写进 AGENTS.md

这能让每次 review(CLI、GitHub、自动)都从你的标准起步,而不是空白模板。在顶层 AGENTS.md 加一段 ## Review guidelines——Codex 会对每个被改文件套用「最近的那份 AGENTS.md」:

## Review guidelines

- 每条 finding 都锚到 file:line;锚不上的删掉。
- 改了逻辑却缺测试,标 P1。
- 改了 public 函数签名或行为,标 P1。
- 在 services/payments/** 下,非幂等写入和无保护的并发更新标 P0。
- 不要提 style / 格式问题——那是 ESLint 的活。

在高风险包里再放一份嵌套的 AGENTS.md(或 AGENTS.override.md)——比如 services/payments/AGENTS.md——它对该子树下的文件优先级更高,因为「更近的文件赢」。

Step 3:一次 review 只问一个问题

不要打包维度,分开跑:

Pass 1:「按 correctness review。是否有任何合法输入会得到错误结果?」

Pass 2:「按 null/undefined 处理 review。列出每处新代码在没检 null 前就 deref。」

Pass 3:「按 API 合同变化 review。这个 PR 是否改了任何 public 签名 / 行为?」

每个 pass 都比一次大杂烩更深、更带 file 锚。

Step 4:前置 context

Context:这个 PR 在支付路径,~10K 笔/天。
我们关心:
- 幂等(同一请求两次不能双扣)
- 竞态(两个并行 webhook 更新同一订单)
- 审计(每次状态变更必须 log 谁 / 何时 / 从什么状态)

仅按这些关切 review,其他维度不管。

domain context 让通用 review 升级成 domain review。

Step 5:对抗式 framing

试试把这段代码打挂:
- `processPayment(req)` 能收到的最坏输入是什么?
- 最坏的并发时序(race condition)是什么?
- 什么状态会让这个函数违反前置 / 后置条件?

每条给出 输入 + 期待 vs 实际 行为。

对抗式问题逼 Codex 从「看着合理」切到「找失败」模式。

Step 6:抽查,再拒掉没锚的 finding

不要全盘信。挑 2 条 finding 核实:

review 声称:"billing.ts:42 有 read 和 update 之间的竞态。"
打开 billing.ts:42 读周围代码,自己判断。

抽查站得住——其他评论可信度高。抽查不通过(“42 行什么都没有”)——是幻觉,重 prompt。如果 Codex 出「考虑下错误处理」却没行号,推回去:

「考虑下错误处理」不可执行。每条问题给我:
- 具体 file:line
- 出问题的精确代码行
- 什么输入触发什么错误

按这些约束重 review,锚不上的条删掉。

这是给 session 训练——后续 review 会保持具体。

怎么确认修好了

一份真正有用的 review 应该过这 4 关:

  1. 每条 finding 都有可点的 file:line。没锚就不算 finding。
  2. 每条 finding 都有严重度(P0/P1/P2),让你知道哪条阻塞 merge。
  3. 抽查站得住——打开 2 条引用的行,问题确实在那。
  4. 它提到了你的 domain 风险(写在 AGENTS.md 或 context 块里的那些),不是通用 CRUD 套话。

如果跑完 Step 1–2 重 review 后还是零锚,说明 diff 太大(原因 #4)——拆 PR,或用 codex review --base main 限定单个路径逐个文件 review。

预防建议

  • AGENTS.md 保留一段 ## Review guidelines,高风险包用更严的嵌套规则。
  • 维护一个 review prompts 目录,每个关切一份(security / perf / correctness)。
  • 始终前置 domain context(支付 / auth / 内部工具)。
  • 强制每条评论带 file:line + 严重度,缺一即拒。
  • 跑多个窄 review pass,不要一次大杂烩。
  • 每份 review 抽查 2 条校准信任。
  • 重要 PR 上 AI review 是补充,不是替代——人工 review 不能省。

常见问题

Codex 有内置 review 命令吗,还是必须我自己 prompt? 有内置路径。CLI 里会话中运行 /review;headless 用 codex review --base main;GitHub 上评论 @codex review。三者都会读完整文件、按优先级报 findings,且不动工作区。prompt 是用来给内置 reviewer 聚焦的,不是替代它。

怎么让 Codex 每次 review 都强制 file:line 锚和严重度? 写进 AGENTS.md## Review guidelines(「每条 finding 锚到 file:line」「缺测试标 P1」)。Codex 对每个被改文件套用最近的那份 AGENTS.md,所以这条规则会在 CLI、GitHub、自动 review 里一直生效,不用每次重打。

为什么 Codex 只评 diff 里的行? 那是它读了 diff hunk 但没读周围文件。/review 命令和 codex review 按设计就会读完整的被改文件;如果你是把原始 diff 粘进聊天框,改用这两条命令。

我的 PR 有 1500 行,review 到一半就开始变泛,怎么办? 那是上下文压力(原因 #4)。拆 PR,或按路径 review:codex review --base main "focus on src/billing/**"。面积小了,反馈才会均匀地具体。

review 能不能用比交互会话更强的模型? 能。在 ~/.codex/config.toml 里设一个 review 专用模型:

[model]
review_model = "gpt-5.5-codex"

这样交互用更快的模型,review 用更强的推理。

Codex 标出了一个真问题——它能直接修吗? 在 GitHub 上评论 @codex fix it,它会起一个 task 自动改并更新 PR。合并前仍要抽查结果。

相关阅读

外部参考:

标签: #Codex #Coding Agent #排查 #排查 #Review 太浅