11|CI、Hooks、测试:别相信 AI 说「应该没问题」

11|CI、Hooks、测试:别相信 AI 说「应该没问题」

2026-10-19 17:47:30 0点赞 0收藏 0评论

本篇是《从头重新学 AI 编程》系列第 11 篇。

对于很多非编程专业的朋友来说,这篇在 AI 编程中不是必须的,有了前面的知识,你基本上已经可以在一些简易的项目中得心应手了。而这篇属于在生产环境上的加强防护,算是能让你对 AI 编程的理解更加深入。

上一篇聊了 Skill,怎么把反复说的话固化成自己的模板。

这一篇聊一个你迟早会踩的坑,AI 写完代码跟你说「应该没问题」,你到底该不该信。

先讲一件事。

我让 AI 给一个待办应用加「批量删除」功能。AI 很快写完了,回了一句让我特别有安全感的话,已完成,添加了批量删除的 API 和前端按钮,测试已通过,代码没有问题。

我看了一眼,逻辑好像对,代码也挺整洁。点了合并。

然后线上炸了。

原因是它写的批量删除,没有检查这些待办项是不是属于当前用户。任何人只要猜到 ID,就能删别人的数据。

你说 AI 是故意骗我吗?不是。它跑的测试是它自己写的,那个测试只测了「能不能删成功」,根本没测「能不能删别人的」。在它的世界里,测试确实过了,代码确实没问题。

这就是 Vibe Coding 里我觉得最危险的一个瞬间,你信了 AI 那句「没问题」。

为什么会这样?因为你让 AI 自己写代码、自己写测试、自己跑测试、自己说没问题。这就像让考生自己出卷子、自己批卷子,那分数当然好看。

11|CI、Hooks、测试:别相信 AI 说「应该没问题」

所以你需要的不是更聪明的 AI,是几道不归 AI 管的防线。我自己梳理下来是三道,每一道拦的东西都不一样。

第一道,叫 Hooks,作用是事前拦截。

你在 AGENTS.md 里写的那些规则,其实是软约束。你写了「不要改 migration 文件」,AI 可能记住,也可能聊到第二十轮就忘了。Hooks 不一样,它是硬约束,在 AI 执行操作的那一瞬间,用脚本去检查,不合规直接给你拦下来。

打个比方,AGENTS.md 是贴在门口那张「请勿吸烟」的告示,Hooks 是烟雾报警器加自动喷淋。一个靠自觉,一个直接动手。

它能拦的事情挺多的。AI 要执行 rm -rf 或者 git push --force,直接阻断。AI 改完文件忘了格式化,自动补一道 prettier。AI 想去读 .env 文件,拦住,提醒它走环境变量。会话一开始,自动提醒它先读 AGENTS.md。

以我们这个待办应用为例,你可以配一个 hook,让 AI 每次改完 .ts 文件就自动跑一遍 lint。

{ "hooks": { "afterFileEdit": [ { "matcher": "*.ts", "command": "npx prettier --write $FILE && npx eslint --fix $FILE" } ] } }

配好之后,AI 写的每一行 TypeScript,出来就是格式化好的,你完全不用操心。

Hooks 跟 AGENTS.md 的分工其实很清楚。AGENTS.md 告诉 AI 应该怎么做,Hooks 直接拦住它不该做的。一个动嘴,一个动手。

11|CI、Hooks、测试:别相信 AI 说「应该没问题」

但 Hooks 有个管不到的地方,它拦得住危险命令和格式问题,拦不住逻辑错误。前面那个「批量删除没检查权限」的坑,Hooks 一点办法都没有,因为那段代码格式完美、命令也不危险,它就是逻辑上少了一刀。

这种问题,只有测试能抓出来。这就是第二道防线。

但这里有个关键的顺序问题。在 Vibe Coding 里,测试不是写完代码再补的东西,而是先定「什么算对」,再让 AI 去写。

你跟 AI 说「帮我加个批量删除」,它上来就开写了。但如果你换个说法,

先不要写实现。帮我列一下批量删除这个功能,需要测哪些场景。

它会给你一份测试计划,大概像这样。

1. 正常删除,选中 3 个待办,删除成功,列表更新 2. 空选,没选任何项就点删除,提示请先选择 3. 权限校验,尝试删除不属于自己的待办,返回 403 4. 部分失败,选中 5 个,其中 1 个不存在,其余 4 个正常删除 5. 并发,两个人同时删同一个待办,不报错

你扫一眼就会发现,第 3 条「权限校验」,AI 自己写实现的时候大概率是想不到要测的。那你现在就把它摁在这儿,确认它会覆盖到,然后再让它写代码。

这里有个原则我想说重一点,永远不要让 AI 实现完再补测试。因为它补的测试会刚好贴着它写的实现来,实现里有什么 bug,测试就跟着绕过什么 bug,俩一起糊弄过去。先定标准再写代码,测试才是在考它,而不是在配合它。

测试定好了,还有个现实问题,你不可能每次 AI 一改代码你就手动跑一遍。这事得自动化,那就是 CI。

一份最小的 CI 配置,拿 GitHub Actions 举例,长这样。

name: CI on: push: branches: [main] pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm ci - run: npm run lint - run: npm test - run: npm run build

就四步,装依赖、跑 lint、跑测试、跑构建。任何一步挂了,整个 CI 红灯,代码合不进去。

你还可以在 AGENTS.md 里加一条,让 AI 主动配合 CI。

## CI 规则 1. 提交前必须本地跑过 npm run check,确保通过 2. 如果 CI 挂了,先看失败日志,不要猜测式修复

