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

Codex 给你回了 50 条 audit,从 typo 到架构混在一起——按维度收窄、限输出大小、强制 file:line。

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

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

常见原因

按命中率从高到低:

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

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

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

如何判断:看你原始 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+ 个标签就是维度混了。

最短修复路径

按收益从高到低,前 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,不要合成一份巨型报告。

Step 3:用受约束的 audit prompt

把下面这段贴过去,填上方括号里的内容:

仅审计 [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 条再读一遍。

预防建议

  • 每个维度维护一份 prompt 模板(prompts/audit-security.mdprompts/audit-perf.md…),别现写
  • 每次 audit 输出限 10 条;问题多就分片跑,下次再开
  • 强制要求 severity + file:line + 一行修法,三者缺一即拒收
  • 发现进 issue tracker,不要烂在 markdown——markdown 不更新,ticket 会被关
  • 安全每发版审,性能每退化审,风格每季度审,按维度定 cadence
  • 重审前把上一轮发现作为 skip 列表传进去,确保第 N 轮还在变短

相关阅读

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