当模型改太多:最小编辑保真度,代码修复质量被忽视的那一轴

修一个 off-by-one bug,测试全过,但 diff 多了 60 行没人要的输入校验和类型转换。这算修好了吗?

问题:测试通过 ≠ 修对了

过去的代码修复评测只看一件事:测试过没过。Pass@1 成了行业标准,但这个指标有一个盲区——它不区分「刚好改对」和「改了一大堆顺带把 bug 改没了」。

EMNLP 2026 的这篇论文把这个盲区单独拎出来,变成一个可度量、可训练的目标:编辑保真度(edit fidelity)。

论文标题:When Models Edit Too Much: On the Fidelity of Minimal Code Edits
作者:Tongyao Zhu, Wei Hern Lim, Min-Yen Kan(NUS)
方向:Software Engineering / NLP
链接:arXiv:2609.04061


方法:注入 bug,然后知道正确答案是什么

这是这个工作的核心创新点。

过去评代码修复,没有「正确答案」的参照——你不知道「最小需要改多少行」是多少。论文的做法:

  1. 取 BigCodeBench 400 个任务,每个从一个正确实现出发
  2. 手动注入 1–2 个AST 层面的局部 corruption(比如把 < 改成 <=,把循环边界改一个)
  3. 只保留「注入后测试失败」的样本
  4. 最小修复 = 注入的 reversal,天然已知

这相当于给每个任务发了标准答案,而且标准答案是「只改一行」。这样就能精确测量:模型实际改了多少?超出最小修复多少?

Benchmark 统计:

  • 平均函数长度 10.4 行,最多 34 行
  • 50.2% 的最小修复只需要改 1 个 token,91.8% 不超过 2 个 token
  • Bug 类型分布:谓词/控制流 43.0%,计算/值 29.9%,边界/迭代 18.7%,API 语义 8.5%

发现一:过度编辑是普遍现象,连 GPT-5.5 也不例外

论文在 20 个前沿模型上跑了这个 benchmark,核心指标是 Excess Levenshtein Distance(超出最小修复的归一化 token 编辑距离)。

结果:高度通过率和大幅过度编辑可以共存

一个具体例子:修一个「下标差 1」的边界 bug,gold patch 只需要改一个字符,GPT-5.4 的输出却删了 5 行、插了 60 行——加了输入验证、dtype 转换、NaN 掩码、曲线上采样。测试当然全过,因为那些代码本来就是正确的,只是没人要。

在所有模型中,5 次采样全部通过测试的前提下,中位 patch 大小从 2 行插入(最保守模型)到 60 行插入(最大模型)不等,而且最新模型并不比旧模型更保守。

这不是能力问题,是目标函数问题。 评测只问「测过没过」,模型就往那个方向优化,过度改写在训练时从来没被惩罚过。


发现二:一句提示就能大幅改善,但不是因为模型变强了

论文测试了一个简单的「保守编辑提示」:

「Make only the necessary changes to fix the bug. Do not add new functionality, improve code style, or add defensive checks. Preserve the original code as much as possible.」

效果:

  • 前沿模型平均 Excess Levenshtein Distance:从 0.195 降到 0.131
  • 新增认知复杂度降低 26.6%
  • Pass@1 反而提升了 2.3 个百分点

这是一个重要的反直觉发现:更保守的编辑不仅没有牺牲正确率,还略微提升了正确率——因为过度改写有时候会改掉正确的东西。

但关键限制:这些收益并不随推理时间增加或模型变大而单调提升。推理能力的提升和编辑保守性是两条正交的能力轴,大模型不一定更保守。


发现三:SFT 会把过度编辑学进模型,RL 才能保持域外保真度

这是论文最值得警惕的发现。

研究对比了 SFT(监督微调)和 RL(强化学习)在编辑保真度上的表现:

SFT:在见过的 corruption 模式上表现良好,但域外保真度显著下降——它学会了特定类型的「改法」,但没学会「克制」。这和代码修复研究里「plausible patch」问题的老毛病一脉相承。

RL(PPO):在未见过的 corruption 模式上达到 0.782 Pass@1,同时 Excess Levenshtein Distance 仅 0.050,且没有损害通用编码能力。

RL 学到的是「克制本身」,而不是「某类 bug 的特定改法」。这意味着编辑保真度是可迁移的能力,而不只是针对特定任务的拟合。


为什么这很重要:diff 可读性是生产的真实瓶颈

Agent 写代码在 demo 场景下已经很强,但生产场景的真实约束不只是「功能测试通过」:

  1. Review 成本:一个 3 行 patch 和一个 60 行 patch 的 review 时间不是一个量级,维护者的时间和注意力是稀缺资源
  2. 回归风险:改得越多,引人新 bug 的概率越高,即使测试全过也可能在边界条件上埋雷
  3. 跨仓库泛化:SFT 过拟合意味着在一个代码库上学到的「改法」会在另一个代码库里制造噪声
  4. 版本管理:大 diff 会在 blame、bisect、rollback 时制造不必要的麻烦

这篇论文把这些工程约束变成了可量化的指标,第一次让「编辑保真度」和「功能正确性」成为代码修复质量的两个独立维度。


对 Agent 开发的实际意义

评测层面: 仅靠 Pass@1 评测代码修复能力是不够的。论文的 excess edit distance 应该成为评测矩阵的标准配置——一个改 500 行的通过方案和改 3 行的通过方案,真实工程价值差距悬殊。

训练层面: 如果你的代码修复数据里大量存在「改了很多行但功能对了」的样本,SFT 训练会把它学进去,变成模型的默认行为。需要在 post-training 阶段引人编辑保真度目标。

Prompt 工程层面: 「保守编辑提示」简单到可以直接加进系统 prompt,特别是对 brownfield 场景(修改现有代码而非从头生成)的任务。

架构层面: 这篇论文进一步支持了「验证比生成更重要」的趋势——与其让模型生成完美代码,不如让它生成很多代码,然后有一个验证层把不合格的过滤掉。编辑保真度可以成为验证层的额外约束。


Code: https://github.com/nreHieW/over-editing