我亲手训练了一个AI来测Bug,结果它发现了CTO十年前留下的“屎山”

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 两周前,我用历史缺陷数据训练AI“闻”代码坏味道,首次扫描便揪出一段CTO十年前写的高风险对账函数——硬编码、浮点误差容忍、无测试覆盖,却在线上隐匿十年。它不替代人工,而是揭示被遗忘的“未知未知”,让技术债务无可遁形。

这事过去两周了,我还是没缓过来。

起因是我在团队里搞了个小实验——用历史缺陷数据训练一个模型,让它学会“闻”代码里的坏味道。目标很简单,提交代码前自动扫一遍,标出高风险区域,省得每次靠人肉眼 review 那些陈年代码。

训练数据用的是我们仓库过去五年的缺陷记录和对应的代码提交。模型本身不复杂,一套基于代码 AST 的向量化表示加上一个缺陷倾向性分类器,跑了几轮交叉验证,准确率还不错。

有意思的事情发生在第一次全库扫描的时候。

它在一个没人敢动的模块里,标记了一个极高风险函数。模块是订单对账的核心,代码注释里写着“2009/03/15 老张”。那个函数逻辑极其扭曲:各种硬编码的魔数、嵌套五层的 if-else、还有一段明显是反着写的金额比较。模型给它的风险评分是 0.97,而我们人工标注过的已知缺陷区最高才 0.82。

我把这段代码摘出来,找了一个在公司待了 13 年的架构师看。他盯着屏幕沉默了两分钟,然后说了一句让我后背发凉的话:“这是当年 CTO 写的。那时候公司刚起步,对账老差 1 分钱,他半夜临时糊上的。”

这段代码在线上跑了十年,从未被改过。不是因为没问题,是因为没人敢碰,也没人在回归测试里覆盖到它的异常分支。

AI 把它揪出来了。

目录

为什么我想训练一个“闻Bug”的AI
屎山是怎么形成的:CTO留下的时光胶囊
训练过程:让AI学会闻代码的“味道”
模型发现的不止一个Bug,是一类反模式
如果没有AI,这类Bug能藏多久
这件事改变了我对测试的认知
你也可以训练一个,不需要大模型
为什么我想训练一个“闻Bug”的AI
我们团队的自动化用例覆盖率早过了 85%,线上事故却没见少。复盘时发现一个规律:真正造成线上问题的,不是新功能逻辑,而是改老代码时触发的隐藏副作用。那些十年前的代码,没人记得当初的上下文,单元测试要么没有要么写的假,回归用例又不可能把每行代码的每个分支都跑一遍。

人工 review 面对这种代码其实也无力。reviewer 的注意力会被新业务逻辑吸引,老模块的改动只要编译过、看起来不突兀,大概率直接放行。

我就在想:有没有办法让机器把全仓库扫一遍,专门找出那些“看起来就像会出Bug”的代码?

这个想法的核心假设是:缺陷不是均匀分布的,它们会聚集在某些特定模式的代码里。 如果能让模型学会识别这些模式,我们就能在代码合入前精准预警。

屎山是怎么形成的:CTO留下的时光胶囊
模型标出的那个高风险函数,场景是这样的:对账系统需要比对内部订单金额和外部支付渠道的回调金额,在分账场景下,要把总金额按比例拆给多个商家。

正常写法是:总金额先转成 int(分),按比例乘除,最后再转回元。但这函数用了一堆浮点数直接做加减,末尾还用了一个魔数 0.001 做误差容忍。更诡异的是,有一行判断写了 if (Math.abs(diff) > 0.001 && diff < 0)。第一眼看过去,这个条件永远为 false,因为 diff 大于 0.001 就不可能是负数。但仔细看上下文才发现,他在前面把 diff 取了一次反,这行判断其实是生效的——以一种极度扭曲的方式。

当年的背景是:支付渠道回调金额偶尔会有浮点尾差,导致对账报错,技术团队排查了很久没找到根因。CTO 为了保上线,半夜写了这个容忍逻辑,硬把误差吃掉了。

