AI测试人类工程师:代码评审逆向实验全解析

发布时间:2026/10/18 18:16:21
AI测试人类工程师:代码评审逆向实验全解析 一周之前我们内部开了一个有点“叛逆”的讨论会。话题是代码评审这么耗时如果让AI反过来评审人类工程师会是什么结果说“叛逆”是因为过去一年的注意力都放在怎么用AI测系统、测算法、测自动化流程“AI先生成代码、人类来审”已经不算新鲜事了。但“AI当测试员拿人类的代码、提交记录、技术方案来打分”这个反向操作我们还真没系统试过。于是就有了标题里那个脑洞当AI测试员开始测试人类工程师。这篇内容会完整复盘这个实验的思路、功能拆解、可复现的落地实现以及我们跑了两周之后踩到的坑和总结出的长期建议。适合正在做研发效能、效能度量、AI工程化或者单纯对代码评审自动化感兴趣的朋友参考。别急着把这套东西当考核工具它真正有价值的地方在于把很多不可量化的协作习惯变成了可回看的证据。1. 需求与设计思路先想清楚“能测什么”再动手1.1 为什么偏偏要反过来测先说背景。我们的研发团队大概有几十人有人写得很规范有人常年只改一个小文件。代码评审流程是有的但评审意见质量参差不齐有的Reviewer认真到逐行看有的评论连“lgtm”都嫌长。平时我们衡量代码质量要么靠人肉评审的主观感受要么靠覆盖率、复杂度这些静态指标。但覆盖率只能说明“哪些行被执行过”不能说明“这次改动到底有没有想清楚”。评审意见的数量也不代表评审效果就好。你会发现团队里谁靠谱、谁在摸鱼大家心里都有数但拿不出数据也没法反推到底是哪一步习惯出了问题。所以我们试着把“AI测试”的概念还回去以前是我们给AI一堆测试用例看AI能不能通过现在反过来让AI去看人类的开发交付物从代码、提交记录、PR描述、Review响应、方案文档里找到行为模式。理论上这个思路能补上三个缺口第一它把“软素质”变成了可观察的“硬指标”因为commit和PR本身就是行为留下的痕迹第二它比人工评审的覆盖面广可以做到每个提交都过一遍第三在流程规范很重的团队里它可以当第二双眼睛提醒那些连自己都没注意到的坏习惯。1.2 方案选型为什么自己搭而不是买现成的刚开始有人提议直接买现成的代码质量管理工具装上去跑一轮就能出报表。但我们调研下来发现几个问题。现成工具通常只盯静态代码也就是圈复杂度、重复率、bug模式这些。它们根本不看提交信息是否清晰也不会判断你的PR描述有没有把改动动机讲明白。就算有些平台自带了“AI评审助手”大多也是锚定某个固定模型没法让我们自定义“测什么、权重多少”。我们需要的是一件足够“薄”的工具能让规则自己定能插进现有Git工作流结果要能解释为什么给这个分。最终选择是“开源静态分析工具 大语言模型接口 自写的打分逻辑”拼装起来。静态工具负责算硬指标大语言模型负责做语义判断自写脚本负责汇总和展示。这样性能可控、可解释性强而且想加一条规则不用等厂商更新。1.3 先定义清楚AI测的是人还是人留下的东西这个点特别重要。我们一开始也纠结过是不是在“给人打分”。后来达成一个共识AI不测人的态度和能力AI只测“交付物与协作痕迹”。也就是说它评价的是那行代码、那条提交信息、那个方案文档而不是“这个人技术水平差”。这个定位决定了整个系统的设计边界——它不能做主观断言只能说“从这些可观察到的特征来看这次变更存在哪些风险”。确定这个大方向后整个项目被拆成了四个维度代码质量维、提交行为维、技术决策维、协作时效维。每个维度背后都有对应的数据源不会为了指标去凭空造数据。这就是我们在整个项目里反复提醒自己的第一原则可测的前提是在仓库里留得下痕迹。2. 核心功能拆解AI到底在测哪几件事2.1 代码质量维从圈复杂度到魔法数字代码质量维是最好实现的因为它已经有成熟的静态分析生态。我们先用开源工具把基础指标跑出来包括每个文件的环形复杂度、函数行数、重复率、未使用变量数量等等。但光有这些还不够。真正看出水平的是那些“味道”型问题。举个例子我们会用脚本扫描PR里新增的代码然后标注是否有超过100行的函数、是否有连续超过5层的if嵌套、是否有同名同逻辑代码块被复制粘贴到不同文件。这些不直接影响功能正确性但直接影响后续维护成本。这一层还要注意一个细节不能只测“新增代码”要连同被改动的上下文一起看。有些老模块本来就是历史债务高发区新改动只是在一堆烂代码里加了一行。如果只看新增行AI会误判成“这个人写了烂代码”所以我们规定被测的最小单位是“diff涉及的块”而不是“全量仓库”。2.2 提交行为维看得见的协作素质这一维度是最有趣的部分。它不看你代码写得好不好而是看你怎么把一个开发过程包装成别人能看懂的内容。我们定义了几条硬规则。提交信息少于10个字的一律降权比如“fix”、 “bug”、 “改bug”这种等于没写PR描述必须包含“背景”和“改动点”两个部分且背景不能只是“见标题”Review意见如果超过3条必须看到开发者后续的回复或代码修正动作否则判定为“意见未闭环”。为什么拿这些当指标因为它和我们后面要做的自动化变更记录管理高度相关。提交信息、PR描述这类东西平时写的时候觉得多花了10分钟但真到大版本发布、接新同事、系统出问题回溯时它们就是唯一的路标。我个人的感受是一个能花30秒把提交理由写清楚的人大概率也会在架构设计时把边界想清楚。这两件事在习惯上是同构的。2.3 技术决策维让AI去评方案文档这个维度是实验里最受争议的但产出也最有价值。我们的做法是把技术方案文档交给大语言模型按几个固定问题打分是否写清楚了要解决什么问题是否列出了2个以上的备选方案并说明取舍是否考虑了数据一致性和兼容性风险是否定义了回滚或退出机制每项0到5分并要求模型给出依据比如“第2.3节提到了备选方案但没有量化对比”。这里有个很实际的教训如果你让AI“自由点评”它会写出一堆正确的废话比如“建议加强性能测试”这种谁都会说但毫无指向性的内容。但如果你把维度限定成“从文档中找证据”它的价值立刻不一样了。AI不会创造文档里没有的信息但能很犀利地识别出“这段写得很泛、那种说法等于没说”。所以技术决策维的核心不是“AI替你做判断”而是“AI帮你发现判断依据是否充分”。它更像一个严格的读者专门挑那些你想含糊带过的部分。2.4 协作时效维隐藏的团队氛围指标第四个维度我们花了不少功夫去定义。很多团队有隐性问题代码写得不错但review响应能拖一周PR在深夜零点提交连续好几周只改非核心文件展示面很好看但实际产出很少。这些点很容易被传统指标忽略却对团队真实效率影响很大。我们把它定义为“协作时效与投入分布”包括首次响应review的平均时长从PR发起到合并的周期一个时间窗口内活跃提交的文件分布是否集中在核心模块提交时间戳的分布是否健康。但特别提醒一点这个维度只适合做整体趋势观测不适合给个人下结论。比如有人就是习惯深夜写代码不代表他效率低有人一周只改一个配置文件可能是因为他在负责攻坚一个跨部门需求commit看起来少实际压力不小。所以这个维度在我们系统里权重最低只产生观察结果不直接参与最终评分。3. 实操过程与核心环节实现我们是怎么搭出来的3.1 第一步把git提交历史变成结构化数据要想让AI分析先得有干净的数据。我们写了一个简单的数据采集脚本用git log把提交历史导出成结构化行。git log --dateiso --prettyformat:{commit:%H,author:%an,date:%ad,msg:%s} --since2025-01-01这条命令会把最近几个月的提交信息逐条输出成JSON格式每条记录包含commit哈希、作者和提交信息。接下来用Python按空格分割把每一个字段读进内存。import subprocess import json from datetime import datetime def load_git_log(): raw subprocess.check_output([ git, log, --since2025-01-01, --prettyformat:%H|%an|%ad|%s ]).decode(utf-8) rows [] for line in raw.splitlines(): parts line.split(|, 3) if len(parts) 4: continue rows.append({ commit: parts[0], author: parts[1], date: parts[2], subject: parts[3] }) return rows这个脚本很简陋但够用。我们把它跑在每天凌晨增量拉取新提交存到一个表里。后面所有分析和展示都基于这张表不做实时扫描节省成本也方便结果复现。3.2 第二步静态分析层先把硬指标算出来静态分析我们分两层第一层用现成工具扫出lint和复杂度指标比如ESLint、SonarQube这类第二层是自写的“坏味道扫描器”专门抓我们自定义的规则。举一个实际落地的规则例子。我们要检测一个PR中是否有超过120行的新函数最简单的方式是用文本扫描。import re def detect_long_functions(diff_text, max_lines120): issues [] func_pattern re.compile( r^\s*(def|function|public\s[A-Za-z0-9_]\s\w)\s*\( ) current_func None func_start 0 for i, line in enumerate(diff_text.splitlines(), start1): if func_pattern.match(line): current_func line.strip() func_start i elif current_func and { in line: # 简化处理统计大括号配平后的行数 func_end i if func_end - func_start max_lines: issues.append({ line: func_start, func: current_func, length: func_end - func_start }) current_func None return issues这段代码用于读取diff文本遇到函数定义的行就记下来再遇到第一个非空的大括号结束行就统计跨度。真实项目里需要考虑更复杂的解析规则但思路不变与其让大语言模型去数行数不如用确定性的脚本算好准确又省token。这类指标我们称为“硬指标”全部走正则和AST解析不依赖模型输出。3.3 第三步大语言模型做语义评分硬指标算完之后语义层才是重头戏。我们让大语言模型读“看起来像人能读懂的信息”而不是把整个代码库塞给它。具体做法是把一次PR的信息精简成四块提交信息、变更文件列表、diff摘要、以及人类review的评论内容。然后把它们拼成一个结构化Prompt。你是一名严谨的技术评审专家。请根据以下信息评估开发者本次提交的质量。 【提交信息】 {subject} 【变更文件】 {files} 【变更摘要】 {diff_summary} 【相关评审意见】 {review_comments} 请从三个维度评分每个维度0到5分只输出JSON 1. 变更可读性提交信息与代码意图是否清晰 2. 描述充分性能否看出为什么做这次修改 3. 风险把控是否有明显遗漏的边界情况 同时给出4句以内的中文解释说明低分的具体原因。这里有个技术小细节我们不让模型直接看整段diff而是先用脚本抽取“变更统计摘要”比如“新增文件3个修改文件5个新增代码统计约180行删除约30行涉及数据库session初始化逻辑”。这样既保留了关键信息又避开了token限制和不必要的噪声。输出结果我们固定成JSON结构方便直接入库。温度参数调的尽量低固定写死在0.2保证同一份输入每次打分不会差太多。模型不稳定是这个方案最容易翻车的点后面会在问题排查部分细说。3.4 第四步汇总打分输出一眼能看懂的报告最终打分的展示页面没什么特别的我们用了一张简单的表格来呈现。前面提到的所有指标分成四个组每组推荐权重也标在表里。维度核心指标推荐权重数据来源代码质量复杂度、重复率、坏味道数40%diff扫描静态工具提交行为提交信息清晰度、PR描述结构25%git logPR字段技术决策方案文档覆盖度、风险说明20%评审文档LLM协作时效响应时长、变更周期、是否闭环15%提交与review时间戳整体分数我们会转成一个0到100的百分制每个维度内部再按规则加权。展示的时候不只给一个总分还会列出“本次提交中建议关注以下风险点”这样的具体条目。这一点很重要——工程师看完只会说“凭什么给我60分”但如果他看到“你的PR描述缺少背景说明且涉及数据库字段变更但未评估存量数据兼容性”他就认了。反馈必须足够具体否则这个工具还没到考核环节就会先死在信任危机上。4. 常见问题与排查技巧实录看起来在测人其实在测沉淀4.1 AI误判拿“历史债务”当成“当前指标”这是我们刚跑一周就遇到的第一个严重问题。有些老模块早就烂成一团圈复杂度奔着60去了一位新同学只是在里面新加了一个方法调用结果整个文件的复杂度指标一起崩他的评分直接被带低。排查后发现静态分析工具的指标是按“文件全量”计算的而不是按“本次变更片段”计算的。修正方法是把复杂度的计算范围改成“本次diff新增和修改的代码块”并且要求扫描器先确认哪些行是本次变更引入。我们做了一个简单的处理把本次提交涉及的旧代码行先标记为“历史债务”不参与个人评分只留档到“代码维护风险清单”。这样评分不冤枉人那些老代码也仍然会被关注。4.2 模型输出不稳定同一份PR两次打分不同AI测评系统最怕的是不信服。有同事发现自己在周一和周三各收到一次评估分数竟然差了一整档。查下来发现是模型默认参数不一样周一时我们用的温度是0.7后来改成了0.2但没跑全量重测系统里混着两套输出逻辑。处理办法有三点第一所有调用统一固定temperature、max_tokens等参数并记录版本号第二对语义评分做三次采样取中位数只要有一次结果偏差过大就自动重跑第三每份结果的数据库记录里写入模型版本和参数哈希方便事后溯源。这样再出现争议可以直接定位到“这版模型对这类文本本身就不稳定”而不是被归结为系统黑盒。4.3 刷分和反套路人类开始对付AI了大概第二周开始个别同事已经摸清了评分规则。他们会把提交信息写得特别详细哪怕是只改了一个变量名也写两百字背景会把一个大PR拆成七八个小PR制造出一种“高产出高效闭环”的假象有人会故意在PR描述里写上“已评估风险”但细看内容全是套话。这其实是所有指标体系的通病。我的处理意见是不要把所有权重都压在显式文本上。加入内容一致性校验比如检查commit描述里提到的修改点和实际diff是否有强相关如果没有就视为“描述与内容不符”。同时定期人工盲抽个别PR做复核让AI和人类评审结果交叉验证。拆小PR的问题本质上不是刷分因为拆小之后逻辑确实更清晰了只是粒度不自然所以我们增加了“时间累计粒度”的观察如果一个人7天内PR数量超过某阈值该部分权重自动衰减。说到底刷分行为本身也是信息。它说明工程师认为这套指标是关注的。关键在于你的系统有没有能力识别“形式合规”和“实质靠谱”之间那条线。4.4 别忘了放一条“申诉通道”AI测试员跟人类测试有一个相同点都会出错。如果你不给被测对象申诉的机会系统一定会被抵制。我们在面板上给每条低分记录加了一个“申诉”按钮工程师可以提交一段说明比如“该文件为历史代码本次仅做重构原复杂度不属于本项目引入”。每一条申诉都会有评审组定期看如果申诉成立分数会被修正这条修正记录同时进入规则库让AI下次不再犯同类错误。这个机制跑下来我们很受用它把机器评分从“单方面判决”变成“可对话的反馈”。还有一个隐形红利申诉内容本身就是很好的训练数据。哪些场景容易误判、措辞怎么表述算作有效依据都能从这些记录里学出来。5. 让这套系统长期运行的三个建议5.1 把它定位成“提醒助手”不要直接挂钩绩效最核心的建议也是我们内部达成高度一致的一条这套AI测评结果初期绝对不能直接进绩效表。原因很简单现有的很多隐性因素AI还看不见比如跨团队沟通的摩擦、需求本身的复杂度差异、被临时拉去救火的次数。如果分数直接和绩效挂钩必然会催生大量刷分行为最终指标烂掉、信任崩掉。我们的用法是每周生成一份团队层面的趋势报告只看相比上周变化的分布不聚焦到个人。等模型稳定性、人群覆盖度都跑通至少两个迭代再考虑是不是要引入到低权重的人力流程中。5.2 反馈信息要做到“具体可执行”而不是“评判对错”工程师最反感的一句话是“综合素质偏低”。这种话没有任何信息量只会激起防御心理。AI测评的输出表述我建议统一成“在这次PR中检测到风险点X、Y、Z其中X可能导致问题AY的原因是B。”它要说清楚检测到的现象、可能的后果以及建议的下一步动作。这听起来很简单但真正执行下来会发现很多统计工具的输出都停在了“你错了”那一层完全没到“你可以怎么做”那一层。5.3 持续用人类评审结果校准AI标准AI打分准不准不能只让它自己说了算。我们每两周做一次校准会随机抽取若干份AI评分报告让有经验的工程师背靠背独立评分两边的差异超过一定阈值时就把样本拿出来讨论。讨论结论用来修正评分维度和Prompt里的提示语。目前我们已经迭代了三轮AI的评分逐渐接近一个稳定的分布但它永远不完美。这也是这个实验最有意思的地方AI试图去测人类但它对人类的理解依然需要人来纠正。微信扫一扫可打开此内容 使用完整服务我本来想做一个完美闭环现在发现漏洞正是AI和人的边界所在。这套系统本质上是把团队里习惯最好的一小部分工程师的行为特征变成了可观察的标尺然后让所有人都能看见这把标尺上的刻度。它会惹人生气会让你看到自己确实忽略过的细节也会让很多以前靠口头禅掩盖的问题显形。如果你也想做一个类似的实验我的建议是先从“提交信息清晰度”这一单项开始不要一上来就搞全维度大评分。给团队留一周适应期把申诉通道先打开无论结果多难看让它先跑起来。等到所有人都习惯了那句“建议你补充背景说明”之后再回头看看自己手里的那把尺子大概也会像我们一样发现AI和人之间那种互相校准的关系比任何单边测试都更有意思。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询