
你有没有遇到过这种情况:让AI帮你改一段代码,明明要求很明确,"把这个过时的判断逻辑删掉,换成新的",结果它给你的答案是,把旧逻辑原封不动地留在那里,然后在外面套一层if-else,新逻辑塞进新的分支里,旧代码继续待着,一动没动。
代码能跑,测试能过,任务被标记为"已完成"。可你打开一看,这文件比之前更长了,逻辑分支更多了,那段本该被清理掉的老代码,还在那儿喘气。
这不是个例。2026年,一组来自加拿大女王大学的研究者做了一件挺较真的事:他们把市面上最顶尖的五个代码AI模型(包括GLM-4.6、GPT-5、Kimi-K2、Claude Opus-4.5和Salesforce SAGE)在SWE-bench Verified这个业界公认的编程能力测试集上的表现,重新扒了一遍。他们不看这些模型有没有"通过测试",而是死磕一个更狭窄却更本质的问题:当任务要求删代码的时候,模型到底删没删?
结果挺让人意外的。**即便是那些被测试判定为"完全解决问题"的任务,模型依然平均留下了28.3%到34.8%该删的代码**。这些模型不是找不到该删的地方,它们能定位到92%以上正确的文件,能改到68%到74%正确的函数或模块里,可最后真正把那一行代码删掉的比例,只有44.6%到51.6%。
研究者给这个现象起了个名字,叫"删除规避"(deletion avoidance),意思是模型系统性地倾向于保留那些一个正常修改本该移除的代码。这篇论文的标题起得挺有意思,"加代码是机器干的,删代码得靠人",听着像句玩笑话,但背后是一套相当扎实的实证研究。
这事儿有多普遍:五个顶级模型的"手下留情"
研究团队没有随便挑几个案例说事,而是做了一次相当系统的对照实验。
他们从SWE-bench Verified的500个任务里,筛出377个任务,这些任务的"标准答案"(也就是真实开发者提交的修复补丁)里至少删除了一行非测试Python代码,而且这行代码没有在同一个函数、类或模块内被重新加回去(如果加回去了,那就只是代码挪了个位置,不算真正的删除)。
**参照补丁**:研究中把开发者原始提交的修复方案叫做"参照补丁",用来作为衡量AI输出是否"该删的都删了"的基准,但并不代表这是唯一正确答案。
在这377个任务里,研究者又挑出254个"结果一致"的任务:197个是五个模型全部解决了的,57个是五个模型全部没解决的。为什么要这么筛?因为这样可以把"任务难度"这个变量控制住,五个模型面对的是完全相同的题目和相同的成败结果,唯一的区别就是它们各自怎么改的代码。
结果是这样的:即便是全部解决的197个任务,五个模型的"删除召回率"(也就是开发者删掉的代码里,模型也跟着删掉的比例)最高的是Opus-4.5,71.7%;最低的是Kimi-K2,65.2%。换句话说,就算测试全过了,还有接近三分之一该删的代码原地未动。
而在五个模型全部失败的57个任务里,这个删除召回率直接跌到19.8%到30.4%,统计检验显示这个差距非常显著(p值小于十的负八次方,效应量属于"大效应")。
这里有个细节值得琢磨:模型不是"没找到"要删的代码。数据显示,模型修改包含目标代码的文件的比例超过92%,修改到目标所在的函数/类/模块范围的比例是68.1%到74.4%,但真正删掉那一行的比例骤降到44.6%到51.6%。
这就好比你让一个人去仓库里清理过期的库存,他确实走到了那个货架前,甚至打开了那个箱子,但最后只是把箱子重新盖好放回原处,库存单上却写着"已清理"。如果只看"有没有走到货架前"这个指标,你会觉得任务完成得不错;但如果你真正在意的是"过期货物有没有被处理掉",这个指标就完全掩盖了问题。
模型在删除的地方做了什么:守卫式绕行(Guard-and-Go)
既然不是没找到,那模型在那个位置到底写了什么?
研究者用一个AI分类器(MiniMax-M2.7)去逐一分析每个任务里模型和开发者补丁的差异,给每一对"任务-模型"结果打上三个标签中的一个。
**Delete-and-Replace(删除并替换)**:模型确实删掉或替换了开发者删除的大部分逻辑,这是理想状态。
**Guard-and-Go(守卫绕行)**:模型保留了开发者删除的逻辑,但在外面加了一层条件判断或旁路,让新逻辑走一条新路径,旧逻辑留在原地当"备胎"。
**Non-reference alternative(非参照式替代)**:模型走了完全不同的路子解决问题,没有遵循开发者的思路。
这个分类跑了2,358组有效数据(涵盖五个模型在几乎所有任务上的结果,不只是那254个一致任务)。结果显示,在1,703个"测试通过"的补丁里,有494个(29.0%)属于Guard-and-Go模式,也就是说,接近三成的"合格"补丁,其实是把该删的代码藏在了一个新加的条件分支背后,而不是真正清除掉。
论文开头那张图给出了一个非常直观的例子:开发者的补丁把`method = builtin_str(method)`这一行直接删掉,换成`method = to_native_string(method)`。而Opus-4.5生成的补丁呢?它保留了原来的`builtin_str(method)`,然后加了一个`if isinstance(method, bytes)`的判断,把新逻辑塞进`if`分支,旧逻辑挪到`else`分支里继续活着。两份代码跑同样的测试,都通过了,都被系统记录为"已解决"。
**这就是Guard-and-Go这个模式最典型的样子:该扔的东西没扔,而是给它搭了个新的通道绕过去。**
研究者接着对这684个Guard-and-Go案例做了更细致的人工编码分析,归纳出十种具体的结构形式,其中最常见的一种叫"保留路径作为存活兜底"(Retained Path as Live Fallback),占到了550个已分类案例里的40.2%,比排名第二到第四的形式加起来还多。这种模式下,新加的守卫只处理报告中提到的那个特殊场景,而开发者想删掉的那条逻辑,依然是所有其他输入情况下的默认执行路径。
打个比方,这就像一家餐厅接到投诉说某道菜的做法有问题,后厨的解决办法不是把旧配方扔掉换新的,而是专门为投诉的那桌客人开小灶做一份新菜,厨房里旧配方的锅继续用来伺候其他所有客人。表面上问题"解决"了,投诉那桌确实吃到了新菜,可绝大多数顾客吃到的还是老配方。如果不这么绕一圈,直接把旧配方从菜单上撤掉换成新的,厨房的复杂度会大幅下降,但风险是万一新配方有什么没考虑到的地方,所有客人都会受影响,而不是只有投诉那一桌。模型选择"绕道"而非"替换",某种程度上也是在规避这种全局性风险,代价是留下了一堆本该清理的旧逻辑。
这种行为带来的直接后果是补丁变得臃肿。数据显示,Guard-and-Go模式下的补丁比对应的开发者补丁体积更大的比例高达61.1%,体积中位数是开发者补丁的1.67倍。不同模型之间的差异也很大:GLM-4.6有97.8%的Guard-and-Go补丁比开发者版本大,Kimi-K2是81.5%,而Opus-4.5只有33.0%。
这呼应了此前一些独立观察:有维护者反馈,他们评审AI生成的拉取请求时,经常需要删除AI新加的方法,而且必须先完整读一遍才能判断能不能删(Watanabe et al. 2026)。还有一项针对METR的研究发现,296个已经通过SWE-bench测试的AI补丁,真正被项目维护者合并采纳的比例,比基准测试通过率低了24个百分点,理由是补丁太啰嗦,不符合项目代码风格(Whitfill et al. 2026)。
测试真的能测出"该删没删"吗?
到这里有个关键疑问冒出来了:既然测试都通过了,是不是说明保留旧逻辑也是一种"合法"的修复方式?
这是个公平的质疑。毕竟研究者对比的是模型补丁和开发者补丁的差异,而开发者的方案不见得是唯一正确答案,模型或许找到了另一条同样有效的路。
为了验证这一点,研究者做了个"倒逼"实验。他们从69个删除比例较高的Verified任务里,精挑出34个任务,给这些任务的测试套件加装了一种新型检测机制,叫"删除敏感检查"(deletion-sensitive check)。
**删除敏感检查**:一种专门设计的验证机制,如果本该被删掉的目标代码依然残留在最终代码里,这项检查就会直接判定失败,不管其他功能测试是否通过。
构建这套检查并不是拍脑袋决定的,研究者用了一套基于抽象语法树(AST)的方法,专门挑出那些删除了条件判断、控制流语句或完整代码块的"实质性删除目标",然后确保这个检查在原始代码(打补丁之前)上会失败,而在应用了开发者补丁之后会通过。这样才能保证这个检查确实是在验证"删除"这件事,而不是别的什么。
结果非常直接:研究者用四个当时最新的前沿模型(GPT-5.6 Sol、Opus 4.8、GLM-5.2、DeepSeek-V4-Pro)重新生成了136次尝试,其中86次(63.2%)通过了原始测试套件,但加上删除敏感检查之后,只剩57次(41.9%)还能通过,整体下降了21.3个百分点。也就是说,在原本被判定"合格"的86次尝试里,有29次(33.7%)其实保留了那个明明该被清除的目标代码。
四个模型全都出现了下滑,幅度从17.6到23.5个百分点不等(具体数据见下表)。
| 模型 | 原始测试通过率 | 加入删除检查后通过率 | 下降幅度 |
|------|------|------|------|
| GPT-5.6 Sol | 61.8% | 44.1% | 17.6pp |
| Opus 4.8 | 61.8% | 41.2% | 20.6pp |
| GLM-5.2 | 76.5% | 52.9% | 23.5pp |
| DeepSeek-V4-Pro | 52.9% | 29.4% | 23.5pp |
| **整体** | **63.2%** | **41.9%** | **21.3pp** |
这个实验说明的问题很清楚:传统测试套件主要是检验"功能对不对",而不是"该删的删了没有"。这两者不是一回事,一个补丁可以功能上完全正确,同时保留一堆本不该存在的僵尸代码。这就好比体检报告只查你的血压心跳,却不检查你身体里有没有该切除的良性肿瘤,只要生命体征正常,报告就写"健康",但那个瘤子还在那儿长着。
不过研究者也很坦诚地指出了这个实验的局限:这34个任务是按"删除密集型"筛选出来的,不能代表SWE-bench Verified全部任务的情况;而且这个删除检查的判定标准来自开发者补丁,不能完全排除"保留目标代码也是一种合理修复"的可能性。
CanItDelete:把删除这件事单独拎出来考
前面两部分实验有个共同的模糊地带:在真实的代码修复任务里,"该不该删"这件事往往和"该怎么定位""该加什么新逻辑"混在一起。如果模型删除失败,到底是因为它压根没想到要删,还是因为它没找对位置,还是因为它一边删一边还要写新代码分了心?
为了把这些干扰因素彻底剥离,研究团队构建了一个全新的评测集,叫**CanItDelete**。
这个基准测试集的设计思路特别干脆:200个任务,全部从真实的GitHub提交记录里挖出来,每一个任务唯一需要做的事情就是删除代码,不涉及任何新增或替换。也就是说,如果一个模型在这上面表现不好,那问题就完完全全出在"删除"这个动作本身,没有别的地方可以甩锅。
具体怎么构建的?研究者从Python和JavaScript生态里各选了100个最受欢迎、仍在活跃维护的开源仓库,从中挖出79,074次"只删不加"的文件修改记录。然后按照一套结构复杂度指标(综合考虑修改前文件长度、删除行数、删除的代码块数量)排序,挑出难度最高的200个任务。这200个任务横跨35个仓库,151个是Python,49个是JavaScript系,其中53个还涉及测试文件本身。每个任务至少涉及三处分散的删除位置,专门用来考验模型能不能"多点同时清理干净",而不是只处理简单的单行删除。
任务的指令是用GPT-5.6 Sol模型根据完整的修改前文件和真实差异生成的,生成之后还要过两道关卡:一道是AI质量审查,另一道是人工作者复核,确保指令覆盖了每一处该删的地方,并且光看修改前的文件和指令就能定位到所有该删的位置,不需要偷看答案。
评测方式也很讲究,用的是一套确定性的、能识别代码"出现次数"的自动评估器,完全不依赖AI来打分。只有当目标代码彻底消失、周边其他代码结构完好无损、没有引入任何影响行为的多余改动时,才算合格。把目标代码注释掉、禁用掉,都不算数;如果同一行代码在文件里出现了好几次,删掉其中一次不能替代对另一次的要求。
**结果非常扎心。**
十二个模型跑下来,表现最好的Claude Opus 4.8也只拿到79.0%的合规率,这意味着即便是当前最强的模型,面对"就是让你删代码,别的什么都不用管"这么单纯的任务,依然有五分之一会失败。排名第二的GPT-5.6 Sol是74.0%。
再往下看开源模型阵营,差距就更明显了。Kimi K2 Thinking、MiniMax-M3、GLM-5.2、DeepSeek-V4-Pro这几个表现最好的开源模型,聚集在65.0%到67.0%这个区间,比前沿闭源模型低了大约12个百分点。而Qwen系列的指令模型和更早期的MiniMax版本,表现直接跌到18.0%到47.5%,失败原因几乎都是"该删的没删干净"。
这200个任务的区分度也很强:有9个任务是十二个模型全部做对了的,有19个任务是全部做错的,中间每一档都有分布,说明这套题目确实起到了难度筛选的作用,不是随便挑几个简单题就能糊弄过去的。
失败的原因大体分成两类。第一类叫"删除不完整"(incomplete deletion),就是该删的地方没删干净,这是十二个模型里十个的主要失败原因,占到全部失败案例的69.8%。第二类是"完全删除但编辑有误"(complete deletion, invalid edit),模型确实把目标删掉了,但顺手删多了或者改到了不该改的地方,GPT-5.6 Sol和GLM-5.2就属于这一类。
**有意思的是,这两种失败模式之间存在此消彼长的关系。**
沿着GPT系列模型的演进轨迹看,"删除不完整"的案例数量从114降到20,而"完全删除但编辑有误"的案例却从14上升到32。Qwen系列也表现出同样的交换关系,只是整体水平更低。只有MiniMax-M3同时降低了两种失败率。
这说明单纯看一个总的通过率,是没法判断模型到底是进步了还是只是把一种错误换成了另一种错误。这就像考核一个搬家工人,你只看"东西有没有全部搬完"这一个指标是不够的,因为他可能确实把所有东西都搬完了,却顺手把不该动的家具也拆了。你得同时看"该搬的搬没搬"和"不该动的动没动"这两个维度,才能判断这个工人是真的干得好,还是只是换了个偷懒的方式。
给模型划出精确边界之后,问题解决了吗?
既然模型总是删不干净或者删过头,研究者接下来做了个层层递进的实验,叫**诊断阶梯(diagnostic ladder)**,一步步给模型更多提示信息,看到底哪个环节缺失才是问题的根源。
四个累积模式依次是:第一层是"vanilla"(原始版本),就是普通的开发者式请求,不给任何额外提示;第二层加上"explicit deletion"(明确删除指令),明确要求"完全移除,禁止用守卫、注释、禁用分支等任何变通手法";第三层加上"region pointer"(区域指针),告诉模型相关的函数、方法或区域范围,但不透露具体删除边界;第四层给出"exact lines"(精确行号),直接标出需要删除的具体代码段,并要求所有未标记的文本原样保留。
这套阶梯设计的逻辑很清楚:每往上加一层信息,就是在排除一种可能的失败原因。如果模型在"明确删除指令"这一层表现明显改善,说明它之前是没理解要"真删"而不是"绕过去";如果在"区域指针"这层改善明显,说明它之前是没找对地方;如果只有给了"精确行号"才有改善,说明前面几层的信息模型其实都能理解,真正缺的是精准执行边界的能力。
结果显示,前两层信号几乎没什么用。加上"明确删除指令"之后,五个模型的成功率变化幅度只有正负2.5个百分点。区域指针稍微有点效果,能带来0到7个百分点的提升,GLM-5.2受益最大。
**只有当研究者直接给出精确的删除行号,所有五个模型的表现才出现实质性提升,幅度在6.5到31.5个百分点之间。**
给了精确行号之后,四个模型的"删除不完整"比例降到了0.6%到3.0%,几乎被消灭。但Qwen3-235B依然有17.5%的任务在被明确告知具体删哪几行之后,还是没删干净,这是删除规避这个现象最直白的证明:哪怕把答案摆在你眼前,有些模型依然不肯完整执行。
不过更耐人寻味的是另一个现象:当"删除不完整"的问题被压制住之后,一个新的问题冒出来了,叫"过度删除"。GPT-5.6 Sol给了精确行号之后,"完全删除但编辑有误"的比例几乎没变化,从16.0%微升到16.5%;而Qwen3-235B这个比例反而从20.5%上升到26.0%,恰好和它的"删除不完整"比例下降形成镜像关系。
即便是表现最好的Claude Opus 4.8,给了精确行号之后能达到97.7%,但依然不是100%,剩下的1.7%失败案例是删过头了,还有一小部分是完全没变化。
这套阶梯实验揭示了一个挺重要的结论:**模型缺的不是能力,而是控制力。**
这就好比一个学开车的新手,你光跟他说"注意安全"没用,他该压线还是压线;你告诉他"前面路口要小心",他也许能提前减速,但具体在哪里刹车、刹多重,他还是拿捏不准;只有当你精确告诉他"在第三根电线杆处开始刹车,踩到底盘感觉减速的位置松开",他才能做对。可即便如此,有的新手会刹车刹早了(过度删除),有的会刹晚了(删除不完整)。给出精确指令能大幅提升准确率,但没法让每个人都做到完美,因为这本质上考验的是执行的精准度,而不是理解能力。
训练能不能治好这个毛病?
如果删除规避是模型"学不会",那基本没救了;但如果只是"训练时没被充分强化",那就还有希望。研究团队做了一个概念验证性质的小实验,来检验这个假设。
他们选用了一个70亿参数规模的内部模型(选这个尺寸是因为同系列更大的模型正在支撑他们工业场景里的实际编程工作流)。在这个模型原本的代码后训练数据集(总共159亿个token)里,额外加入了12,821个专门针对删除任务的训练样本,包括10,000个文件级别的编辑样例和2,821个仓库级别的修复样例。这些新增数据只占总训练token量的0.7%,也就是1.121亿个token。
两个版本的模型用完全相同的训练配方(六轮训练,全局批次大小64,128个xPU芯片),唯一的区别就是有没有这0.7%的删除专项数据。
结果是这样的:在CanItDelete测试集上,基线模型的成功率是6.5%,加了删除训练数据之后提升到13.7%,几乎翻倍;"删除不完整"的失败比例从80.4%降到66.5%,下降了13.9个百分点。
不过这13.9个百分点的改善并不是全部转化成了成功,其中7.2个百分点变成了合格的编辑,另外6.7个百分点变成了"完全删除但编辑有误",过度删除的比例还单独上升了6.2个百分点。这再次印证了前面的发现:训练让模型更愿意去执行删除这个动作了,但还没教会它精确地停在该停的地方。
更值得关注的是这个改善能不能"外溢"到其他任务上。研究者同时测了三个跟删除训练数据完全无关的基准测试:SWE-bench Verified(真实仓库修复任务)、CanItEdit和EditBench(指令式代码编辑任务)。结果显示,SWE-bench Verified的成绩提升了5.3个百分点,CanItEdit提升了1.40个百分点,而EditBench几乎没变化(下降0.19个百分点,基本可以忽略)。
为什么SWE-bench Verified和CanItEdit能受益,EditBench却没有?研究者的解释是,SWE-bench Verified里有377个任务(占500个总任务的大部分)本身就需要至少一处代码删除,这和删除训练数据的内容高度相关;而EditBench这类纯指令编辑任务本身跟"删除"关系不大,自然收效甚微。这种"选择性受益"恰恰说明了改善确实来自删除能力本身的提升,而不是训练带来的某种泛泛的整体增强。
而且好消息是,这三个基准测试没有一个出现明显的性能倒退(降幅都不超过0.2个百分点),说明加入删除训练数据没有带来意料之外的副作用。
这就好比给一个只会做加法的学生,专门补习了减法,结果发现他不仅减法做得更好了,连带着应用题(需要同时用到加减法)的成绩也提高了,而纯粹考加法的题目成绩没有下降。这说明"减法能力"确实是他之前欠缺的一块拼图,一旦补上,拼图能拼得更完整了。
当然,研究者非常谨慎地强调,这只是单个70亿参数模型的一次概念验证实验,只跑了三次取平均值,没有报告方差,这个结论能不能在更大规模的模型上、在部署级别的场景里成立,还是一个开放问题。
这项研究到底想说明什么
把整篇论文串起来看,研究者想传达的核心信息是:**当前的AI编程模型存在一种系统性的行为偏差,倾向于用"加代码绕过去"来代替"删代码",而这种行为在标准的功能测试下基本是隐形的。**
这不是某一个模型的个别问题,五个不同厂商、不同架构的顶级模型全都表现出这种倾向。这也不是因为模型能力不够,当给出精确删除范围之后,大部分模型都能大幅改善,说明这更像是一种"没被充分训练"的行为模式,而不是能力上限。
这个发现之所以重要,是因为它直接关系到AI生成代码的可维护性。论文开头提到的那组数据挺扎心:在一个包含6.23亿次代码变更的大规模统计里,清理或更新超过一年未改动代码的操作比例,在2023年之后下降了74%,而带有"错误屏蔽"特征的代码结构反而上升了47%(GitClear 2026)。这和论文里发现的Guard-and-Go模式高度吻合,都是"该清理的不清理,靠加新分支糊弄过去"。
如果这种趋势持续下去,代码库会像从不断舍离的房间,东西越堆越多,每次"整理"都是在旧杂物上面再摞一层新的,而不是真的把旧的扔出去。短期内看起来功能都正常,但长期的维护成本会越滚越大。
写在后面
读完这篇论文,最让我意外的一个细节,是那个"过度删除"和"删除不完整"此消彼长的现象。我原本以为,给模型越精确的指令,它的表现只会越来越好,不会有什么副作用。但数据摆在那儿,GPT-5.6 Sol在拿到精确行号之后,虽然几乎不再漏删了,但删过头的比例几乎纹丝不动,Qwen3-235B甚至更严重了。这说明"知道该删哪里"和"能精准停在边界"是两种完全不同的能力,前者靠信息补足就能解决,后者恐怕需要模型对代码结构有更细粒度的理解和更强的自我约束。
另一个值得琢磨的地方是,这项研究选择用"开发者的真实提交"作为参照标准,而不是用某种抽象的"正确性"定义。这个选择本身就很务实,因为它承认了软件工程里很多修复方案没有唯一解,但同时又通过大量的统计显著性检验、跨模型交叉验证,让这个不完美的参照系依然能得出站得住脚的结论。这种"带着局限性诚实地做研究"的态度,比强行追求一个完美无缺的评测标准要更有说服力。
如果删除能力真的只是训练数据里的一个薄弱环节,那么问题来了:未来的代码模型训练,是不是应该像教小孩收拾房间一样,专门设置一些"只许扔,不许留"的练习?这个思路听起来简单,但真正落地会遇到什么新的坑,恐怕还得看后续更大规模的实验。
Q&A
Q1:删除规避(deletion avoidance)具体指什么?
A:指AI模型在修改代码时系统性倾向于保留本该被删除的代码,常见表现是在旧代码外面套一层条件判断绕开它,而不是真正移除,这种行为被称为Guard-and-Go模式,占到测试通过补丁的29.0%。
Q2:为什么测试通过了还说明模型没删干净代码?
A:因为大多数测试只检查功能对不对,不检查该删的代码是否真的被清除。研究者给34个任务加装了专门的删除检测机制后,原本63.2%的测试通过率降到41.9%,说明近三成通过测试的补丁其实保留了该删除的目标代码。
Q3:给模型精确的删除位置就能完全解决问题吗?
A:不能完全解决。给出精确行号后,多数模型的漏删问题大幅改善,但有的模型开始出现删除过头或改到不该改的地方,即使表现最好的Claude Opus 4.8也仍有约2%的任务失败,说明精确定位和精准执行边界是两种不同能力。
好文章,需要你的鼓励
ARCHead是一种专门压缩大语言模型输出层的方法,通过量化低秩核心与激活度量修正,将LM-head存储压缩至BF16的约25%,质量损失极小。
这项研究发现AI投票推理在多答案问题上会系统性失效,提出用因果数学规则直接验证候选答案的CALVER方法,准确率比投票提升约11至19个百分点,且差距随尝试次数持续扩大。
这项来自港科大与腾讯视频的研究提出WorldCycle框架,通过可逆动作循环构造无标注自验证奖励,将视频世界模型的长程漂移误差降低最高44%,复合动作准确率提升约四倍。
哥本哈根大学团队构建了首个同时覆盖三种引用粒度、屏蔽信息泄露、包含全量段落候选库的法律信息检索数据集LegalPincite,用于评估法律判决段落精确检索任务。