SWE-Touch:用户随手改了两行代码,你的编程 Agent 就崩了?

用 Cursor 或者 Claude Code 写代码的时候,你有没有干过这种事——Agent 还在那儿吭哧吭哧跑,你看它半天没动某个文件,手痒,自己上去改了两行。或者它改的方向不对,你直接把那段代码删了自己写。

我干过,而且经常干。

问题来了:Agent 接下来会看到一份"被用户动过手脚"的代码库。它读到的程序状态,和它脑子里记住的状态,已经不一样了。它会怎么处理?是发现"诶这代码变了"然后重新对齐,还是傻乎乎地基于过期认知继续往下走,最后给你产出一个跑不通的补丁?

说实话,我之前从来没认真想过这个问题,直到刷到这篇 SWE-Touch。中科院自动化所这篇工作干的事,用一句话说就是:在 Agent 干活的时候,模拟用户往代码库里塞一个"帮倒忙"的补丁,然后看 Agent 能不能兜住。结果挺扎心的——9 个前沿模型,平均掉 7.7 个点,最惨的从 76.5% 直接掉到 62.7%,排名从第 3 跌到第 8。而 Claude Opus 4.8 和 GPT 5.5 几乎毫发无伤。自主编程能力差不多的模型,在"用户会碰代码"这个真实场景下,差距大得离谱。

这篇论文没有提出什么新模型、新算法,就是一个 benchmark。但我觉得它是近期 Agent 评测里少见的"打在痛点上"的工作——因为它测的能力,是每个把 AI 编程工具当生产力用的人每天都在真实经历、却从来没有被量化过的东西。


论文信息

  • 标题:SWE-Touch: Benchmarking Coding Agents When Users Touch the Code
  • 作者:Yuqiao Tan, Jinxiang Meng, Fangyu Lei, Minzheng Wang, Shizhu He, Jun Zhao, Kang Liu
  • 机构:中国科学院自动化研究所、中国科学院大学
  • 链接arXiv:2608.02499GitHubHuggingFace 数据集

一个被所有 benchmark 忽略的交互通道

先交代一下这个问题的现实分量。

现在主流的仓库级编程评测,SWE-bench 也好,后来的各种变体也好,基本都假设 Agent 在一个封闭环境里独立干活:给一个 issue,Agent 自己读代码、改代码、跑测试,最后交卷。就算是那些引入"用户模拟器"的评测(Ambig-SWE、HiL-Bench、SWE-Interact 这些),用户和 Agent 的交互也只限于发消息——用户动嘴不动手。

但真实的结对编程完全不是这样。作者统计了公开的 SWE-chat 数据集(真实用户和编程 Agent 的会话记录),发现 59.0% 的会话里用户直接改过代码仓库。将近六成的会话。这不是边缘行为,这是主流用法。

图1:用户和 Agent 共享同一个工作区

图1:左边是论文给的场景示意——Agent 在 Read/Plan/Edit/Test 循环里干活,用户同时通过 Messages 和 Code Edit 两个通道影响共享工作区;右边那个条形图是 SWE-chat 的统计,59.0% 的会话包含用户发起的代码修改。注意用户侧那个"Repo Belief"(用户对仓库的认知),这个设定后面会呼应到。

你想想看,这个比例意味着什么。现有的所有编程 benchmark,测的都是一个覆盖率不到一半的交互模式。而另一半——用户会伸手碰代码的那一半——每次编辑都在悄悄改变 Agent 后续动作所能观察到的程序状态。Agent 基于旧状态做的规划,可能在新状态下已经不成立了。

所以 SWE-Touch 的问题定义很直接:当用户编辑和任务修复产生语义冲突时,Agent 能不能检测到这个变化、调和冲突、并且验证修复仍然有效?

怎么造一个"帮倒忙但看起来合理"的用户补丁

这个 benchmark 最难的地方其实不是评测本身,而是怎么构造那个"用户编辑"。

随便改坏代码当然容易——直接把关键变量名改了,Agent 肯定挂。但这不是真实用户行为。真实用户改代码有他的道理:他相信这个改动是好的,可能本地还跑过某些检查,只是这个改动恰好和任务需要的完整修复冲突。

作者把这个东西叫 Counter-Edit:规模小、局部合理、但会挡住任务完成的编辑。构造流程分三步走,pipeline 长这样:

图2:SWE-Touch 的整体流程

