文章目录
- 前言
- 1. 规矩一:三态不齐,直接打回
- 2. 规矩二:理解不随 PR 提交,就是盲盒评审
- 3. 规矩三:任务外的顺手行,零容忍
- 4. 给 AI 的打回评论,和人写的不是一种东西
- 5. 打回的能力,是有保质期的
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看, 传送门https://blog.csdn.net/qq_34419312
前言
最近干了一件以前想都不敢想的事:把 AI 写的 PR 打回去了。而且是越打越勤,打得我都有点职业病了——现在看到diff的第一反应不是「看看写了啥」,而是「这次又在哪儿埋了雷」。
先说清楚,我不是嫌它写得差。论速度论整洁度,它吊打我。以前我吭哧吭哧一天能写三百行,现在它一分钟三百行,我除了鼓掌就只能怀疑人生:到底谁才是那个该被优化的?
问题出在评审标准上。拿人写代码的老标准去评机器写的代码,就像用谈恋爱的标准去给相亲对象打分——他确实温柔体贴会做饭,但你要的是能一起还房贷的队友,维度根本对不上。
我把现在的处置标准压成了 3 条规矩,先全部摆出来:
| 规矩 | 触发条件 | 处置 |
|---|---|---|
| 1 | 三态不齐(loading / error / empty) | 直接打回,不商量 |
| 2 | AI 的需求理解没随 PR 提交 | 打回,先补材料 |
| 3 | diff 里混进任务外的「顺手改动」 | 打回,越权行零容忍 |
第 1 条争议最大,因为它明摆着是双标。往下看我的理由。
1. 规矩一:三态不齐,直接打回
AI 生成的前端代码有一种天然的迷惑性:看起来对。UI 能点,数据能显示,演示的时候网络刚好也好。它默认产出 happy path,不是它笨,是你给的上下文里只有 happy path。
说人话就是:AI 的代码只活在「一切顺利」的世界里。网络好、数据有、用户不急,它就觉得天下太平了。别人写代码是面向对象,它写代码是面向 happy path。它以为的世界叫岁月静好,真实的世界叫接口 502。
一个典型的 AI 产出,数据列表组件:
function OrderList() { const { data } = useQuery({ queryKey: ['orders'], queryFn: fetchOrders, }); return ( <ul> {data.map((o) => ( <li key={o.id}>¥{o.amount.toFixed(2)}</li> ))} </ul> ); }演示的时候毫无问题。但 React Query 在请求成功之前data是undefined,接口一抖动,这行data.map直接白屏;接口报错,用户看到的还是白屏,一条提示都没有。
你品品这个画面:用户打开页面,白屏。刷新,白屏。再刷新,还是白屏。他以为是网络问题,重启路由器,回来还是白屏。最后发现是你代码的问题,他只能对着屏幕缓缓打出一个问号。用户体验的不是产品,是一场无声的默剧。
打回标准很具体:三态补齐才算完成。
function OrderList() { const { data, isLoading, isError, refetch } = useQuery({ queryKey: ['orders'], queryFn: fetchOrders, }); if (isLoading) return <Skeleton rows={3} />; if (isError) return <ErrorState onRetry={refetch} />; if (data.length === 0) return <EmptyState />; return ( <ul> {data.map((o) => ( <li key={o.id}>¥{o.amount.toFixed(2)}</li> ))} </ul> ); }这条被质疑得最多,理由很整齐:人写的组件三态不齐的时候,你怎么就留个 comment 提醒一下,合了?
对,就是双标。我的理由:打回人的代码,对方一下午白干,还搭一次不愉快的沟通;打回 AI 的代码,它重跑三分钟。这个动作变便宜了,标准还停在原地,那才是浪费。
再翻译一下:人写的代码被打回,对方要消化情绪、请你喝奶茶、连夜改完还得附赠一个「辛苦啦」的表情包;AI 写的代码被打回,它只会默默重跑,连个委屈的表情都没有。这便宜不占白不占。
顺着这个逻辑还有个推论:AI 的 PR 我要求得比人更严,反正它改起来不心疼。它不心疼,我也不心疼,只有电费在心疼。
2. 规矩二:理解不随 PR 提交,就是盲盒评审
规矩二管的是另一件事:AI 对需求的理解,代码倒是其次。它以为的「列表要分页」和产品说的「列表要分页」,中间可能隔着一万个默认值。
所以任务描述必须贴进 PR。看不到它以为什么是需求,这 PR 就没法评,你评的是盲盒——打开之前,你根本不知道里面是隐藏款还是雷款。
我现在的 PR 描述固定三段:
## 需求原文 (产品的话原样贴,不改写、不翻译成技术语言) ## AI 的计划 (agent 的 plan 输出原样贴,含它打算动的文件清单) ## 我纠正过的理解 (它哪条理解错了、我改成了什么,这段是评审最该看的)第三段最值钱。Claude Code、Codex 这类 agent 都有计划模式,先让它列方案再动手,那份计划输出就是现成的评审材料,比从 diff 里反推它当时在想什么省事得多。
评审动作也跟着变了。以前逐行看代码猜意图,现在先看「它的理解」和「需求原文」差多少,再决定代码细看到什么程度。理解全对的,代码扫一眼结构就行;理解跑偏的,diff 再漂亮也白搭。就像相亲,照片再好看,三观对不上也是白搭。
3. 规矩三:任务外的顺手行,零容忍
AI 修一个按钮对齐,能顺手把半个目录按 prettier 重排一遍,删两个它判定没人用的导出,再把某个依赖悄悄升个小版本。
人干这种事叫顺手,机器干这种事叫越权。人会为自己的顺手负责,机器不会:它不记得自己顺手改过什么,等下次出问题排查的时候,这些混在任务 diff 里的无关行全是噪音。AI 的顺手,是薛定谔的顺手——你永远不知道它这次到底顺手动了啥。
识别方法很机械:diff 的文件清单和任务对不上,就有越权。比如一个「修复按钮文案对齐」的 PR 里出现这个:
--- a/package.json +++ b/package.json @@ - "react": "^18.3.1", + "react": "^19.0.0"不用看第二眼,打回。格式化噪音和依赖版本好认,难的是「删了没人用的导出」:前端项目里动态引用、字符串调用、被构建脚本扫的导出太多了,AI 的静态分析看不见这些。
规矩三是三条里最没有讨论空间的。规矩一你还可以吵吵双标合不合理,规矩三连吵的余地都没有。就像一个同事说帮你修个灯泡,修完你发现他把客厅重装修了,还顺手拆了承重墙,你除了报警还能干什么?
4. 给 AI 的打回评论,和人写的不是一种东西
打回之后怎么写评论,是我最近才想明白的环节。
给人写评审意见,重点是把 why 讲清楚,因为人需要被说服;给 AI 写,重点是把 what、边界、验收标准给足。它执行 what 的效率极高,领会 why 的能力很差——像极了只会执行需求、从不问为什么的新同事,但新同事至少还知道问一句,它连问都懒得问。
问题:OrderList 在加载中和请求失败时白屏 要求:补三态(骨架屏 / 错误态带重试 / 空列表态) 边界:只改 src/components/OrderList.jsx,不要动其他文件 验收:DevTools 里切 offline 刷新页面,不白屏四个字段里最值钱的是「边界」。不写边界,它修 OrderList 的时候顺手把整个 components 目录「优化」一遍,正好撞回规矩三。记住,你写的是打回评论,不是放它出笼的钥匙。
我自己用下来的体感:这种填空式的打回,一次返工就过的比例高了不少,比「这里有点问题你看看」管用。现在打回全是填这个,填得我快把模板刻进肌肉记忆了。
5. 打回的能力,是有保质期的
最后说个我的真实感受。
「看起来没问题就合」这件事有隐性成本。三个月后你可能就打不动它了,权限都在,但读不动了:它的产出速度早就超过你逐行确认的速度,等你只能扫一眼 diff 就点合并的时候,标准想立也立不住。
外面也差不多是这个方向。arXiv 今年有论文专门讨论 agent 时代的 code review 怎么重新设计,CodeRabbit 这种 AI 审 AI 的机器人快成开源项目的标配了。连 Anthropic 自己的研究都被拉到 Reddit 上吵了一圈:AI 辅助编码的效率提升没那么大,还可能影响开发者的能力。
评审这条流水线上,人还说了算的地方不多了,打回算一个。这是咱们手里为数不多的、还能对 AI 说「不」的按钮,且按且珍惜。
你们团队现在 AI 生成的 PR,过评审用的是和人同一套标准吗?规矩一这种「该不该双标」,我站更严这边。你呢?
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看,传送门https://blog.csdn.net/qq_34419312