Codex 审计报告范围太广:6 个原因 + 可执行的修复模板

让 Codex 审项目,结果回了 50 条 audit,从 typo 到架构混在一起?收窄到单一维度、限输出大小、强制 file:line,用 /review 的自定义指令预设。

你发了”帮我 audit 一下项目”(或在 /review 里选了 Custom review instructions),收到一份 50+ 条的报告:「考虑用 const 替代 let」、「API key 应该走环境变量」、「这个函数 200 行了」、「建议补 edge case 测试」……读完只剩一个感受——下午到底先修哪 3 个?这份报告就成了一份你永远不会动手的”愧疚清单”。

最快修法: 单一维度、单一范围、限定输出条数。跑 /review -> 选 Custom review instructions,贴一行:Audit only src/api/auth/ for security issues. Return at most 10 items, P0–P3, each with file:line. Skip cosmetic items.——光这一步就能把一墙 bullet 变成能排期的清单。完整模板见下面 Step 3。

这不是模型问题,是 audit prompt 问题。一份能用的 audit 必须只有一个维度、一个范围、固定输出大小、每条带文件锚点。下面拆解 audit 跑广的 6 个常见原因,以及能稳定产出 10 条可执行清单的 prompt。

术语澄清(截至 2026 年 6 月):并不存在 codex audit 子命令。内置审查器是 /review 这个 slash 命令,它提供四个预设——review against a base branch、review uncommitted changes、review a commit,以及 Custom review instructions。最后这个会把你的自由文本 prompt 拼到审查器前面,所以它正是放”带范围的 audit”的地方。直接在对话里发”audit my project”也行,但 /review 会把范围限定在某个 git diff,且永远不改你的工作区。

常见原因

按命中率从高到低:

1. Prompt 只有”审一下项目”

开放式 prompt 必然得到开放式报告。“audit”不指明维度,Codex 只能猜你在乎什么——而它的对冲策略就是”全部列一遍”。

你:audit 一下我的项目
Codex:[返回 50 条,覆盖安全 / 风格 / 性能 / 类型 / 测试 / 文档 / 可访问性]

打开 /review、选 Custom review instructions、只输入”全都审一遍”也是同样的下场——这个预设会把你的文本原样拼上去,含糊的指令只会换来含糊的审查。

如何判断:看你原始 prompt——只要没出现「安全」「性能」「类型」之类的单一维度词,报告肯定混维度。

2. 没限 scope,Codex 审了整个 monorepo

不指定路径时,Codex 会爬整棵树。monorepo 一审就把 apps/marketing/packages/ui/scripts/docs/ 的问题全堆在一起——但你这次只关心 API 层。

如何判断:按文件路径分组——跨 4 个以上顶层目录就是 scope 没限。

3. 没要严重度,每条看起来一样重

不要求”为每条标 1–5 严重度”时,Codex 是按发现顺序返回的,不是按影响排序。一行 ; 漏写就紧挨着一个 SQL 注入风险。

如何判断:读前 5 条——明显严重的事项和小修小补的事项混在一起、没标签,就是没要 severity。

4. 重审时没传”已修”列表

第二轮 audit 又把上一轮你修过的问题列一遍——因为 Codex 不知道这期间改了什么。你又得手动标 40% 是「已修」。

如何判断:把这次和上次 audit 做 diff——文字 30%+ 重复就是没传 skip 列表。

5. 没文件锚点(file:line)

「建议改进 auth 流程的错误处理」这种条目没法立即执行——要花 20 分钟翻文件。报告显得长,其实是被大段含糊描述撑起来的。

如何判断:数有多少条带 file.ts:42 这种锚点——低于 50% 就没法直接排期。

6. 维度混杂:style + perf + security 一起跑

让 Codex 找”所有问题”时,它返回的是并集。不同维度的判断标准不一致,报告读起来就乱(漏注释和漏 CSRF 检查被给了一样的权重)。

如何判断:给每条打 security / perf / style / types / tests / docs 标签,直方图平铺到 4+ 个标签就是维度混了。

你属于哪一类?

报告里的症状根因跳到
安全 + 风格 + 性能混在一份里没限单一维度Step 1
条目来自 4+ 个顶层目录没限 scopeStep 2
严重和小修没标记、按发现顺序排没要严重度Step 3
30%+ 条目和上一轮重复没传 skip 列表Step 5
不到一半条目带 file.ts:42 锚点没要 file:lineStep 3

大多数”广 audit”是同时踩中其中两三条,所以 Step 3 的模板用一个 prompt 同时锁住维度、严重度和 file:line。

最短修复路径

按收益从高到低,前 3 步就能把”广 audit”变成 10 条可执行清单。

Step 1:只挑一个维度

每次只挑下面一个:

维度什么时候跑
security发版前;改了 auth / 支付 / 用户输入后
perfp95 延迟或 bundle size 退化时
typesTypeScript 升级或大重构后
tests每季度,或刚修完一个没补测试的 hotfix
style每季度跑一次,优先级最低
docs新人 onboarding 前

安全审计单独跑,不要和 style 打包在一起。

Step 2:只选一个窄 scope