图2:三大模块。(a) 挖掘任务关键区域——让 GPT 5.5、GLM 5.1、MiniMax M2.7 三个不同系列的模型各自跑一遍任务,把它们的读取/编辑轨迹取交集,交集区域就是"干这活绕不开的地方",每个任务最多保留 8 个。(b) 用户编辑构造——一个独立的 User Patch Generator 拿着关键区域和参考补丁,生成 Counter-Edit,然后过三重验证。(c) 共享工作区评估——Agent 干到一半访问到重叠区域时,运行时把编辑连带一条用户消息(比如"我在本地测过了,请保留")注入进去。

这三步里我觉得最见功力的是那个三重验证。一个合格的 Counter-Edit 必须同时满足:

\[V_i^F(R_i^-) = 0, \quad V_i^F(R_i^*) = 1, \quad V_i^F(R_i^{-*}) = 0\]

工程直觉上讲,这三个条件卡掉了三种"注水"情况。第一条,光打用户补丁跑不过测试——保证这个编辑自己不是答案(不然测的就变成"Agent 会不会抄用户作业"了)。第二条,参考补丁能过——保证任务本身是可解的,编辑没把任务搞成无解。第三条最关键:用户补丁叠上参考补丁,还是过不了。也就是说,正确修复和用户编辑不是简单共存的关系,Agent 必须主动处理这个冲突——要么改它,要么绕过它,装没看见是一定交不了差的。

这个设计真的挺精巧的。它把"鲁棒性"从一个模糊的词,变成了一个有严格操作定义的评测对象。

补丁规模上也很克制:Counter-Edit 平均 7 到 13 行、涉及 1 到 1.5 个文件,而参考修复在 DeepSWE 上平均 730 行。用户就是随手改了改,没有大动干戈——这才像真实场景。

主实验:平均掉 7.7 个点,排名大洗牌

评测在 200 个 SWE-bench Verified 任务上进行,9 个模型,每个条件独立跑 3 次。核心结果一张表:

模型 Vanilla 解决率 Counter-Edit 解决率 变化 保留率 排名变化
Claude Opus 4.8 85.2 (1) 83.3 (1) 降 1.8 96.0%
GPT 5.5 80.5 (2) 79.2 (2) 降 1.3 95.0%
GLM 5.1 72.7 (7) 68.3 (4) 降 4.3 83.3% 升 3 位
MiniMax M2.7 76.5 (3) 62.7 (8) 降 13.8 个点 78.1% 跌 5 位
MiniMax M2.5 75.7 (4) 66.2 (5) 降 9.5 78.3% 跌 1 位
Qwen 3.7 Max 75.2 (5) 70.3 (3) 降 4.8 90.3% 升 2 位
Qwen3-Coder-480B 57.2 (9) 40.7 (9) 降 16.5 个点 60.8%
Kimi K2.6 70.3 (8) 64.3 (6) 降 6.0 87.2% 升 2 位
DeepSeek V4 Pro 74.8 (6) 63.8 (7) 降 11.0 81.5% 跌 1 位

表1:SWE-bench Verified 上的 Vanilla 与 Counter-Edit 对比,括号内为排名。保留率指 Vanilla 下解决的任务在 Counter-Edit 下仍被解决的比例。

看到这个表我的第一反应是盯着 MiniMax M2.7 那一行看了好几秒。Vanilla 条件下它排第 3,76.5 的解决率,跟 Claude 也就差不到 9 个点——光看传统榜单,你会觉得这模型挺能打的。结果用户一碰代码,直接掉到第 8,13.8 个点就这么没了。

更扎眼的是 Qwen3-Coder-480B,480B 的参数量,专门的代码模型,掉了 16.5 个点,保留率只有 60.8%。

而头部的 Claude Opus 4.8 和 GPT 5.5,掉分控制在 2 个点以内,保留率 95% 以上。坦率地讲,这个差距比 Vanilla 榜单上任何两个相邻名次的差距都有说服力——它说明"自主编程强"和"协作场景下稳"是两个维度的事,而且这两个维度在现有榜单上完全混在一起了。

还有一个容易被忽略的细节:GLM 5.1、Qwen 3.7 Max、Kimi K2.6 的排名反而上升了。不是它们变强了,是别人掉得更狠。这提醒我们,Counter-Edit 条件下的榜单和 Vanilla 榜单讲的是两个故事——如果你是个要给团队选 AI 编程工具的人,你该看哪个榜,取决于你的团队有多爱动手改代码。

任务级别的迁移图也很直观:

图3:任务结果从 Vanilla 到 Counter-Edit 的迁移

