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

简介: 两周前,我用历史缺陷数据训练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

相关文章
|
23天前
|
人工智能 算法 测试技术
独家揭秘:拼多多测试团队如何用AI把回归时间从3天压到2小时
拼多多测试团队借AI重构回归流程:代码提交即启动智能分析,精准筛选高风险用例,将大促前回归从3天压缩至2小时内,告别通宵等待——瓶颈不在执行速度,而在决策智能。
|
22天前
|
人工智能 JSON 测试技术
不会写代码也能做自动化测试?Skill + AI 帮你搞定重复性工作
本文介绍一种“零代码”自动化测试新范式:无需编程基础,测试人员只需整理接口文档、操作步骤和判断标准,借助AI+Skill(一个含SKILL.md的文件夹),即可自动生成可运行的Python测试脚本或Postman集合。实测将2.5小时手工回归压缩至48秒,真正让测试经验一键转化为生产力。
|
20天前
|
人工智能 运维 BI
QoderWork + QoderWake 实战:AI 数字员工的企业级落地与效率革命
企业办公中大量重复性工作正在吞噬团队的创造力。QoderWork CN 作为桌面 AI 办公助手,本地运行、自主规划、安全可控,内置丰富 Skill 覆盖文案写作、幻灯片制作、浏览器自动化等场景;QoderWake CN 作为数字员工平台,全天在线、支持企业私域知识库与自定义扩展。本文从运营团队的实际痛点出发,完整拆解 QoderWork + QoderWake 的企业级落地路径,包含四大典型场景的实战配置、五个真实踩坑案例,以及从试点到推广的完整 SOP。
|
23天前
|
域名解析 存储 弹性计算
海宝云-阿里云服务器续费太贵?这有一份不同机型降配与省钱方案的“榨干”测评!
本文由阿里云官方服务商海宝云撰写,直击云服务器续费痛点:新客低价、老客高价。详解三大省钱策略——“续费降配”“跨代降配”“数据迁移”,辅以节省计划、停机模式等隐藏技巧,并提醒缩容、IP变更、共享型风险等避坑要点,助你合法合规砍掉50%~80%续费成本。
|
28天前
|
人工智能 弹性计算 API
Hermes Agent 安装接入阿里云百炼教程:按量 / Coding Plan/Token Plan 三种配置方案
Hermes Agent 是一款开源终端AI编程工具,支持按量计费、Coding Plan 或 Token Plan 团队版三种方式接入阿里云百炼大模型,具备自主规划、多工具调用与持续进化能力,开箱即用。阿里云Hermes官方部署教程:https://t.aliyun.com/U/EfvSK0
|
19天前
|
人工智能 缓存 JavaScript
当AI学会自己“探索性测试”,纯手工点点点的QA还能活多久?
本文探讨AI时代测试工程师的生存危机与转型机遇:当AI不仅能生成用例,更能自主探索、发现未知缺陷,手工测试正被“绕过”而非简单替代。文章剖析AI探索性测试的三层架构、真实效能对比,并指出测试人的新定位——从执行者转向策略设计者与AI教练。核心能力不再是“点点点”,而是定义风险、校准AI、沉淀测试知识。
|
23天前
|
存储 监控 对象存储
基于YOLO11的道路积水视觉检测:从数据集构建到云上训练实践
本文介绍基于YOLO11的道路积水视觉检测实践,涵盖数据集构建(5275张图片、7155个标注框)、云上训练部署及工程化落地要点,适用于城市内涝预警与智慧交通场景,助力开发者快速实现鲁棒、可复现的积水识别系统。(239字)
基于YOLO11的道路积水视觉检测:从数据集构建到云上训练实践
|
2月前
|
算法 搜索推荐 黑灰产治理
小红书负面下拉词删除实战方法与技巧
小红书搜索下拉词负面频现?实为“搜索+内容互动”双驱动结果!本文揭秘负面生成三大推手(踩雷笔记、集中搜索、负面评论),并分享小马互动实战验证的“三阶删除法”:精准诊断类型、分类施策(投诉举证/正面覆盖/主动澄清)、长效监测防护,助品牌将下拉框变种草入口。(239字)
|
2月前
|
人工智能 小程序 安全
个人全栈开发实战 依靠口述编程完成外包小程序项目
作为独立全栈开发者,我以“口述需求→AI生成→迭代优化”为日常核心工作流。TRAE凭借98%代码准确率、多模型切换、免费永久使用及优秀中文理解能力,完美适配小程序与后端外包开发,显著提升30%+效率,大幅降低单人全栈交付门槛。(239字)
|
23天前
|
人工智能 弹性计算 API
【AI 尝鲜实验室】上新 | New API:一个入口打通全网大模型的统一网关
New API 是 QuantumNous 开源的下一代大模型网关与 AI 资产管理系统(GitHub 42k+ Stars,AGPL-3.0 协议)。它将 OpenAI、Claude、Gemini、DeepSeek、通义 Qwen、Midjourney、Suno 等全网主流大模型聚合到一个统一的 OpenAI 兼容接口,内置多渠道分组、加权随机分发、失败自动重试、完整的用户/令牌/额度管理和在线充值能力。 本次实验通过阿里云计算巢一键部署 New API 到云端,几分钟即可拥有一套专属大模型网关。部署完成后你可以在后台集中管理所有模型渠道、给团队成员分发独立令牌和额度,并通过格式互转让 Cl
323 2