AI 帮我写完功能后,我把 Code Review 的第一问换了
2026/8/4 1:39:05 网站建设 项目流程

上周我让 AI 改一个很普通的功能:订单列表增加“只看待支付”筛选,并记住用户上一次的选择。

它很快给出了 PR:筛选组件、URL 参数、请求参数、本地存储、单测,一个不少。跑起来也没报错。

但我没有急着看 diff,而是手动做了三件事:

  1. 先选“待支付”,刷新页面;
  2. 复制链接到无痕窗口打开;
  3. 清空筛选后点浏览器后退。

第三步就出问题了:页面回到了“待支付”的视觉状态,请求却发的是全部订单。原因不复杂——URL、组件 state 和 localStorage 三个状态源,在“后退”这个路径上没有统一优先级。

这不是 AI 特有的 bug。人手写也会踩。区别在于,AI 很容易把主流程补得又快又完整,让人误以为需求已经被实现;但它不会天然知道,浏览器后退、旧链接、失败重试、权限变化,哪些才是我们项目里真正昂贵的边界。

所以我现在给 AI 的第一份输入,不再是“帮我实现这个需求”,而是一组验收样例。

从“描述功能”变成“描述可观察行为”

以前我会这样提需求:

给订单列表加状态筛选,默认全部,刷新后记住用户选择。

这句话对人够用了,对 AI 却留了不少空白:

  • “记住”是 URL、localStorage 还是服务端?
  • URL 和本地记录冲突时听谁的?
  • 老链接带了已经下线的状态怎么办?
  • 切换租户或账号后还能沿用吗?
  • 请求失败时,筛选项是否要回滚?

把它改成验收样例后,输入会变得像这样:

describe('订单状态筛选',()=>{it('首次进入且 URL 没有 status 时,展示全部订单',()=>{})it('URL 中有合法 status 时,URL 优先于本地缓存',()=>{})it('选择待支付后,应更新 URL、发起对应请求,并在刷新后保持一致',()=>{})it('URL 中 status 非法时,回退到全部订单并清理非法参数',()=>{})it('切换账号后,不读取上一个账号的筛选缓存',()=>{})})

注意,这不是为了追求测试覆盖率。它真正的作用是把“完成”的定义钉在可观察结果上。

AI 可以根据这些样例补实现、补测试,甚至提出状态设计;但优先级、异常策略和产品取舍,仍然需要开发者先做判断。这里恰好是人比模型更值钱的部分。

我会让 AI 先回答两个问题,而不是直接改代码

现在接到类似需求,我通常先让 AI 做一轮“反向澄清”:

根据下面的需求和现有代码,列出状态来源、冲突优先级、可能破坏现有行为的路径。不要写实现,先给出需要确认的验收场景。

这个限制很有用。因为一旦直接让它写代码,它会自然选择一种自洽的方案,然后用很多代码把方案包起来。等我们发现设计不对,删掉的不只是几十行代码,还有已经被 review、联调甚至提测的时间。

第二个问题是:

如果这个功能上线后只能保留 5 条自动化测试,你会保留哪 5 条?每条防的是什么回归?

这能筛掉不少“测了等于没测”的用例。比如只断言按钮文字变了,意义不大;而“浏览器后退后 UI 与请求参数仍一致”,就是很典型的回归点。

Code Review 也该换顺序

AI 生成的代码经常很整洁:命名像样、注释齐全、类型也补得很勤快。先盯着函数拆分和写法,很容易陷进去。

我现在 review 的顺序更粗暴一点:

  1. 用户能从哪些入口到达这个状态?
  2. 每个入口下,页面、URL、缓存和请求是否一致?
  3. 如果请求失败、数据为空、权限变化,用户看到什么?
  4. 这些路径里,哪几个已经有测试或可重复的验证步骤?
  5. 最后才看代码是否优雅。

前四项没过,后面的“优雅”基本没有意义。

有一次 AI 把一个复杂表单的保存逻辑抽成了三个漂亮的 hook。review 到最后才发现,接口返回 409 时它统一 toast 了“保存失败”,但产品实际要求是提示用户刷新并保留未提交的编辑内容。代码没错,业务结果错了。

这类问题不该靠“认真一点”避免,而要在验收阶段显式写出来。

一个不那么完美、但够用的工作流

我目前用的是下面这个小闭环,没什么神奇之处:

  • 先写 3~5 条验收样例,至少包含一个异常或回退路径;
  • 让 AI 只输出方案和风险点,不要急着改;
  • 人确认状态归属和优先级后,再让 AI 实现;
  • 要求它把验收样例转成可运行测试,或给出明确的手工验证步骤;
  • review 时从用户路径倒推,不从 diff 正着读;
  • 合并后记录一次真实漏掉的边界,下次变成团队的样例模板。

最后一步尤其重要。团队不需要一份越来越厚的“AI 使用规范”,更需要把真实踩过的坑留下来:分页与筛选联动、重复提交、权限切换、弱网重试、老链接兼容……这些才是项目自己的上下文。

别把“会用 AI”理解成提示词技巧

AI 编程让“产出代码”变便宜了,但并没有让“定义正确结果”变便宜。

甚至相反:代码来得越快,模糊需求被迅速包装成完整 PR 的概率越高。以前一个需求写两天,中间还能被各种阻塞打断、重新思考;现在半小时就有可运行页面,人更容易跳过那段本该慢下来的设计。

我不觉得每个小需求都值得写完整测试矩阵。一个内部运营页的文案调整,确实没必要上纲上线。但只要功能涉及状态同步、钱、权限、数据删除,或者用户能通过浏览器行为绕出主流程,我就会至少写下那几条验收样例。

它们不是 AI 的束缚,而是我们不把判断力外包出去的方式。

你在用 AI 改需求时,最容易漏掉的是哪类边界:状态同步、异常处理,还是对旧功能的兼容?欢迎在评论区聊聊你踩过的坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询