图3:全部模型所有运行的桑基图。Vanilla 下解决 1063 个任务实例,Counter-Edit 下只剩 961 个。红色的流是"本来能解决、被用户编辑搞砸的",161 个;蓝色的流是"本来没解决、注入编辑后反而解决了的",59 个。

注意那个蓝色的流——59 个实例是用户编辑反而帮了忙的。这符合直觉,用户补丁虽然和参考修复冲突,但偶尔会给 Agent 提供有用的中间状态。不过 161 对 59,帮倒忙的几乎是帮忙的三倍。

长期任务上,问题没有消失,只是换了人倒霉

主实验是在 100 步预算的 SWE-bench Verified 上跑的。那在更长的任务上呢?作者又在 SWE-Bench Pro 和 DeepSWE 上各抽了 25 个任务,预算放宽到 500 步,编辑改在轨迹的 25%、50%、75% 位置按固定节奏注入。

模型 SWE-Bench Pro 解决率变化 DeepSWE 解决率变化
Claude Opus 4.8 0.0 降 10.0
GPT 5.5 0.0 降 8.0
GLM 5.1 降 10.3 降 2.5
Qwen 3.7 Max 降 10.0 降 2.0
MiniMax M2.7 降 6.0 0.0

表2:长程任务上 Counter-Edit 相对 Vanilla 的解决率变化。

这张表有意思的地方在于,倒霉的模型换了。主实验里毫发无伤的 Claude 和 GPT,在 DeepSWE 上掉了 8 到 10 个点;而主实验里崩得最惨的 MiniMax M2.7,在 DeepSWE 上居然纹丝不动。

说实话这块我没有一个特别干净的解释。样本量小(每个基准 25 个任务、2 次运行),方差肯定大,单个任务的得失就能造成好几个点的波动。但至少能说一件事:没有任何模型在所有设定下都稳。鲁棒性不是模型的固定属性,它跟任务分布、编辑时机、交互节奏全都纠缠在一起。

编辑频率的消融进一步佐证了这一点:

图4:不同编辑频率 K 下的解决率

图4:两个长程基准上,编辑次数 K 从 1 加到 5 的解决率变化,深灰柱是 Vanilla 基线。有的模型(比如 MiniMax M2.7 在 SWE-Bench Pro 上)随 K 增大单调退化,编辑越多死得越惨;而 GPT 5.5 和 GLM 5.1 在中间 K 值反而持平甚至略有回升。

编辑越多越差,这个方向性结论不意外。但部分模型的曲线不是单调的——K=3 比 K=1 还差,K=5 又回来一点。我的猜测是多次编辑给了模型更多"用户会碰代码"的信号,反而触发了更谨慎的行为模式,但这个解释论文里没给,我保留意见。

拆开看:Agent 到底是怎么死的

数字层面看完之后,论文最有价值的部分来了——作者人工审计了所有"Vanilla 解决但 Counter-Edit 失败"的运行,给失败归因。

图5:失败模式分析

图5:(a) 总体失败分布——保留冲突代码占 63.3%,错误替换 13.9%,不完整调和 11.6%,剩下的是偏离目标、证据不足等小类。(b) 分模型的失败构成,红色(保留冲突)的长度和右侧 n 值一起读才有意义。(c) 修订率——失败轨迹中 Agent 尝试修改或删除用户编辑的比例,Claude Opus 4.8 高达 79.3%,而 MiniMax M2.5 和 DeepSeek V4 Pro 只有 15% 上下。

63.3% 的失败是"保留冲突"——Agent 看到了用户编辑,接受了它,然后在它基础上继续干,最后交出一个带着冲突代码的补丁。用户说"我本地测过了请保留",它就真的保留了。

但这里有个更微妙的发现。你看 Claude Opus 4.8:它的保留冲突占比只有 17.2%,修订率高达 79.3%——它几乎总是去挑战用户的编辑。可它失败的那 29 个案例里,所有轨迹都修订过用户编辑,然后还是失败了。它的主要死法是"错误替换"(占它失败的 37.9%):反对了,改回去,但改错了。

这就带出一个挺反直觉的结论:敢于反对用户,只是鲁棒性的入场券,不是鲁棒性本身。完整的链路是——发现代码被改了、判断这个改动和任务冲突、给出正确的替代方案、再跑测试验证。四个环节断在哪一环都算输。MiniMax 系列死在最前面(顺从),Claude 死在中间(改错),死法完全不同。

修订率和性能损失的 Spearman 相关系数是 0.80,挺强的。但相关不是因果,Claude 的例子摆在那儿。

