审出问题不难,难在「落地」
让 Codex 审出问题只是第一步。真正的价值在于:把审查结果转化成实际的修改,并验证改对了。这一节讲审查反馈怎么「落地」,而不是停留在报告里。
file-lib 的 io.js 挖出了一堆问题——大文件内存占用、非法路径崩溃、模块级缓存竞态。但「发现问题」不等于「问题解决」。这一节我们把这些问题真正「落地」:分档、修复、复核、测试,一步不落,让 file-lib 从「体检出毛病」变成「真修好了」。第一步:把问题分档
审查完,别眉毛胡子一把抓。把问题按严重程度分档:
| 档 | 含义 | 处理 |
|---|---|---|
| 必须改 | bug、安全、数据风险 | 立即改 |
| 建议改 | 影响性能/可读性,但不是 bug | 尽快改 |
| 可不改 | 风格、优化空间 | 看情况 |
先处理「必须改」,再谈「建议改」。这是落地的最优先原则。拿 file-lib 上节挖出的问题来分档:
【必须改】
- io.js 读到不存在的文件直接 throw,调用方没兜底 → 会崩
- 模块级 cache 并发读会竞态覆盖 → 数据错乱
【建议改】
- 大文件一次性读全量,内存占用高 → 可改流式
【可不改】
- 某些函数命名可以更语义化
分完档,你就知道「先修谁」,不会在风格问题上浪费时间,也不会漏掉真正会崩的。
第二步:让 Codex 改「必须改」
分完档,把「必须改」的问题丢回去让 Codex 修:
上面审查出的「必须改」有 2 条,请逐一修复:
1. 边界:limit=0 时返回全部 → 加校验,limit 最小为 1
2. 性能:N+1 查询 → 改为一次 IN 查询
改完跑测试确认没破坏。
问题明确 + 要求修复 + 验证,Codex 就能精准落地。对 file-lib 的 io.js,这样丢给它:
把上面【必须改】的 2 条修复掉:
1. readFile 遇到不存在的文件,不要直接 throw,返回 { ok:false, error } 结构
2. 移除模块级 cache,改为函数内局部变量,避免并发竞态
改完跑一遍现有测试,确认其他模块没被破坏。
注意第 1 条我明确说了改成的返回结构——越具体,它越不会自己乱发挥。
第三步:人复核「关键改动」
不是所有改动都甩给 AI。关键改动人工复核:
- 涉及安全、数据的改动 → 人必须看
- 核心逻辑改动 → 人必须懂
- AI 说「已修复」≠ 真修好 → 人抽查
AI 修,人把关,尤其对「必须改」里的高危项。对 file-lib 修 io.js 的竞态和崩溃,改完你要亲自读一遍改动,确认它没引入新问题、没把 { ok:false } 结构改得让调用方踩空。AI 说「修好了」只是它的自我报告,不是证据。
第四步:测试兜底
改完一定要跑测试,别只看「改了没」:
修复后跑一遍:npm test
再针对原问题加回归用例,防止以后再犯。
测试是「改对了」的证据,也是防回归的保险。对 file-lib,修完 io.js 要专门为「不存在的文件」「并发读」各加一条回归用例:
// test/io.test.js 新增回归用例
it('不存在的文件返回 ok:false 而不是 throw', () => {
const res = readFileSafe('/no/such/file');
expect(res.ok).toBe(false);
});
加了回归用例,这次的修复才「锁死」,以后谁再改回去,测试立刻报警。
一个完整落地闭环
审查出问题 → 分档 → 修「必须改」 → 人复核关键 → 测试兜底 → 复审
这个闭环走完,审查才算「落地」,否则报告永远是报告。对 file-lib 走一遍就是:挖出 io.js 的问题 → 分档 → 修必须改 → 你复核 → 加回归用例跑测试 → 让 Codex 再审一遍确认干净。
常见误区
- 只审不改:出份报告就完事,问题还在
- 不分档:眉毛胡子一把抓,效率低
- 全信 AI 修复:AI 说修好了就信,不验证
- 没测试兜底:改完不跑测试,埋新雷
io.js 问题分成「必须改 / 建议改 / 可不改」三档;再让 Codex 修复「必须改」的 2 条(崩溃 + 竞态),要求它给出改成什么结构;最后你人工复核改动、为原问题补回归用例并跑 npm test。②怎么判断做对了:必须改的问题真的修好了(不再 throw、无竞态)、你亲自看懂并复核过改动、新增的回归用例确实能拦住「再犯」。③卡住了怎么办:如果 Codex 只改了一处忘了另一处,把「必须改」逐条列给它逐个确认;如果回归用例写不出来,让 Codex 参照 test/string.test.js 的写法帮你搭骨架。常见坑:AI 说「修好了」就真信了,没验证
这是落地环节最普遍的坑:Codex 修完一句「已修复」,你点个头就继续,结果下一个功能在它「修好」的地方炸了。AI 的「已修复」是它对自己的评估,不是经过测试的结论。
避坑办法:把「验收」当成不可省略的一步,明确要证据:
你说修好了,给我证据:
- 跑一下相关测试,贴出通过的结果
- 针对原来的崩溃和竞态,各写一条回归用例
- 确认其他模块的测试也没被破坏
拿不到证据,就不算「落地」。习惯性地把「修好 + 证明修好」绑在一起要求,你的 file-lib 才不会在看似修好的地方埋雷。落地不是 Codex 说了算,是你验证了算。
小结
- 落地 = 把审查结果变成「实际修改 + 验证」
- 分档:必须改 / 建议改 / 可不改,先改必须改
- 让 AI 修 + 人复核关键 + 测试兜底
- 走完「审→分档→修→复核→测→复审」闭环
下一模块进入「Git 工作流集成」。