这段代码的问题不在于逻辑错误,而在于它的“隐蔽正确性”。 它在当前数据下恰好正确,但只要上游金额计算的精度规则稍有变化,这个 0.001 的硬编码就会产生真正的对账差异。而且没有任何测试用例能发现它,因为异常分支的触发条件被浮点误差掩盖了。

训练过程:让AI学会闻代码的“味道”
说回模型本身。它的目标不是理解业务逻辑,而是学习“缺陷倾向模式”。我把这个模式拆成了三个维度。

第一个维度是代码结构复杂度。圈复杂度、嵌套深度、函数长度这些硬指标是基础,但更关键的是“修改频次与缺陷的关联”。一个函数如果改 10 次有 7 次伴随缺陷修复,那它的结构大概率有问题。

第二个维度是代码克隆率。如果一段代码是通过复制粘贴产生的,并且在不同模块里有轻微变体,它的缺陷概率会显著上升。因为当初的 bug 很可能也被复制了,只是还没暴露。

第三个维度是注释与代码的一致性。我用了一个小模型来比对函数注释和实际实现。注释说“计算退款金额”,实际代码里却有扣减积分的逻辑,这种不一致是高危信号。

训练数据是过去五年里 4300 多个缺陷修复的 commit,提取出每次修复前的“坏代码”和修复后的“好代码”,做成成对样本。模型结构就是 CodeBERT 做 backbone,后面接一个二分类头,输入是函数的 AST 序列化表示,输出是 0 到 1 的风险分。

验证集上做到 0.79 的 precision 和 0.83 的 recall。不算惊艳,但作为辅助筛查工具足够了。

模型发现的不止一个Bug,是一类反模式
CTO 那坨代码被标出来之后,我顺着模型的高分结果继续排查,发现它不止找出一个具体问题。它实际上标记出了一类反复出现的反模式:“带误差容忍的浮点金额计算”。

全仓库一共扫出 14 处类似模式,分布在对账、结算、优惠券分摊、运费计算四个模块里。其中 3 处已经暴过线上问题并被修复,剩下的 11 处里,有 5 处在特定条件下可以重现计算偏差。虽然大部分偏差在 1 分钱以内,但叠加高频业务场景后,部分月份的对账差异能累积到几百元。

这类问题靠人工 review 几乎不可能全揪出来。因为它分散在多个模块,每个单独看都像是正常的容错处理,只有拉通全局才知道这是一个系统性的设计缺陷。

一个缺陷是事故,一组同模式缺陷就是架构负债。

如果没有AI,这类Bug能藏多久
CTO 那段代码藏了十年。不是没有测试,而是所有测试都在验证“正常情况下对账金额正确”,没有任何一个用例去验证“误差容忍的边界值”。因为当年写用例的人根本不知道有这个容忍逻辑——它写死在代码里,没有在需求文档里出现,也没有在接口说明里暴露。

这种“代码里偷偷做了容错”的情况,在老旧系统里其实很常见。开发人员为了解决一个紧急问题,在底层做了兜底,但没告诉任何人。测试人员按照接口文档写用例,永远触达不到那个分支。代码就这么安安静静地躺在线上,成了一个定时炸弹。

AI 能把它找出来,靠的不是聪明,而是“不挑食”。它不会因为这段代码在核心模块就不敢报,也不会因为注释写着“临时”就放松警惕。它会平等地扫描每一行代码,用数据训练出的嗅觉做判断。

这件事改变了我对测试的认知
以前我认为测试的价值在于“验证”,确认系统做了该做的事。现在我觉得测试的更大价值在于“发现未知”——找到那些连开发者自己都忘了的隐藏逻辑和假设。

传统测试依赖一个前提:需求明确,预期清晰。但老旧系统的真实状态是:代码即需求,行为即文档。当你面对十万行无人维护的代码,谁也不知道它真正在做什么的时候,用例覆盖率的数字是骗人的。

