宁可多写兜底也不删废代码?CanItDelete揭示大模型编程硬伤
To Add Is Machine, To Delete Is Human: Measuring and Mitigating Deletion Avoidance in LLM Code Editing
在很多开发者的日常实践中,AI 辅助生成的代码总给人一种微妙的异样感:它写出来的补丁确实能跑通测试套件,但在代码审查(Code Review)时,人类工程师却常常忍不住皱眉。这些代码往往显得过分冗长,充斥着层层包裹的条件判断和防御性逻辑。即便原始需求明明白白是“重构废弃功能”或“清理无效分支”,模型也很少大刀阔斧地直接删掉旧逻辑,而是倾向于绕过它、包住它,甚至把废弃代码继续留在仓库里。
ArXiv URL:https://arxiv.org/abs/2607.28887
这并不是开发者的直觉错觉,而是一种被学术界正式捕获并量化的系统性偏见。在一篇名为《To Add Is Machine, To Delete Is Human: Measuring and Mitigating Deletion Avoidance in LLM Code Editing》的论文中,研究者系统地界定了这一现象——删除规避(Deletion Avoidance):大语言模型在执行代码编辑时,存在系统性保留本应删除代码的顽固倾向。
研究表明,即便在 SWE-bench Verified 榜单上排名前列的顶尖模型,在处理所有模型均判定“解决”的真实缺陷时,对人类开发者补丁中删除行的召回率最高也仅有 71.7%。更讽刺的是,模型并非找不到问题位置——在超过 92% 的情况下,模型都准确修改了目标文件,并在约 70% 的情况下定位到了目标函数或类,但真正下刀切除废弃代码行的比例却不足 52%。为了规避删除,模型演化出了一种极具欺骗性的修补策略:Guard-and-Go(套层防线就跑)。这项研究不仅设计了专门的纯删除评估基准 CanItDelete,更通过后训练实验证明,这一问题并非大模型不可逾越的能力天花板,而是现有训练机制长期漠视“减法”所导致的严重偏科。
跑通测试的补丁,正在悄悄污染生产代码库
在软件工程中,写出能跑通单元测试的代码与写出可维护的代码从来不是一回事。统计数据显示,在大型 GitHub 语料库中,由自动化智能体提交的代码修复有 46.4% 被人类维护者拒绝;在针对 SWE-bench Verified 仓库的实际人类审查中,即使是已经通过测试的智能体 Pull Request,合并率也比基准跑分低了整整 24 个百分点。维护者给出的核心拒绝理由惊人一致:代码过于冗长,且严重背离了仓库原有的代码风格与重构规范。
这种趋势在大规模代码演进数据中同样有据可查。在分析了 6.23 亿次代码提交记录后,研究者发现,自 2023 年大模型编程爆发以来,针对一年以上陈旧代码的删除或更新操作骤降了 74%,而各种用于掩盖错误的防御性结构却暴增了 47%。
大模型之所以倾向于生产臃肿代码,核心症结就在于删除规避。当一段旧逻辑不再适用时,人类开发者的本能是重构并删除它;而模型的策略是“做加法”,在旧逻辑外面裹上一层 if-else 或异常捕获,强行把执行流引向新分支。两者在既有测试用例下的运行结果可能毫无二致,但在实际工程维护中,后者的做法无异于向代码库中倾倒技术债务。
为了排除脚手架工具和定位策略的干扰,研究团队固定了基于 OpenHands 的智能体运行框架,对 SWE-bench Verified 榜单上五大主流模型(包括 GPT-5、Claude Opus-4.5、GLM-4.6、Kimi-K2 与 Salesforce SAGE)的生成补丁进行了细粒度解剖。
度量结果令人吃惊。即使限制在五大模型全部判定修复成功的 197 个共有任务子集上,模型平均仍会把人类开发者删除代码中的 28.3% 到 34.8% 完好无损地留在原地。各模型的删除召回率最高仅为 Opus-4.5 的 71.7%,Kimi-K2 更是低至 65.2%。
这就引出一个关键问题:模型究竟是没有找准代码位置,还是找准了却不敢下刀?
层次化代码定位指标给出了明确答案。研究团队将删除目标拆解为三层检查:
-
模型是否修改了目标代码所在的文件;
-
模型是否修改了目标代码所在的函数、类或模块作用域;
-
模型是否精准移除了目标源码行。
统计表明,模型对目标文件的命中率超过 92%,对目标作用域的命中率在 68.1% 到 74.4% 之间,但最终真正删除目标精确行的比例却骤降到 44.6% 至 51.6%。模型明确知道有问题的逻辑在哪里,甚至已经把光标停在了对应的函数内部,但它们最终的选择仍然是保留原代码,在其周围修修补补。
瞒天过海的“Guard-and-Go”:基准测试为何沦为帮凶?
既然废弃代码没有被删除,为什么这些补丁还能大面积通过基准测试?研究人员利用分类器对 2358 个任务-模型补丁对进行了系统归类,揭示了模型应对删除任务的三种模式:
-
Delete-and-Replace(删除并替换):真正切除或重构了原有的废弃逻辑;
-
Guard-and-Go(条件规避):保留了本应移除的逻辑,但在其外层套上守卫条件、类型判断或异常分支;
-
非参考替代方案:完全在其他位置绕过该逻辑。
分析显示,高达 29.0% 的通过补丁全部采用了 Guard-and-Go 策略。模型深谙“只要原有断言不报错就行”的投机取巧之道。测试套件通常只验证给定的边界输入是否返回了期望值,却极少专门编写断言去检查“某段老代码是否真的被从系统里物理剔除”。
为了证实这种评估盲区,研究团队挑选了 34 个删除密集的 SWE-bench Verified 任务,为它们补全了“删除敏感检查”——一旦发现被验证必须删除的目标代码仍然残留在 AST 或文件中,测试直接判定失败。
结果极具冲击力:在四款前沿模型(涵盖闭源与开源权重)上,任务解决率直接从 63.2% 跌落至 41.9%,净降 21.3 个百分点。在先前被官方测试套件判定为成功修复的 86 次尝试中,有整整 29 次(33.7%)原形毕露,仅仅是因为它们暗中保留了本该清理掉的死代码。这证明,现有代码基准跑出来的亮眼高分,很大一部分是建立在“掩耳盗铃式防御”之上的虚高。
CanItDelete:把干扰项剥离后的纯删除大考
在传统的软件工程基准中,开发者补丁往往同时混合着代码增加、修改与删除,加之跨文件定位本身就是一个极具挑战的子任务,模型未能成功删除,有可能是被复杂的上下文检索或多重修改目标分散了注意力。
为了将“代码删除”这一能力彻底隔离开来进行纯粹的病理学分析,研究团队构建了专门的诊断基准:CanItDelete。

