按原样复用具体的修复
具体步骤可以直接照做,但可能只适用于密切相关的 issue。新 issue 也许需要过去修复中的定位策略,却不需要其中针对该仓库的编辑;原始轨迹还夹杂着工具输出、失败的尝试和重复的动作。
- Remove the “Add” button
- User still added items
- Checked why it still worked
- Found a hidden shortcut
Reusing Past Repairs Through Hierarchical Trajectory Abstraction for Coding Agents
修复智能体已经能够解决代码仓库级的 issue,但许多智能体仍把每个 issue 当作孤立的任务来处理。STAIR 复用以往成功修复中的做法:它把每条修复轨迹按阶段切分,把其中的每个过程保留为多个粒度的修复配方(repair recipe),从针对特定仓库的具体步骤到宽泛的策略;再把适用于新 issue 的配方改写成每个修复阶段的计划。
1SPEAR Lab, Concordia University, Montreal, Canada · 2Waterloo Research Center, Huawei, Canada · 3Huawei Technologies Co., Ltd.
有经验的开发者会复用以往有效的做法:定位策略、编辑步骤、验证步骤。
这些知识存在于不同的粒度上。具体的过程,例如检查某个配置文件,可以直接照做,但可能只适用于密切相关的 issue。更宽泛的策略,例如从故障点沿数据流反向追踪,迁移范围更广,却较少告诉智能体下一步该做什么。已有的复用历史修复的智能体(Lingxi、SWE-Exp、ExpeRepair)在提取知识时就固定了单元和粒度:整次修复、阶段级经验,或者一个示范加上抽象洞见。它们都没有把一次过去的修复拆成各自独立的过程,并把每个过程保留为多个详略层次。
具体步骤可以直接照做,但可能只适用于密切相关的 issue。新 issue 也许需要过去修复中的定位策略,却不需要其中针对该仓库的编辑;原始轨迹还夹杂着工具输出、失败的尝试和重复的动作。
宽泛的策略能迁移到更多 issue,但可能省略了让策略奏效的动作,包括密切相关的 issue 所需要的步骤。它对智能体下一步该做什么的指导也更少。
Always enforce intent at every system layer, not just at the visible entry point.
STAIR 由三个环节组成。环节 1 离线运行,在任何目标修复开始之前只执行一次。环节 2 和 3 针对每个新 issue 运行,并分别作用于三个修复阶段:定位、规划、执行与验证。修复配方(repair recipe)是从过去修复中提炼出的可复用过程或策略;修复计划(repair plan)则把选中的配方落实到目标 issue 上。
怎么读自上而下,顺着箭头看。环节 1 把一个已解决 issue 的轨迹转化为低、中、高三层配方,并全部存储。环节 2 为新 issue 检索来自不同历史 issue、不同粒度的配方,并组合成一份计划;计划的每一步都注明来自哪些配方。环节 3 把计划交给修复智能体。
图中要点没有哪个层次能取代其他层次:计划的第二步来自一个中层配方,第三步来自两个不同 issue 的一个高层配方和一个中层配方。图为论文图 1;配方构建、检索和计划生成都按修复阶段分别进行。
STAIR 在同一仓库较早的 issue 上运行 Lingxi 的修复脚手架(关闭其知识复用机制),保留成功修复的轨迹。每条轨迹按修复阶段切成三个有序片段:τ(u) = ⟨τloc, τplan, τexec⟩。在一个片段内,LLM 算子 Gℓ 把服务于同一修复目的的连续步骤分为一组,算子 Aℓ 再把每组抽象为一条配方。随后对配方再次分组和抽象,直到最多剩下 K = 2 条。每一层都会保留。
配方按片段分别构建,之后也按片段分别检索。下方展示其中一个片段,对应论文中的示例。
每一层的每条配方都有这些字段,只是具体程度不同:低层配方可以写出具体的 API,高层配方必须完全通用。配方用 GPT-5 一次性构建,来自 479 条历史轨迹(每条约 $0.44,共约 $211),所有配置共用。
对新 issue u 和每个阶段 s,所选历史修复中阶段 s 的每条配方都是候选,不论粒度。STAIR 按与 issue 报告的余弦相似度(Qwen3-Embedding-8B)把它们排进同一个列表,再由 LLM 验证器剔除在该阶段不适用的配方。保留下来的集合 Rs(u) 可以混合不同粒度和不同来源 issue。随后由 LLM 写出阶段计划 Ps(u) = Plan(u, Rs(u)):保留适用的指导,去掉无关或相互冲突的部分,并把互补的配方组合成针对该 issue 的动作序列。
Make the form edit-only, no new entries allowed
示例来自论文图 1。检索只使用 issue 报告;计划中与仓库相关的细节,由修复智能体在探索目标代码库时核对和调整。
每份计划在对应阶段交给修复智能体。智能体仍会探索仓库、修改代码、运行检查并响应测试反馈;当新证据与计划冲突时,它可以修正自己的决定。底层智能体仍负责构造并验证最终的补丁。
引导智能体关注相关的失败证据和候选代码位置。
描述预期的修改策略、修复范围和相关约束。
建议实施修复以及检查修复的步骤。
保留其决策逻辑、工具和三阶段修复流程;关闭原有的知识复用机制,每个阶段的 prompt 中加入该阶段的 STAIR 计划。
一个只使用 bash 的极简智能体。计划以 <external_reference_plans> 块的形式加在输入前面;其源代码、工具定义和验证逻辑保持不变。
所有实验都在 SWE-bench Verified 上进行:来自 12 个 Python 仓库的 500 个真实 GitHub issue,每个都由开发者编写的测试检验。Pass@1 是单次智能体运行的最终补丁所解决的 issue 比例。实验使用两个基座模型,均开启高推理强度(HR):GPT-5(商用)和 MiniMax M2.5(开放权重)。对每个目标 issue,历史 issue 来自同一仓库、创建时间早于它,并且与评估实例不重叠。
怎么读各行按基座模型分组,因此组内只有智能体不同;论文表 2 按智能体类型列出同样的数字。深灰色的 Lingxi 是受控对比:脚手架、基座模型、工具和历史 issue 都相同,只是用其原有的知识复用机制代替 STAIR 的配方和计划。Claude 4 Sonnet 一组是基座模型不同的报告结果,这组比较的受控程度较低。
图中要点STAIR 在 MiniMax M2.5 上达到 81.2%,在 GPT-5 上达到 79.2%,在论文报告的设置下高于所有对比的智能体。只改变知识复用机制,在 MiniMax M2.5 上提升 6.6 个百分点,在 GPT-5 上提升 3.6 个百分点;GPT-5 下 Lingxi 的基线更高,提升空间可能更小。在相同的基座模型下,STAIR 比 OpenHands 高 7.4 个百分点,比 live-SWE-agent 高 10.8 个百分点,比 mini-SWE-agent v2 高 5.4 个百分点。
怎么读mini-SWE-agent v2 有自己的架构、工具接口和提示策略。唯一的改动是在输入前加上 STAIR 计划块,这些计划由基于 Lingxi 轨迹构建的配方生成。数据来自论文表 3,覆盖全部 500 个实例。
图中要点Pass@1 从 75.8% 升到 81.0%(+5.2 个百分点),接近 STAIR 在 Lingxi 脚手架上的结果(81.2%)。平均步数从 60.45 降到 58.18,每个实例的 token 用量减少 5.2%:计划并不只是增加上下文,智能体的探索也减少了。这是对另一个脚手架的证据,并不说明适用于所有智能体脚手架。
基线修改了错误的组件,且无法从这一早期错误中恢复;计划从一开始就把智能体引向正确位置,例如修复上游的序列化器,而不是下游的加载器。
基线找到了根因,却只修改了部分受影响的代码。在 django-11138 中,它修复了 MySQL 和 Oracle 的时区转换问题,漏掉了 SQLite;计划把它定义为一次跨后端排查。
基线改动的代码多于必要;计划把修复限制在最小改动内,例如扩展一个匹配条件,而不是重写整个发现流程。
计划把握住了主要方向,但没有覆盖所有改动;通常是修复需要在多个文件或入口点上协同修改。其中 5 个来自 STAIRMiniMax,3 个来自 mini-SWE-agent v2 + Plans。
智能体偏离计划、做了不必要的复杂修改,或者犯了局部错误,例如用错 API 或传错参数。其中 5 个来自 STAIRMiniMax,4 个来自 mini-SWE-agent v2 + Plans。
怎么读“新增解决”指只有加入 STAIR 计划后才解决的实例;“退化”指只有基线解决的实例(STAIR 的基线是 Lingxi,加计划版本的基线是原版 mini-SWE-agent v2)。两位作者根据每个实例的计划、补丁和完整轨迹分别标注,再讨论分歧达成一致(Cohen's κ = 0.85)。
图中要点新增解决多于退化:43 比 10,33 比 7。每个智能体都在自己最薄弱的地方获益:Lingxi 已有显式的定位阶段,所以计划主要是扩大修复范围(Partial Fix,49%);只用 bash 的 mini-SWE-agent v2 最常从错误的位置入手,所以计划主要是把它引到正确位置(Wrong Location,52%)。在 17 个退化中,8 个源于计划遗漏了部分所需范围;其余 9 个是计划合适但执行失败。
怎么读每个变体只改变复用的内容。这 125 个实例按难度分层抽样:92 个(73.6%)为中等或困难,估计修复时间至少 15 分钟;33 个(26.4%)为简单。该子集侧重较难的 issue,因此在完整基准上的差异可能不同。
图中要点完整候选池解决了 125 个中的 100 个(80.0%)。只从单一粒度检索会损失 16.0 到 21.6 个百分点;三者中低层配方最好,可能因为它们更可直接执行,但仍落后 16.0 个百分点。复用原始轨迹的结果最低,为 57.6%。这些结果支持把配方保留为多个粒度,并针对每个 issue 和阶段从中选择。
以下局限均由论文本身指出,上面的数字应在这些范围内理解。
SWE-bench Verified 包含来自 12 个仓库的 500 个 Python 实例。结论未必适用于其他语言、基准或私有代码库。
配方来自 Lingxi 的轨迹,换一个来源智能体,轨迹质量可能不同。RQ2 显示计划可以迁移到 mini-SWE-agent v2,但不代表其他脚手架。
分组、抽象和相关性验证器都基于 LLM;配方质量可能随轨迹长度变化,验证器也可能丢掉有用的配方或保留不适用的配方。RQ3 的标注涉及主观判断(κ = 0.85)。
Pass@1 依赖已有的测试,可能接受行为上不正确的补丁。两个基座模型不能说明其他模型也有同样收益。RQ4 使用的子集偏向较难的 issue。
请引用 arXiv 预印本。
@misc{xu2026reusingpastrepairshierarchical,
title = {Reusing Past Repairs Through Hierarchical Trajectory
Abstraction for Coding Agents},
author = {Yisen Xu and Jiayuan Zhou and Ruiqi Pan and Tse-Hsun Chen},
year = {2026},
eprint = {2607.29658},
archivePrefix = {arXiv},
primaryClass = {cs.SE},
url = {https://arxiv.org/abs/2607.29658}
}