AI 趋势下的 review 代码想法
背景
过去一年半,我断断续续在做 Python 代码的 review,被 review 的对象背景各不相同:
- 没有任何编程经验、入行不到一年的新人
- 有五年以上其他语言经验,但从没写过 Python 的工程师
- 有一到三年编程经验、刚开始接触 Python 初级选手
这一年多下来,有很多感受,其中有一点:AI 写的代码越来越多,但人对代码的理解并没有同步跟上。一直想写点什么,但是又忙东忙西,终于觉得要挤点时间,把几个印象深刻的案例整理出来,也顺便说说自己的看法。
5个我经历的案例
案例一:不知道自己引入了什么
技术债:引入新的技术,需要去学习,减少因为不懂原理、功能放手 AI 实现而导致埋雷的可能
在”Python + pytest + 其他(省略)”的测试框架里,A 新增了两个 pytest 内置钩子函数 pytest_runtest_report,两个函数实现一模一样,分别放在不同的目录下。结果不仅导致用例在内部平台上执行报错,还大面积影响了其他业务团队的测试任务分发和执行。
A 有至少一年的编程经验,代码是让 AI 直接生成的。周五下班前发起合并请求,由另一名有合并权限、但不太熟悉 Python 和当前框架的 B 通过了。小小的一个错误,影响面却出奇地大,平台侧的同事在周末排查了将近半天。
事后跟 A 聊,他坦言根本不知道 pytest_runtest_report 是干什么的,也没想到会有这么大的影响。事实上,pytest 根本不支持 pytest_runtest_report,实际 pytest 支持的、相似的是 pytest_runtest_makereport。
案例二:代码是 AI 的,不是我的
AI 不可能知道用户的所有上下文,大部分 agent 的上下文都是有限的。
同一个部门里,A 和 B 经常有相似的功能需求。在 AI 辅助下,两个人各写各的,互相不关心对方实现了什么,就连公共函数也是分别让 AI 生成一份。慢慢地,代码库里开始出现大量重复逻辑,有些相似度超过 90%。
更麻烦的是,时间一长,连他们自己都不记得当初 AI 生成了什么。出了问题,根本没有人能说清楚那段代码的来龙去脉。
AI 生成的风格也比较杂,一会儿这个语言的习惯,一会儿那个语言的写法,前后不一致。比如用 _xx 表示保护成员,但在另一处又把这些属性直接导出给外部模块用——自己打自己脸,但 AI 不在意这些,它只是在”完成任务”。
随着业务扩张、代码量越来越大,AI 能掌控的全局视野越来越有限,最终还是得靠人来收拾局面。
案例三:AI 喜欢把简单事情搞复杂
AI 喜欢过度设计、复杂化。
刚入行的新人提交的代码里,时常能看到一堆明显是 AI 生成的冗余内容。
明明两三行能搞定的逻辑,非要包一大段异常捕获,看起来很严谨,实际上有些分支永远不会走到。AI 不懂什么叫简洁,它只是在机械地拼接自己见过的代码片段。
另一个常见现象是 AI 下意识地追求”可扩展性”——哪怕这个功能以后根本不可能扩展。代码里时常出现 from __future__ import annotations,或者新建一堆自定义异常类,看起来很”高级”,但大部分场景下完全没有必要。
案例四:AI 给的方案,不一定是最好的
AI 输出的工具库、代码风格写法过时,已经有更好更优的主流方案,需要人主动提示 AI 才能生成。
同一个需求,问不同的 AI,可能会得到差距很大的答案。这不是 AI 在”判断哪个更好”,只是因为训练数据不同,输出的倾向性也不同。旧版本的资料在训练集里占比更高,AI 生成它的概率自然也更大。
举个实际工作里的例子:有两个 GitLab 服务器,一个新的,一个旧的(落后十多年的免费版)。需求是把旧服务上的项目迁移过来,同时保留提交记录,并且以后每次提交都要同步一份到旧服务器。
有些 AI 的答案是写个脚本来同步。但更强的 AI 告诉我可以直接用 GitLab 自带的 Mirroring Repositories 功能,一行脚本都不用写,完全解决问题。
这两个答案的差距,不在于谁”更聪明”,在于谁见过更多相关的资料。所以不能闭眼信 AI,还是得自己有判断。
案例五:review 的人也开始跟不上了
对 review 代码者的要求突增,可能面临看不懂、没见过的设计方式和代码写法的情况
AI 让提交代码的门槛降低了,但 review 代码的门槛反而提高了——因为你不知道对方用 AI 生成了什么风格、什么方式的实现。
举个常见例子:某次 review 时,看到有人用 dataclass 组织配置类,里面用到了 __post_init__。以前几乎没接触过这个,只知道 __init__,一时不知道 __post_init__ 是什么时候触发的,也就没法给提交者任何有效的反馈。
打个不太恰当的比方:就像一个领导没有相关专业背景,可能根本看不出下属做的东西究竟有没有问题、难度在哪、值不值得这么搞。
我的想法
应对措施
让 AI 反过来质疑我。 和 AI 交互时,不要只让它”给答案”,先让它质疑我的需求,说说它的困惑在哪。两边对齐了,再让它动手。必要的时候可以让它先复述一遍我的需求,确认理解没跑偏。这一步看着多余,实际上能省掉很多来回返工。
很多 Agent 有 Plan 和 Build 模式,在 Plan 模式下,和 AI 交互,对齐需求、确定目标和准备计划,在 Build 模式下一一实现具体需求。
不理解的东西,先弄懂再用。 特别是大型项目里,一处改动可能牵一发动全身。AI 给我生成了什么,我得知道它是干什么的、会影响什么。就好比 AK47 很好用,但也不能交给一个完全不懂枪的人随便扫射。
现在智驾虽然听着好,即使以后有一天高级到让不会开车人也能开。但如果要用智驾车接送某位重要人物,我肯定还是想找有实际开车经验的人掌控。
不要把控制权全交出去。 我见过有人说:反正当初 AI 写的,出了问题让 AI 改就行,管它影响怎样。这话听着像在开玩笑,但真有人是这么想的。一个产品如果全靠 AI 生成代码、没有人真正审查,出问题只是时间问题。代码合入前的 review,不能省。
小结
有了 LLMs 之后,我有时候会想,如果我是某个项目的负责人,底下人都在大量用 AI 生成代码,让人担心的不是代码质量本身,而是:
- 连自己提交了什么都说不清楚。生产出了问题,没人能定位,因为那段代码根本没人仔细看过。
- 明明有更简单的方案,结果用 AI 搞出一堆脆弱的脚本,看似高级、做了很多东西,维护成本反而更高。
- 整个团队渐渐失去对代码的掌控感。代码是跑起来了,但没人知道它为什么能跑,也没人知道它哪天会出什么问题。
AI 是很好的工具,确实提升了不少效率。但工具终归是工具,用的人得清楚自己在做什么。否则出了事,AI 不会负责,锅还是得人来背。
每次开会、线下交流时,领导问自己一个问题,大家都不想每次这样吧:我来问问 AI、等我马上搜一下。
最大的体会:有了 AI,更加需要学习了。