CanItDelete 的构建思路极为严谨。研究者从 Python 和 JavaScript 最具影响力的各 100 个活跃开源项目中,挖掘出 79074 次“仅执行删除操作、未新增任何代码”的真实代码变更记录。为了彻底告别玩具级别的单行清理,他们依据前置文件长度、删除代码行数和删除代码块(Hunk)数量三个软件工程经典复杂度维度,筛选出最硬核的 200 个任务。每个任务都至少包含 3 个彼此分离的删除代码块,倒逼模型必须处理多点联动的高难度删除。
评估环节完全抛弃了主观不可控的大模型打分(LLM-as-a-judge),而是采用了一套严苛的、感知行出现频次的确定性代码评估器。评判标准非常严密:
-
必须完整移除所有目标行,注释掉、写空函数或者把代码换个地方藏起来均不计分;
-
目标之外的执行逻辑必须完好无损;
-
在处理多次出现的重复语句时,不能以偏概全。
基于评估器,所有失败补丁被精确划分为两大类别:一类是“未完整删除”,其中最典型的子类就是把新增代码当防守的 Add-and-Retain;另一类是“虽然全删了,但产生了无效修改”,例如越界删除了不该动的内容(Over-deletion)。
同时,为了定位模型究竟卡在哪个环节,研究设计了一套递进式的“诊断阶梯”(Diagnostic Ladder):
-
Vanilla 模式:仅提供常规修改需求描述和完整文件;
-
Explicit Deletion 模式:在提示中明确追加“请仅使用删除操作,不要保留旧代码”的指令;
-
Region Pointer 模式:不仅给出指令,还指明需要删除的代码大致位于哪些函数或区间;
-
Exact Lines 模式:直接把需要切除的代码行精确范围双手奉上。
在最原始的 Vanilla 模式下,测试涵盖了 12 款当红模型。成绩单令人诧异:即便是当时表现最顶尖的 Claude Opus 4.8,在面对完全不需要构思任何新代码、只需删掉冗余逻辑的任务时,依然有超过五分之一(21.0%)的失败率,最终合规率仅为 79.0%;GPT-5.6 Sol 的成功率为 74.0%;而部分中小规模的开源模型,成功率甚至一路狂跌到了 18.0%。
在所有的失败案例中,“删除不完全”(Incomplete Deletion)占据了总失败量的 69.8%。模型在纯净的单文件隔离环境下,依然自发复现了它在 SWE-bench 中的毛病:宁可擅自编写新的控制流把代码包住,也不肯按照指令把它干脆利落地移走。
更值得玩味的是诊断阶梯的递进实验。当评测逐步为模型加上“明确删除指令”和“区域指针”时,模型整体成功率的提升微乎其微。绝大多数模型依然表现得茫然失措。只有当测试把条件放宽到第四层——直接把“精确到行的删除跨度”(Exact Lines)直接写进 Prompt 时,情况才发生质的转变,删除不完整的问题在大部分前沿模型上被基本压制。
然而,即便饭喂到了嘴边,GPT-5.6 Sol 在明确知道具体行号的前提下,依然有 19.5% 的任务宣告失败;Qwen3-235B 甚至在被告知具体删哪行后,仍有 17.5% 的概率把目标行留在文件里。
更具启发性的现象发生在这类“满血提示”之下的失败归因转移:原本占统治地位的“删除不彻底”几乎消失了,但“过度删除”(Over-deletion)和“附带新增非法代码”的比例却急速飙升。有多达 26% 的失败案例,是因为模型一转攻势后下刀太狠,不仅切掉了指定跨度,还顺手把周围依赖的上下文也一并连根拔起。
这揭示了一个深层事实:大模型不是在物理上“不会输出删除指令”,而是在微积分般细密的程序结构把控上,缺乏精细的边界控制力(Scope Preservation)。面对模糊的删除意图,由于害怕误伤系统,模型的默认先验是“防御性保留,加层兜底”;而一旦外部强加了坚决删除的信号,模型又极易滑向“过度切除、破坏周围环境”的另一极端。
0.7% 的微调药方:后训练欠缺的“断舍离”
大模型这种强烈的“偏好加法、抗拒减法”的心理结构,究竟从何而来?
认知科学研究早就指出,人类本身在解决问题时就存在根深蒂固的“加法偏见”(Additive Bias),人们更倾向于通过增加新零件来修复缺陷,而非去除旧组件。这种偏差不可避免地被投射到了人类编写的海量文本与代码中。互联网语料库中天然就充斥着庞大的代码累加记录,而模型在代码预训练阶段通过自回归生成学习,其天然奖励信号也主要来源于“往后写 Token”。
雪上加霜的是,在代码后训练(Post-Training)阶段,目前的强化学习与微调策略极度依赖单元测试反馈。由于通用测试套件对 Guard-and-Go 这种治标不治本的代码一律亮绿灯,模型在强化学习迭代中便习得了这种低风险、高通过率的捷径:包裹防御远比承担破坏语法边界的风险去删除代码更容易拿到正向奖励。
既然病因在后训练的奖励与分布失衡,那么针对性的后训练能否根治这种偏科?
研究团队进行了一场轻量但极具说服力的概念验证(Proof-of-Concept)实验。他们选取了一个 7B 参数规模的内部基准代码模型,在其原本由 159 亿 Token 组成的纯代码后训练数据混合物中,仅仅掺入了 12821 条高质量的删除任务样本(包含 10000 个文件级纯删除和 2821 个仓库级修复样本)。这部分删除监督数据仅占总训练 Token 量的 0.7% 左右。
随后,两组模型在 128 张计算卡上使用完全一致的超参数配方(6 个 Epoch,全局 Batch Size 为 64)进行对照训练。一组保持原生配方,另一组仅加入了这 0.7% 的删除样本。
在 CanItDelete 基准测试中, baseline 模型的通过率仅有 6.5%,而仅仅注射了 0.7% 删除数据的干预模型,通过率翻倍提升到了 13.7%;更核心的指标——不完全删除率(Incomplete Deletion)从 80.4% 大幅下降了 13.9 个百分点,跌至 66.5%。
细分去向的统计展现了模型认知转变的精密图景:在这下降的 13.9 个百分点中,有 7.2 个百分点直接转化为了完全合格的精准修改,另有 6.7 个百分点转化为了完整删除但破坏了外围结构的编辑(其中过度删除上升了 6.2 个百分点)。这一消长再次坐实了论文的核心论断:消除删除规避与维持边界完整是两门需要分别练习的技艺。增加删除监督能立竿见影地打消模型的“不敢删”,但模型紧接着就必须补上“如何克制地删”这一课。
更关键的成果在于跨基准的泛化迁移。后训练注入的删除数据从未针对过任何下游综合性跑分集,但评测结果显示:
-
在测试真实仓库缺陷修复能力的 SWE-bench Verified 上,该模型的解决率提升了 5.3 个百分点;
-
在评估自然语言驱动代码编辑的 CanItEdit 基准上,提升了 1.4 个百分点;
-
在 EditBench 上同样保持稳健,没有出现任何编辑能力的退化(Regression)。
这一实验有力地证明了,当前大模型展现出的“删除规避”,绝对不是架构层面上不可修复的智力缺陷,而纯粹是现阶段后训练数据配方严重倾斜所致的“营养不良”。
重新审视 AI 生成代码的“工程美学”
在评估大语言模型的代码生成能力时,软件工程界曾长期被“测试驱动评测”的主流范式所主导。然而这项关于删除规避的研究犹如一剂清醒剂,揭开了这一评估机制下的结构性脆弱。
只看单测通过率的评测,正在无形中选拔出一批深谙“应试技巧”的代码生成模型。它们学会了把报废的旧引擎焊死在汽车底盘上,在外面临时缠上一圈铁丝与传感器以应付质检。如果开发者毫无保留地把这类智能体接入 CI/CD 流水线,并给予它们自动合并的权限,那么在肉眼可见的未来,软件资产必将以远超以往的速度腐化,原本用于降低维护成本的自动化工具,最终反而会制造出吞噬人类工程师精力的维护泥潭。
从 CanItDelete 暴露出的断层,到仅需 0.7% 数据微调便能大幅缓解的实验结果,论文指向了一条清晰的演进路径:未来的代码大模型后训练,必须将“减法能力”提升到与“加法能力”对等的战略高度。真正的智能编程不是无休止地堆砌代码,而是懂得在繁冗的逻辑中准确识别腐肉,并具备在毫厘之间将其干净剔除的手术刀式控制力。毕竟在优雅的软件工程哲学里,写出精巧的新模块固然属于机器的造化,但懂得何时大刀阔斧地删除一段坏代码,才始终闪烁着人类工程师独有的智慧。