想象你是一位试图修复复杂复古汽车引擎的资深机械师。在过去,每当出现新问题,你都得从零开始:阅读手册、猜测故障所在、尝试修复,并祈祷奏效。如果失败,你便再次尝试,却忘记了从上次错误中学到的东西。
ExpeRepair 就像是赋予那位机械师一套受人类大脑启发的、超强大的双部分记忆系统。该系统不再让 AI 每次都从零开始,而是帮助其“记住”过往的修复经验并从中学习,从而显著提升其修复软件漏洞的能力。
以下是其工作原理,拆解为简单概念:
两种记忆类型
该论文指出,人类记忆并非一个巨大的容器,而是由两个截然不同的部分组成。ExpeRepair 复制了这一设计:
情景记忆(“相册”):
- 是什么: 这是一组具体、实例化的案例集合。将其想象为过往修复工作的剪贴簿。它包含精确的“修复前与修复后”照片:具体的错误信息、确切的故障代码,以及具体的修复补丁。
- 如何帮助: 当新漏洞出现时,系统会翻阅这本剪贴簿,寻找类似的过往案例。“嘿,上周我们修复过一个类似的坏掉的电灯开关;让我们试试同样的方法。”这提供了一份可遵循的具体方案。
语义记忆(“规则手册”):
- 是什么: 这是从所有过往修复中提炼出的抽象智慧。它不涉及具体照片,而是关于通用原则。将其想象为用通俗英语写成的“最佳实践”或“经验法则”列表。
- 如何帮助: 它教导 AI 通用的教训,例如“修复安全问题时,务必检查边缘情况”或“如果一个函数处理多个输入,请确保修复所有输入,而不仅仅是提到的那一个”。这有助于 AI 适应其未曾见过的新情况。
如何修复漏洞(工作流程)
该系统使用两个“智能体”(AI 工作人员)来执行修复:一个负责编写测试脚本(以证明漏洞存在),另一个负责编写实际修复代码。
- 旧方式: AI 接收漏洞报告,试图基于其通用训练猜测修复方案,并寄希望于最佳结果。如果失败,它会在相同的静态指令下再次尝试。
- ExpeRepair 方式:
- 回顾过去: 在尝试修复新漏洞之前,系统会检查其相册(情景记忆),寻找类似的过往失败与成功案例。
- 查阅规则: 它同时检查其规则手册(语义记忆),获取与该类问题相关的高层建议。
- 动态指令: 系统不再使用僵化的预写指令手册,而是为 AI 工作人员创建自定义的“动态”提示。它会说:“这是新漏洞。这是上个月我们修复过的类似漏洞(来自相册)。并且请记住这条关于处理边缘情况的规则(来自规则手册)。”
- 学习与更新: 一旦修复完成(甚至即使失败),系统也会保存此次经验。它将具体细节添加到相册中,并将学到的教训总结归纳到规则手册中,以备下次使用。
结果
研究人员在两组著名的真实世界软件漏洞数据集(称为 SWE-Bench Lite 和 SWE-Bench Verified)上测试了该系统。
- 得分: 使用强大的 AI 模型(Claude 4 Sonnet),ExpeRepair 在较难的测试集上成功修复了 74.6% 的漏洞,在较轻松的测试集上修复了 60.3%。
- 对比: 这是他们在测试的所有开源方法中表现最好的。它击败了其他顶级工具,如 SWE-agent、Aider 和 AutoCodeRover。
- 成本: 它在无需对 AI 模型进行昂贵且耗时的重新训练的情况下取得了这些高分。它仅仅是通过“阅读”自己过往的工作来学习。
为何重要
该论文认为,当前的 AI 修复工具就像那些参加考试、获得成绩,然后在下次考试前立即忘记一切的学生。而 ExpeRepair 则像是一个保留学习指南、复习错误、并在解决每一个问题后变得更聪明的学生。
通过将具体实例(情景记忆)与通用智慧(语义记忆)相结合,该系统创造了一个反馈循环:AI 工作的越多,修复软件的能力就越强,从而模拟了人类开发者随时间推移实际学习和提升的过程。
技术摘要:ExpeRepair
问题陈述
自动化程序修复(APR)传统上专注于函数级缺陷,但现实世界的软件维护需要涉及大型代码库、复杂的跨文件依赖关系以及错综复杂的问题描述的仓库级修复。尽管近期基于大语言模型(LLM)的方法已转向仓库级修复,但它们存在两个关键局限性:
- 忽视历史经验:现有方法将每个问题孤立处理,未能利用同一仓库中先前已解决问题中的宝贵模式和见解。
- 静态提示:现有方法依赖于僵化的、人工编写的提示,无法适应不同软件项目多样化的编码规范、架构模式或不断演变的上下文。
方法论:ExpeRepair
ExpeRepair 是一种新颖的基于 LLM 的框架,旨在通过模仿人类认知的双重记忆系统(情景记忆和语义记忆)来克服这些局限性。它无需计算昂贵的微调,而是依赖双重通道知识积累机制。
核心架构
该系统由两个主要模块组成:
- 程序修复模块:协调一个测试代理和一个补丁代理,协同执行测试生成、补丁生成和补丁验证。这些代理利用 ReAct 算法迭代处理任务。
- 记忆模块:将修复轨迹组织为两种互补的记忆:
- 情景记忆:存储具体的修复演示,包括成功的(输入,输出)对以及带有反馈的失败尝试。
- 语义记忆:编码从过往修复轨迹中提炼出的抽象、反思性见解(例如,通用策略、常见失败原因)。
工作流程
ExpeRepair 分两个阶段运行:
- 初始阶段(冷启动):系统在无先验记忆的情况下处理种子问题集(每个仓库的前五个问题)。生成的修复轨迹被提取并整理到情景记忆和语义记忆中,以建立“热启动”。
- 推理阶段:对于新问题,ExpeRepair 动态激活两个记忆系统:
- 情景激活:基于当前问题上下文和执行反馈检索前 k 个相关演示(使用 BM25 检索)。这些作为上下文示例。
- 语义激活:检索高层反思性见解,以指导代理的推理策略。
- 动态提示:代理接收增强的提示,结合了任务定义、问题上下文、执行反馈、检索到的演示和语义见解。这用上下文感知、经验驱动的指令取代了静态提示。
记忆维护
语义记忆通过“总结与更新”过程动态更新,其中 LLM 分析修复轨迹以生成新见解。这些见解通过三种操作进行管理:ADD(添加新有价值见解)、REMOVE(移除矛盾或冗余条目)和EDIT(细化或合并重叠见解)。系统将见解数量限制在特定范围内,以防止上下文饱和。
主要贡献
- 双重记忆框架:提出了 ExpeRepair,这是首个通过双重记忆系统(情景和语义)在不进行参数更新的情况下持续从历史经验中学习仓库级 APR 的方法。
- 动态提示生成:设计了一种机制,通过整合具体演示和抽象模式来定制修复策略,解决了静态提示的僵化问题。
- 实证验证:在 SWE-Bench Lite 和 SWE-Bench Verified 上进行了全面实验,证明了其在开源方法中的最先进性能。
- 开源:提供公开可访问的源代码,以促进复现和进一步研究。
实验结果
作者在 SWE-Bench Lite(300 个问题)和 SWE-Bench Verified(精选可解决问题)上评估了 ExpeRepair,使用了多种 LLM 骨干网络(Claude 3.5 Sonnet、Claude 4 Sonnet 等)。
- 性能:使用 Claude 4 Sonnet,ExpeRepair 在 SWE-Bench Lite 上实现了 60.3% 的 pass@1,在 SWE-Bench Verified 上实现了 74.6% 的 pass@1。
- 对比:这些结果超越了所有评估的开源基线,包括 SWE-agent、AutoCodeRover、SpecRover、Agentless、OpenHands、PatchPilot 和 DARS。例如,在 SWE-Bench Verified 上,ExpeRepair(74.6%)显著优于次优的开源方法 DARS(表中未报告 Verified 数据,但 PatchPilot 为 53.6%)。
- 效率:ExpeRepair 保持了具有竞争力的推理成本(使用 Claude 4 时每个实例约 1.91 美元),显著低于 DARS 等高成本策略(12.24 美元)。
- 消融研究:
- 移除整个记忆模块导致性能下降最大(例如,使用 Claude 4 在 Verified 上从 60.3% 降至约 50%),证实了历史经验的必要性。
- 情景记忆(具体演示)对性能提升的贡献大于语义记忆(抽象见解),尽管两者对于获得最佳结果都至关重要。
- 检索:基于术语的检索(BM25)优于基于嵌入的检索,表明错误消息和反馈中的词汇重叠对代码生成至关重要。
- 记忆管理:包括 REMOVE 和 EDIT 操作在内的策略至关重要;简单的累积(仅 ADD)会导致因上下文噪声而性能下降。
意义与主张
该论文声称,ExpeRepair 证明了利用过往修复知识能显著提高具有挑战性的仓库级修复任务的性能。通过模拟开发者随时间学习和适应的方式,ExpeRepair 实现了协同效应:具体演示提供精确的实现参考,而反思性见解则实现通用化适应。
作者强调,他们的方法在有效性和效率之间取得了有利平衡,避免了微调的高昂成本,同时优于复杂的代理编排方法。他们指出,虽然该方法在设计上是语言无关的,但目前的评估仅限于 Python。此外,他们承认,虽然双重记忆系统增强了测试和补丁生成,但由于缺乏用于验证的自动化预言机,缺陷定位仍然是一个挑战,并将其确定为未来工作的方向。
该研究得出结论:不同的修复方法具有互补的归纳偏置;ExpeRepair 在具有重复模式的场景中表现出色,而其他方法(如 DARS)可能更适合需要探索性推理的新颖问题。
每周获取最佳 computer science 论文。
受到斯坦福、剑桥和法国科学院研究人员的信赖。
请查收邮箱确认订阅。
出了点问题,再试一次?
无垃圾邮件,随时退订。