能落地的 scope 是「一个目录」或「一个功能」,不是「整个项目」。例子:

  • src/api/auth/ — 一个功能模块
  • src/components/billing/ — 一个用户流
  • migrations/*.sql — 一类文件

代码量大就切片跑,把发现合并进 issue tracker,不要合成一份巨型报告。

/review 时,Review against a base branchReview uncommitted changes 两个预设本身就把范围限定在某个 git diff(Codex 会算出你和上游分支的 merge base),天然只审你刚改过的部分。要审整个目录、不受 git 状态影响,就用 Custom review instructions,把路径写进 prompt 里。

Step 3:用受约束的 audit prompt

把下面这段贴进 Custom review instructions 预设(或直接发对话),填上方括号里的内容:

仅审计 [SCOPE] 下的 [DIMENSION] 问题。

约束:
- 最多 10 条,按严重度排序(P0 → P3)。
- 每条必须包含:
  - severity(P0 = 阻塞发版,P1 = 发版前修,P2 = 下个迭代,P3 = 可选)
  - file:line(或文件区间)
  - 一句话问题描述
  - 一句话修法
- 跳过纯外观问题(格式、命名),除非掩盖了 bug。
- 跳过这些已修事项:[贴上一轮 audit,或写"无"]。
- 不要提架构级重构。

用 markdown 表格输出,列:severity | file:line | problem | fix。

预期产出长这样:

| Sev | File:Line | Problem | Fix |
|---|---|---|---|
| P0 | src/api/auth/login.ts:42 | 密码用 `==` 比较,非常数时间 | 改 `crypto.timingSafeEqual` |
| P0 | src/api/auth/session.ts:118 | JWT 用 HS256,密钥在 env 不轮换 | 加 `kid` header,季度轮换 |
| P1 | src/api/auth/reset.ts:23 | 重置 token TTL 24h,RFC 建议 1h | `TOKEN_TTL` 降到 3600 |
| P2 | src/api/auth/middleware.ts:67 | 限流按 IP 不按账号 | key 加 `accountId` |

Step 4:进 issue tracker,不要留在 audit 文件里

每条 P0/P1 单独开 issue,标题里带 file:line。P2/P3 合并成一张「audit backlog」票。markdown 报告读完即弃。

# 用 gh CLI 批量从 Codex audit 建 issue
gh issue create -t "P0: login.ts:42 时序攻击" -b "Codex audit 2026-05-22"

Step 5:重审时传”skip”清单

第二轮 prompt:

审计 src/api/auth/ 的安全问题。
SKIP 这些已修事项:
- 常数时间密码比较(login.ts:42)
- JWT 轮换(session.ts:118)
- 重置 token TTL(reset.ts:23)

约束同第一轮。

得到的就是一份新清单,而不是同样 50 条再读一遍。

Step 6:确认真的修好了

一份带范围的 audit 算成功,要同时满足这四条:

  1. 单一维度。 每条都对应你指定的那个维度(安全审里不掺杂风格意见)。
  2. 条数受限。 列表不超过你设的上限(<= 10),不是 30+ 条。
  3. 带锚点。 每条都带 file.ts:42 锚点,能直接打开。
  4. 已排序。 条目按 P0 -> P3 排,不是按发现顺序。

任意一条不满足,说明对应的约束没生效——把那一行写得更明确再发一遍。一个快速自检:报告应该一屏能装下,且你能在十秒内在编辑器里打开第一条 P0。

预防建议

  • 每个维度把一份可复用的 audit prompt 存成 skill(截至 2026 年 6 月,Codex 的 ~/.codex/prompts/ 自定义 prompts 已被废弃,改用 skills——它能随仓库共享,也能从 /review 调用)。别现写临时 audit prompt。
  • ~/.codex/config.toml 里设一个更强的 review_model,这样即便日常用快模型,审查也跑在你最强的模型上。否则 /review 用的是当前会话模型。
  • 每次 audit 输出限 10 条;问题多就分片跑,下次再开。
  • 强制要求 severity + file:line + 一行修法,三者缺一即拒收。
  • 发现进 issue tracker,不要烂在 markdown——markdown 不更新,ticket 会被关。
  • 安全每发版审,性能每退化审,风格每季度审,按维度定 cadence。
  • 重审前把上一轮发现作为 skip 列表传进去,确保第 N 轮还在变短。

常见问题

有没有 codex audit 命令? 没有。截至 2026 年 6 月不存在 audit 子命令。内置审查器是 /review slash 命令,四个预设:review against a base branch、review uncommitted changes、review a commit,以及 Custom review instructions。带范围的 audit 放在最后这个预设里,或在普通对话里用 Step 3 的模板。

为什么 /review 只审了几个文件,我想审整个项目? 四个预设里有三个把范围限定在 git diff(Codex 会算出你和上游分支的 merge base),所以只看改动过的文件——这是设计如此。要审整个目录、不管 git 状态,就用 Custom review instructions,在 prompt 里写明路径,例如 Audit only src/api/

上限被忽略,还是回了 30 条,怎么办? 上限是软约束,不是硬限制。把它放在约束的第一条,写成”Return at most 10 items, drop the rest”,并且只挑一个维度。上限 + 单一维度几乎总能守住;五维度 prompt 上的上限基本守不住。

审计要不要专门用更强的模型? 通常要。在 ~/.codex/config.toml 里把 review_model 设成顶配模型(例如 GPT-5.5 的推理档),这样 /review 总用它,而你的交互会话仍跑在快模型上。安全审计尤其能从更强的审查器受益。

怎么让重审不再把已修的条目又列一遍? 把上一轮的发现作为显式 SKIP 列表贴进去(Step 5)。Codex 在会话之间不记得你修过什么,没有 skip 列表它每次都会把同样的问题重新发现一遍。

相关阅读

标签: #Codex #Coding Agent #排查 #排查 #审计过广