AI 在这件事上的优势是,它不需要理解业务就能发现异常。它把“未知的未知”转化成“已知的未知”,然后人再去判断这个未知是不是风险。这可能是 AI 测试最被低估的价值。

不是用 AI 替代人写用例,而是用 AI 做人做不到的全量扫描。

你也可以训练一个,不需要大模型
这个方案的门槛没有想象的高。核心三件套:Git 历史、缺陷记录、一个轻量级代码模型。

我用的 CodeBERT 是开源的,一张消费级显卡就能跑推理,训练用 colab 的免费 GPU 也能搞定。真正的工程量在数据清洗上——你需要从 Git 历史里把“缺陷修复”的 commit 挑出来,和对应的“缺陷引入” commit 配对。这一步可以用 SZZ 算法自动标注,准确率 70% 左右,再加人工抽样校验就够了。

如果你不想训模型,还有更简单的路径:用现有 code embedding 工具把仓库所有函数向量化,再用已知缺陷函数做相似度检索。这个方法虽然粗暴,但对于找出“复制粘贴型缺陷”特别有效。

不管用什么技术路径,核心逻辑是一样的:让数据说话,让模式显形。

你现在维护的系统里,有没有那种“没人敢动、动就出事”的代码区域?你有没有想过,里面可能也藏着一颗十年前埋下的雷?

本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。

image.png

相关文章
|
6天前
|
缓存 人工智能 安全
GPT-5.6 Terra与GPT-5.5性能实测:成本减半后的跑分对比与快速迁移指南
GPT-5.6 Terra 的定价为每百万 token 输入 2.50/输出 15。GPT-5.5 则是 5/ 30。Terra 的每一项费率,包括 $0.25/M 的缓存读取,都恰好是 GPT-5.5 的一半,因此在任何工作负载组合下,Terra 都固定 便宜 2.0x。以每天 10 万次请求、3K token 提示词计算,大约是 Terra 每天 2,000,GPT−5.5每天 4,000,即每月约 60,000对 120,000。问题在于:OpenAI 没有发布任何针对 Terra 的编码基准。那个著名的 91.9% Terminal-Bench 数字是 Sol 在 Ul
|
2天前
|
数据采集 机器学习/深度学习 人工智能
田间杂草定位与检测4200张YOLO智慧农业数据集分享
本数据集含4200张真实农田图像,YOLO格式,单类别(杂草)高质量标注,覆盖多作物、多光照、多生长阶段等复杂场景,专为智慧农业杂草检测与智能除草设备研发设计,支持YOLOv5/v8/v10等主流模型训练。
328 93
|
3天前
|
缓存 UED 开发者
Codex109天重置23次,明天还要再送一次
Codex近109天完成23次额度重置,7月14日将迎来第24次。Tibo高频响应用户反馈:优化GPT-5.6高消耗问题、补发失效福利、调整重置时间——形成“反馈→回应→修复→补偿”正向闭环,彰显以用户为中心的产品哲学。(239字)
505 11
|
6天前
|
人工智能 缓存 JSON
刚刚 GPT-5.6 发布,吊打 Claude 5 和 Grok 4.5?一手实测来啦!
GPT-5.6 刚发布,跑分号称超越 Fable 5,真的假的?附一手实测,让 3 个最强 AI 编程模型 GPT-5.6 Sol、Claude Fable 5、Grok 4.5 在 Cursor 里同时一把梭开发网页游戏,看看最新模型到底谁更能打。
341 0
|
6天前
|
存储 人工智能 JSON
Qwen 本地部署搭配 ComfyUI 生成 AI 漫剧完整实操指南(小白零基础可落地,零成本无限生成+角色一致性天花板)
2026全网最优本地漫剧流水线:零成本、离线运行、角色统一、低配(8G显卡)可跑。融合Qwen本地大模型+ComfyUI双引擎,实现剧本生成→分镜绘图→动态成片全自动,隐私安全、无审核限流,新手30分钟上手,日更无忧。(239字)