我亲手训练了一个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

相关文章
|
4天前
|
人工智能 JSON 测试技术
保姆级教程:从零手搓一个 Agent Skill,让AI变成你的专属助手
本文详解AI工程化新范式——Agent Skill:将隐性经验封装为可复用、可复现、可进化的标准化流程。通过实战手搓邮件Skill,揭示其三层渐进加载机制与落地路径,助你告别低效对话,迈向流程驱动的AI协作新时代。
|
21小时前
|
存储 监控 对象存储
基于YOLO11的道路积水视觉检测:从数据集构建到云上训练实践
本文介绍基于YOLO11的道路积水视觉检测实践,涵盖数据集构建(5275张图片、7155个标注框)、云上训练部署及工程化落地要点,适用于城市内涝预警与智慧交通场景,助力开发者快速实现鲁棒、可复现的积水识别系统。(239字)
基于YOLO11的道路积水视觉检测:从数据集构建到云上训练实践
|
23小时前
|
存储 人工智能 关系型数据库
千问背后的记忆引擎:PolarDB-X Mem0
阿里云PolarDB-X分布式数据库,作为夸克与千问APP“长记忆”核心底座,支撑流量暴涨100倍、峰值20万TPS,具备海量弹性扩展、统一向量+结构化存储、强一致高可用及全球低延迟能力。其推出的全托管服务Mem0,一体化融合语义与业务记忆,降本50%,助力AI实现长期、安全、有温度的连续交互。
44 0
千问背后的记忆引擎:PolarDB-X Mem0
|
22小时前
|
弹性计算 运维 监控
阿里云国际站服务器:遭遇UDP Flood攻击怎么办?
UDP Flood 不像应用层攻击那样需要精巧的漏洞利用,它是靠“蛮力”把带宽和 CPU 资源吃满。很多团队开始关注阿里云服务器 UDP 攻击防护配置,并不是因为想提前加固,而是服务器已经卡死才回头补课——这种顺序本身就很要命。
|
6天前
|
人工智能 自然语言处理 数据可视化
TID质量竞争大会分享议题丨从暗箱到透镜:AI Agent 评测与可观测性,正在成为智能研发的关键底座
中兴通讯AI技术教练刘振凯将分享《从暗箱到透镜》,揭秘SpecDrivenDev下AI工程化落地核心:构建“评测—评审—观测—回流”全链路闭环,实现AI研发质量可测、过程可视、问题可溯、系统可优。
|
19小时前
|
人工智能 算法 测试技术
独家揭秘:拼多多测试团队如何用AI把回归时间从3天压到2小时
拼多多测试团队借AI重构回归流程:代码提交即启动智能分析,精准筛选高风险用例,将大促前回归从3天压缩至2小时内,告别通宵等待——瓶颈不在执行速度,而在决策智能。
|
22小时前
|
物联网 中间件 BI
RFID + 资产管理系统:让“人找资产”变成“资产找人”
本文通俗解析RFID如何补足资产管理系统“账实不符”短板:相比条码需逐个扫描,RFID可批量远距识别,实现快速盘点、出入管控、全生命周期追踪与机房巡检。详解无源/有源标签选型、中间件数据打通及金属环境等落地避坑要点,助非技术人员轻松理解落地逻辑。(239字)
|
23小时前
|
人工智能 安全 数据挖掘
2026企业级Agent产品推荐:深度解析企业级Agent平台有哪些
2026年,企业级AI的竞争焦点已从单一的大模型技术转向智能体(Agent)的实战落地。面对如何将AI从“对话玩具”升级为能自主规划、执行复杂任务的“数字员工”这一核心挑战,市场涌现出多种解决方案。本文将聚焦于瓴羊推出的企业级Agent平台——AgentOne,深度解析其如何作为统一调度中枢,通过整合营销、客服、数据分析等五大核心场景,打通企业数据与业务流,构建起一个从意图识别到自动执行的全链路智能闭环,为企业智能化转型提供了一条可落地的路径。
|
23小时前
|
云安全 监控 安全
阿里云国际站:网站被CC攻击访问缓慢?WAF与DDoS防护联动配置教程
网站响应慢、频繁抛出502错误,查了半天日志发现既不是代码缺陷也非带宽跑满,这种情况在阿里云用户中并不少见——多半是遭遇了隐蔽的应用层CC攻击。要想彻底解决,单靠某一款安全产品很难兜底,需要把WAF与DDoS高防联动起来。

热门文章

最新文章