从人工到自动化:用 LLM 筛选值得复盘的 CR 评论

初稿于 2024 年发表于公司内网,2026 年对外重写

好评论淹没在全量评论里

团队这几年一直在建设 Code Review 文化,其中一个具体动作是定期复盘:把有价值的 CR 评论整理出来,在团队里过一遍——哪些评论拦下了真实缺陷,哪些指出了设计问题,哪些把一个人的经验变成了大家都能用的知识。复盘做得好,CR 会从「流程要求」慢慢变成工程师真正在意的事。

麻烦出在筛选这一步。评论总量很大,其中绝大多数是「笔误」「命名再斟酌一下」这类日常沟通,值得拿出来复盘的只占很小的比例。原来的做法是安排人从全量评论里手工筛,问题有两个:一是量大,筛选的人负担很重;二是判断标准不稳定,不同的人筛出来的结果差异明显,同一个人筛到后面,标准也会慢慢漂移。

2024 年我们和 QA 团队合作改造了这个流程,改成「AI 初筛 + 人工复核」,我负责其中 AI 初筛部分的优化。

先把命名说清楚。这个项目统一叫「优质 CR 评论筛选」,我们刻意避免叫它「AI Code Review」。后者通常指让模型直接审代码、产出评论;在这个项目里,评论全部由人写,AI 只做一件事:从海量人写的评论中,筛出值得团队复盘学习的那一部分。两者的技术难度和风险完全是两码事。

整体思路:AI 初筛,人工复核

流程设计很直接:AI 先把明显没有复盘价值的评论过滤掉,再把剩下的候选按价值高低排序;人工只复核头部候选,从中挑出最终进入复盘材料的条目。

选排序而非只做二分类,是给复核的人留操作空间:按顺序往下看,看到候选质量明显下降就可以停,复核量能按当期的时间预算灵活伸缩。

这个分工背后有一个判断:筛选类任务对两类错误的容忍度是不对称的。错杀——好评论被排到靠后——有人工复核兜底,只要头部候选能覆盖住大多数好评论就够用;漏杀——个别好评论没进候选集——代价也可控,复盘本来就是选例子讲道理,漏掉几条不致命。两头都有余量,AI 不需要达到人类专家的判断水平,就已经可以开始创造价值。

效果提升最大的一项:把上下文组织成对话

最早的版本,输入基本就是评论文本本身,效果一般。原因不难理解:单看一句「这里建议再确认一下边界条件」,谁也判断不出它背后是一次真实的缺陷拦截,还是一句客套。

一条 CR 评论从来都挂在具体的代码行上,前后有作者的回复,有修改前后的代码。这些信息合在一起,才构成判断价值的完整依据。整个优化过程中效果提升最大的一项改动,就是把这些上下文按「对话式」重新组织,让模型看到的输入接近一段有头有尾的叙事:

  • 这次修改的代码 diff 是什么,评论挂在哪几行上;
  • 评论者针对这段代码说了什么;
  • 作者如何回应,中间经过了几轮讨论;
  • 代码最终改没改、怎么改的。

同样的信息量,组织成「谁在什么代码上说了什么、对方如何回应、最后发生了什么」的结构,效果比把评论、代码、回复碎片式地拼在一起好得多。这条经验后来在其他 AI 功能上被反复验证:模型对结构化叙事的理解,远好于碎片拼贴。

把「有价值」写成可执行的标准

另一块投入是提示词调优。「有价值」三个字,每个人的理解都不一样,直接丢给模型,得到的只会是模型自己的理解。我们把判断标准明确写成三条:

  • 拦截了真实缺陷:评论指出的问题如果不修,会变成线上问题;
  • 指出了设计问题:接口设计、模块边界、可扩展性这类超出单行代码的意见;
  • 传播了可复用的知识:评论讲清楚了一个别人不知道、以后用得上的机制或约定。

每条标准都配了正例和反例。反例的作用是把标准的边界画清楚——什么样的评论看起来认真、实际不值得复盘——比单纯给定义更能约束模型的判断。

工程化:把调优变成有数据集支撑的流程

调优的过程本身也值得一写。最早的迭代方式是纯手工的:改一版提示词,往对话框里粘几条评论看看效果,感觉不错就再换几条试试。这种方式有两个致命问题:样本太少,结论不可信;改动之间没有可比性,调了几轮之后,说不清到底哪次改动真正有效。

为了摆脱手工反复粘贴,我们开发了一个调优工具(内部名 TTAIToolbox),把调优变成有数据集支撑的流程:

  • 数据集组织:把带人工标注的评论集固定下来,作为每次迭代的统一基准;
  • 可视化编排:筛选流程的各个环节编排成可视的流程图,单独调整某一环,不影响其余部分;
  • 批量执行:一次改动可以在全量数据集上跑完,直接看指标变化;
  • 组合对比:多个模型、多版提示词组成组合矩阵批量执行,横向对比效果。

有了这套工具,「感觉变好了」变成「在同一个数据集上效果变了多少」,迭代速度和结论的可信度都完全不同。

结果与复用

上线后的分工符合预期:AI 初筛过滤掉大部分明显无价值的评论,人工只复核头部候选集,筛选工作量减少约三分之二。判断标准写进了提示词,筛选结果也不再随筛选者的状态波动。

「数据集 + 批量执行 + 组合对比」这套做法,后来成了我们调优其他 AI 功能的默认方式。一个直接的例子是 AI 技术评审总结——用模型自动生成技术评审的总结——用同样的方法调优之后,单次耗时降到了原来的约三分之一。

筛选类任务是 LLM 的舒适区

最后是几点做完之后的体会。

筛选类任务对 LLM 格外友好,条件有三个:判断标准能用自然语言写清楚;错杀有人工复核兜底;漏杀的代价可控。三个条件同时满足时,模型不需要接近专家水平就能创造实际价值;缺任何一个,方案都要重新评估。拿这三条去检查手头的候选场景,比笼统地问「这个场景能不能用 AI」有用得多。

对自动化程度的预期同样重要。我们从一开始就只让模型做初筛,把人的工作量从「全量筛选」压到「头部复核」,没有指望它一步到位替代人。这类改造阻力小、见效快:复核的人立刻感到轻松,最终决定权还在人手上,也没有人担心 AI 把关不严。事后看,这个定位上的克制,比任何一项具体的技术优化都更接近这个项目能做成的原因。