两名工程师对着一块写满依赖关系与取舍说明的白板逐段讲代码

一、把”没人读懂”从抱怨变成一个可检查命题

据公开报道,《灰犀牛》作者米歇尔·渥克提出过度依赖 AI 可能导致认知能力下降与健忘。这类说法涉及的是大脑,我们不碰;它指向的工程问题却很具体:一个团队里,合进主干的代码,能不能说清”有哪个人真的理解它”。

这件事过去靠默契,现在需要一个答案,因为代码的来源变了。以前默认提交者就是最懂那段代码的人,评审只是补充视角;现在一段实现可能在几分钟内出现,写它的人在屏幕前点了一下接受,却没有把它逐行读进自己的模型里。风险不是”代码质量差”——生成结果往往比平均水平更整洁——风险是知识没有落到任何人身上,而故障恰恰只找没有知识的那部分。

所以我们把”理解”当成一条可以验收的交付物,把”没人读懂”从抱怨改成能在流程里检查的项目。判据不能是”我看过一遍”,得是行为:能解释、能改、能定位故障、能在没有 AI 的情况下做出最小决策。

二、理解的五种可检查证据

我们的评审表上写死了五条,每条都有对应的验证动作,不靠自评。

  1. 第二人能指出关键取舍。 作者之外至少一个人能说出”这里为什么用轮询不用回调””这个阈值怎么定的””如果并发涨十倍会先垮在哪”。指出取舍是理解的唯一硬证据,复述代码逻辑不算。
  2. 能画出依赖与数据流。 一张手绘级别的图:这个模块被谁调用、写哪些表、发哪些消息、失败时把错误抛给谁。画不出来,说明只读了实现细节,没建立结构。
  3. 能在演练里定位到具体模块。 给一个模拟故障(慢查询、超时、队列堆积),要求只根据日志、指标与代码定位到函数级别,并给出验证方法。这是最像生产场景的一条,也是最容易暴露”只有作者懂”的一条。
  4. 能删掉冗余段而不破坏行为。 生成代码常见的产物是没人调用但看起来很完整的抽象。能判断”这段可以删、那段不能动”,才说明理解了边界。
  5. 能回答”为什么不用另一种做法”。 至少一个被否决的替代方案与否决理由。答不上来意味着选型是随机的,将来维护时会被无声推翻。

五条里做到三、四、五,我们对这段代码就有信心;只做到一、二,等于没有。

三、传统评审为什么在这批代码上失效

三个原因,都不是”评审制度不好”。

改动单元太大。 过去一个 PR 对应一个人几天的思考,评审天然被切成小块。现在一次提交可能包含一个完整功能,diff 上千行仍自称”只做了一件事”——因为”一件事”的定义从”一个人的思路”变成了”一个需求条目”。评审者面对千字级的陌生实现,注意力会自动退化成看命名、看格式、看有没有明显错误,这几项恰恰是 AI 做得最好的部分。

评审对象错配。 传统评审看的是 diff,而 diff 里不包含设计意图。意图在会话里——在和模型的往返对话中,在那些被放弃的方案里。会话不进版本库,于是评审者看到的是一份”结论”,没有任何”论证”。这不是评审者的能力问题,是信息根本没进入工程资产。

责任边界模糊。 提交者按”我审阅并接受了”承担责任,评审者按”我看过了”承担责任,两边都没错,但都不等于”我能维护它”。故障复盘时最典型的对话就是:提交者说”这段是生成的”,评审者说”我以为他懂”。

四、流程上的六个对策,以及它们的落地字段

对策 具体做法 检查方式
按意图拆小 PR 一个 PR 只承载一个可解释的意图,不以功能大小为单位;上限按评审者能在一次专注中读完的行数设 超限的 PR 需要评审者明确说明”我读不完”,而不是默认放行
PR 描述写”为什么” 固定四栏:背景与目标、关键取舍与被否决的方案、影响范围(数据、接口、下游)、验证方式与结果 缺”被否决的方案”一栏即视为未完成描述
模块负责人签字 用仓库的所有者配置指定模块负责人,负责人签的是”我能维护”,不是”我看过” 负责人不在状态时该 PR 走代签,代签人需在描述里说明如何建立理解
AI 生成部分显式标注 标注生成范围,评审者额外说明用了什么方式检查(逐行读、跑测试、构造反例、只读接口) 检查方式必须是一种可复核的动作,不接受”确认无误”
上线前做一次去 AI 演练 关键路径上线前,负责人在纯文本编辑器与本地日志环境下完成一次故障定位与最小修复决策 演练记录(场景、耗时、是否成功)随发布单归档
关键决策写进架构决策记录 凡是”以后别人一定会问为什么”的选择,落成简短记录:背景、决定、后果、替代方案 每季度抽查:随机挑一份记录,让非作者解释并复述后果

六条里”去 AI 演练”最容易被嫌麻烦,但它的性价比最高:一次演练暴露的理解缺口,通常比十次评审评论更实在。执行时要限定环境,只允许读代码、看日志、用调试器,不允许把报错原样丢给模型。这条约束本身不神秘,它只是把”我真的知道”和”我知道去哪里问”区分开。

五、风险分级:哪些改动必须两个人真的懂

全部代码要求双人理解不现实,会把流程压垮。我们按”错误的后果是否可逆、影响面是否跨边界”分级,五类改动必须有第二人独立理解并签字:涉及资金与计费的计算与对账路径;涉及身份、权限与凭据的判断逻辑;数据迁移、批量删除与结构变更;定时任务、批处理与幂等设计——它们的失败往往在无人值守时发生;并发、锁与共享状态路径,这类代码的缺陷不会在评审时以可读的形式出现。

反过来,展示层的排版、文案、内部工具的样式,用轻量抽查即可。分级的价值在于把稀缺的”第二个大脑”投到不可逆的地方,同时避免整个团队被评审拖慢之后,大家开始形式化地走流程——流程一旦形式化,理解度检查就同时失效了。

六、度量要谨慎,新人上手是同一道题

理解度可以观察,但不能变成 KPI。一旦把它做成”评审覆盖率””阅读时长””签字率”这类指标,它们会在两周内被刷满:点批准只需要一次点击。可参考的是滞后指标,不是过程指标——故障复盘里”该改动是否有人能解释”的比例、一次演练中从告警到定位的耗时中位数、模块负责人变更后的缺陷率变化。这三个数不需要人人可比,只在趋势上看,才有意义。洹拓科技内部还有一条规矩:这些数字不进入个人绩效,只进入流程改进的议题,否则团队会立刻学会怎样把它们做得好看。

新人和招聘场景里是同一道题,只是更敏感。我们的做法是把入职练习设计成”提交之后还要讲一次”:完成一个小改动后,画一次依赖、解释一处取舍、然后给一段带缺陷的既有实现(可以是生成的)请他指出问题并说明判断依据。这里评的不是人的聪明程度,而是一件具体工作的验收:他能不能在没有模型代劳的情况下,对一段代码做出可辩护的判断。带教者只需要问三个固定的问题——这段代码被谁调用、这里为什么这么写、如果它出故障你会先看哪条日志。三问答完,理解边界在哪儿很清楚。

说到底,AI 没有改变软件工程的一条基本判断:系统的可靠性取决于团队里可共享的理解总量,而不是产出的代码量。把”有没有人懂”变成能检查的行为,比争论工具好不好用有用得多。