然后在 package.json 里加一个命令,让本地检查跟 CI 跑的完全一样。

{ "scripts": { "check": "npm run lint && npm test && npm run build" } }

这样 AI 改完能自己先跑一遍 check,不用傻等 CI 跑五分钟才发现挂了。

11|CI、Hooks、测试:别相信 AI 说「应该没问题」

聊到这,你可能觉得,CI 绿了,测试过了,这下总该万事大吉了吧。

还真不是。

CI 能证明的,是代码能构建、测试能跑过。但它证明不了一件更重要的事,功能方向对不对、设计合不合理、有没有顺手改了不该改的东西。这些是机器看不出来的,得靠 review。这就是第三道防线。

还记得第 7 篇讲的 Subagent 吗?我当时说,实现和审查不能共用一个上下文。这里就是最典型的应用场景。写代码的那个 AI,已经为自己的方案辩护了好几轮了,你再让它回头审自己的 diff,结果几乎一定是全绿,它怎么可能说自己写得不好。

正确的做法是另开一个干净的会话,让一个没参与过实现的 AI 来审。

你是 code reviewer,只读,不准改代码。 输入, - AGENTS.md,项目约定 - git diff,这次的改动 输出要求, 1. diff 有没有超出这次任务的范围 2. 有没有顺手改了无关文件 3. 测试覆盖了哪些场景,哪些没覆盖 4. 有没有新增依赖,有没有碰 auth、权限、密钥 5. 按严重程度列出问题,blocking、question、nit

这个 review agent 只看 diff,没参与过实现,上下文是干净的。它不会因为「这段代码是我写的」而手下留情。一个旁观者,永远比当事人更容易看出问题。

把这三道防线串起来,AI 写完代码、你合并之前,其实就是过一份提交前的清单。

提交前 checklist 格式和规范 - [ ] lint 通过 - [ ] 类型检查通过 - [ ] 格式化一致 逻辑和测试 - [ ] 测试覆盖了正常流程 - [ ] 测试覆盖了边界情况,空值、权限、并发 - [ ] 自己跑了测试、看了输出,不是只信 AI 说的过了 范围和设计 - [ ] diff 没有超出这次任务 - [ ] 没有顺手改无关文件 - [ ] 没有无理由新增依赖 - [ ] 没有碰 auth、权限、密钥 文档 - [ ] 公开行为变了,文档同步了

你可以把这段贴进 AGENTS.md,让 AI 每次提交前自己先过一遍。但有句话我得说清楚,AI 自己过 checklist 只是第一轮,你自己过那一遍,才是最终确认。

说到这个,我还想给你一个我每次都会用的指令。AI 实现完功能之后,别让它甩给你一句「已完成」,你这么跟它说。

实现完成后,不要直接总结「已完成」。先输出, 1. 修改了哪些文件,每个文件为什么改 2. 跑了哪些测试,输出是什么 3. 哪些测试没跑,为什么 4. 还有什么风险是我需要自己检查的

这段话的目的,就是逼它把证据摆出来,而不是给你一句感觉。

「应该没问题」不是验证结果。「测试跑了,输出贴在这」才是。这两句话的差别,就是工程和碰运气的差别。

11|CI、Hooks、测试:别相信 AI 说「应该没问题」

顺着这个再多说一句,关于「测试要自己跑」这件事,我想专门拎出来强调,因为它实在太常见了。

AI 跟你说「测试通过了」,你信了。但你可能不知道,它说这句话的时候,背后可能是这么几种情况。它跑的是旧测试,新代码的测试压根没加进去。或者它改的是测试本身,让测试去迁就实现,而不是改实现。再或者,它根本没跑,只是「预计会通过」。

所以,永远不要信 AI 那句「我跑过了」。让它把命令和输出贴出来,或者你自己跑一遍。

这不是不信任 AI,这是工程纪律。你让一个同事改完代码,也得自己跑一遍测试才敢合,对 AI 凭什么放宽。

回过头看这三道防线,加上 AGENTS.md,其实是四层东西在配合。

AGENTS.md 管软约束,约定、风格、红线,AI 偶尔忘了也不至于出大事。
Hooks 管硬拦截,危险命令、格式、敏感文件,因为操作一旦执行就撤不回来了。
测试和 CI 管事后验证,逻辑错误、回归 bug,漏了就会混进主分支。
Review 管合并前的最后把关,方向偏差、设计问题、AI 自己审不出来的盲区。

11|CI、Hooks、测试:别相信 AI 说「应该没问题」

四层叠在一起,才是一道完整的护栏。少了任何一层,都会在某个时刻给你来一下。

我有时候会把它类比成开车。安全带、气囊、刹车、后视镜,平时你一个都用不上,但少哪个你心里都不踏实。写代码也一样,尤其是 AI 写的代码,它量大、速度快、看着特别专业,但「看着对」和「真的对」之间,差的就是这几道你愿不愿意搭起来的防线。

给你一个小练习。

下次你让 AI 写完一个功能,别急着合。先按上面那份 checklist 过一遍,自己跑一次测试,再开一个新会话让另一个 AI 审一下 diff。你体会一下「证据都在手里」的那种踏实,跟以前「AI 说没问题我就信了」的那种忐忑,完全是两种感觉。

下一篇是第 12 篇,也是正文的最后一篇。我们聊 AI Coding 的反模式清单,那些真能把项目搞失控的错误,以及怎么躲开它们。

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
京东京享红包
距结束::
领京东现金红包 天天领3次 最高26888元
红包按钮
最新文章 热门文章
0
扫一下,分享更方便,购买更轻松