图6:最终编辑之后 Agent 的行为

图6:(a) 最后一次用户编辑之后,各模型平均发出的 Read/Edit/Test 命令数。Kimi K2.6 的 Read 量一骑绝尘(40 多次),是 GPT 5.5 的三倍以上。(b) Agent 对用户编辑的响应模式:绿色是反对(Counteract),红色是顺从(Follow),灰色是没表态。

这张图里的对比很生动。GPT 5.5 在 90% 的轨迹里反对最终编辑,用的读取操作却很少——它像是扫一眼 diff 就能下判断。Kimi K2.6 也在 80% 的轨迹里反对,但它要翻 3 倍多的文件才敢动手。最后殊途同归,可成本完全不同。而且就算反对了编辑,仍有 28% 的轨迹以未解决收尾——反对只是第一步,修得对不对、测得够不够,才是生死线。

几个值得单独拎出来的消融结论

作者还做了两组对照实验,把混杂因素拆干净了。

一组是把"消息"和"代码编辑"解耦。只发消息不动代码,影响在 -2.0 到 +3.0 点之间晃,有的模型甚至正提升;只动代码不发消息,稳定掉 1 到 9.5 个点。所以杀伤力的来源是代码冲突本身,不是用户那句"请保留我的修改"的措辞有多恳切。这个结论对做 Agent 的人有实际指导意义:防"花言巧语"的 prompt 工程救不了你,得在状态追踪上下功夫。

另一组是 Co-Edit 对照:注入不冲突的小编辑(用户在无关地方改了改注释、加了无关功能之类),平均影响只有 0.1 个点。这组对照非常关键——它证明模型掉分不是因为"被打断"或者"工作区脏了"这种表层原因,而是精准地死于语义冲突。整个 benchmark 测的东西是干净的。

我的判断:benchmark 本身比结果更有价值

聊完数据,说说我对这篇论文的整体看法。

它最值钱的地方,是把一个所有人都隐约知道、但没人量化的问题,变成了有严格定义的评测对象。"Agent 和用户共享工作区"这件事,之前的研究要么假设不存在,要么只模拟到消息层面。SWE-Touch 补的是交互的另一半——代码编辑通道。而且 Counter-Edit 的三重验证设计,保证了测的是"冲突调和"而不是"抄作业"或"任务被搞无解",这个分寸感把握得很好。

但问题也不少,我说三个。

其一,Counter-Edit 是合成的,而且刻意构造为"和参考修复冲突"。真实用户的编辑分布远比这丰富:有互补的、有部分正确的、有纯粹跑题的、有改需求的。作者在局限性里也承认了这一点。所以论文里的掉分数字,应该理解为一个特定压力测试下的下界参考,而不是真实使用场景的预期损失。真实场景是更好还是更坏,没人知道——真实用户编辑可能更温和(不总往关键区域招呼),也可能更刁钻(连着改三个文件还改需求)。

其二,长期任务实验的统计功效偏弱。25 个任务、2 次运行,掉 10 个点也就是两三个任务的差别。方向性结论可以信,具体数字别当真。

其三,评测的是单 Agent 框架下的表现,而不同 Agent 脚手架(怎么呈现 diff、什么时候提示工作区变化)对结果的影响没有系统研究。模型排名换个脚手架可能就变——所以这个 benchmark 测的是"模型 + 默认脚手架"的组合,归因到纯模型能力时要小心。

对工程实践的启发,我觉得有这么几条。做编程 Agent 产品的,工作区变更检测应该成为一等公民——每次执行动作前 diff 一下当前状态和上次认知的状态,成本很低,收益直接对标那 63.3% 的保留冲突失败。做模型的,论文指出的能力链路(检测变更 → 调和冲突 → 验证行为)基本就是训练数据构造的 checklist,尤其是"修订后重新验证"这一环,Claude 的错误替换失败说明现有模型普遍缺这口气。选模型的,如果你的使用场景是人机高频结对,别只看 SWE-bench 榜单,Vanilla 第 3 和协作第 3 可能是完全不同的两个模型。

最后说句题外话。这篇论文让我想到一个更大的问题:现在的 Agent 评测体系,说到底还是在考"独立做题",而真实世界的工作全是协作。消息交互、代码编辑、需求变更、中途接管……这些维度一个个被补上之后,现在榜单上的座次恐怕还要再洗几次牌。SWE-Touch 只是开了个头。


觉得有启发的话,欢迎点赞、在看、转发。跟进最新AI前沿,关注我