FailForge:从顽固失败中提炼排查方法论,SWE-bench基准提升6.6分

FailForge: Distilling Procedural Competence from Persistent Failures into Code Agents

论文原文 ↗ 论文发布 解读发布 解读:AI前沿分享

在以软件工程为代表的复杂长程任务中,基于执行反馈的拒绝采样微调(Rejection Sampling Fine-Tuning,简称 RFT)已成为训练代码智能体(Code Agent)的核心手段。这种方法在大规模任务库中反复采样探索,通过测试用例验证的成功轨迹被悉数保留,作为有监督微调的数据源;而未通过测试的轨迹,通常会被系统直接丢弃。然而,代码智能体在最棘手的真实世界软件缺陷上往往表现出连续的、全盘的失败,常规 RFT 简单粗暴的“全丢弃”机制,导致耗费巨大推理开销采出的边缘难例无法贡献任何有效梯度。

ArXiv URL:https://arxiv.org/abs/2608.08570v1

这些屡战屡败的顽固失败任务(Persistent Failures),恰恰处于模型当前能力的最前沿边界,是构建下一代更强智能体最稀缺、信息量最大的金矿。来自西安交通大学与未来智能实验室的研究团队在论文《FailForge: Distilling Procedural Competence from Persistent Failures into Code Agents》中指出,盲目堆叠采样预算不仅无法解决顽固失败,还会带来巨大的算力浪费;智能体反复碰壁的根源,往往不是缺失某个特定代码仓库的局部知识,而是缺乏跨仓库通用的“程序化排查能力”(Procedural Competence)。为此,团队提出了名为 FailForge 的智能体自愈蒸馏框架,将原本注定被丢弃的失败样本重新激活为高价值训练数据。

实验表明,FailForge 成功挽回了超过 26% 连试数次均彻底失败的难题。在 SWE-bench Verified 基准上,基于该方法增广微调的 Qwen3.5-4B 模型实现了 6.6 个百分点的 resolve rate 显著跃升,且在多语言代码环境及不同智能体脚手架(如 Claude Code)上展现出高度稳健的迁移泛化能力。

技能引导恢复失败轨迹

RFT的边界瓶颈与“无效重试”陷阱

理解 FailForge 的设计初衷,需要先看清现有代码智能体后训练范式的结构性缺陷。在标准的 RFT 流水线中,每个任务通常会被分配固定的采样轮次(例如 $K=5$ 次 rollout)。只要其中有任意一次通过测试,该轨迹就被记入正样本集合;但如果 5 次尝试全军覆没,这个任务在本次训练迭代中的贡献度便直接归零。

在强化学习和策略优化中,这被称为“零信号困境”。为了解决这一问题,直觉上的首选做法是加大计算预算,把每个任务的重试次数从 5 次翻倍到 10 次。但实验给出了残酷的结论:盲目增加无引导的采样轮次,能够挽回的失败样本极为有限。因为在真实复杂的软件工程场景中,失败往往不是由于随机探索带来的方差波动,而是因为智能体根本不知道如何有条不紊地定位断点、理解庞大的跨文件调用链,或是设计合规的测试闭环。

学术界过去曾尝试通过细粒度信用分配来利用负样本,例如在失败轨迹内部挖掘有用的单步动作、在反向传播时掩盖错误步骤的损失、或是将错误轨迹与正确步骤拼接。但这类方法在长上下文、稀疏奖励的代码任务中极易失效。代码智能体的排查过程动辄包含数十步工具交互,某个早期步骤可能只是漏读了一个并不显眼的配置文件,导致后续的所有修改顺序彻底颠倒;在单步层面,每一步工具调用的语法和逻辑看似都毫无瑕疵,传统的步级归因很难从这种“慢性失误”中榨取价值。

论文作者洞察到,智能体在难题面前频频受挫的核心短板,是一种可以跨仓库复用的“程序化能力”。优秀的人类工程师在面对陌生代码库时,拥有一套高度抽象的方法论:把现有测试套件视为接口的显式契约、在修改一个核心标识符时排查所有下游依赖方的导入可见性、在修改逻辑前先写出可复现异常的微型测试用例。正是这种高阶排查策略的缺失,构成了模型跨越能力鸿沟的真正阻碍。

FailForge框架:从失败诊断到去支架内化

针对上述洞察,FailForge 构建了一套环环相扣的闭环系统,旨在将失败轨迹诊断为可复用的策略,再利用该策略引导智能体生成合规轨迹,并最终将这一过程“无缝内化”进小模型的权重之中。

FailForge整体架构流程

整个流程由五个严密的阶段组成,其核心设计既保证了引导策略的高抽象度,又杜绝了信息泄露带来的虚假繁荣:

第一阶段为初始筛选与顽固失败集锁定。给定任务池,教师策略(实验中采用基于 Kimi-K2.6 与 OpenHands 构建的智能体)对每个任务执行标准采样与测试验证。一次性全部失败的任务被精确聚合成顽固失败集合 $\mathcal{F}$。在 SWE-Gym 的 2,401 个 Python 真实任务中,有多达 832 个任务属于此类无论如何重试都无法解决的硬骨头,而 FailForge 的后续处理完全针对这 832 个任务展开。

第二阶段为智能体技能归纳(Agentic Skill Induction)。对于顽固失败集中的任务,系统指派诊断智能体复盘之前的全部失败轨迹、工具调用回显、测试报错信息以及离线参考补丁(Gold Patch)。需要特别强调的是,诊断智能体并不是输出一段随意的自然语言反思,而是必须遵循极其严格的四元结构规范:

  1. 适用条件(Applicability Condition):清晰界定该排查技能在何种代码场景与问题模式下生效。

  2. 核心原则(Key Principles):明确修复方案必须坚守的软件工程不变量。

  3. 常见陷阱(Common Pitfalls):提炼可能导致同类探索走入死胡同的典型误区。

  4. 推荐路径(Recommended Approach):给出一套有序的、先验证后修改的高阶调查方案。

这一结构输出的技能被严格限制在方法论层面,严禁出现任何具体的函数名、文件名或针对该特定 Bug 的具象答案,确保其具备高度通用性。

第三阶段为关键的防泄露过滤(Leakage Filtering)。虽然离线训练环境可以访问参考补丁,但如果生成的技能中无意夹带了具体补丁的实现细节,引导重测就会退化为简单的“照抄答案”,丧失方法论指导的本质。FailForge 引入经过人类标注严格校准的大模型作为独立裁判,判定技能是否泄露了特定实现的细节。未通过审核的技能会被强制重新生成直至合规。

第四阶段为技能引导的重采样(Skill-guided Re-rollout)。将审核通过的高阶技能直接注入教师智能体的上下文环境(例如 OpenHands 的系统提示词或 Claude Code 的配置文档中),使教师模型在获得方法论启发的状态下对原失败任务发起第二轮求解。得益于搜索空间的收敛与排查路径的规范,原先无法逾越的顽固任务被大量攻破。

第五阶段为去支架内化与学生微调(Skill Removal and Training)。这是 FailForge 区别于传统外挂记忆库智能体的精髓所在。所有由技能引导成功生成的新轨迹,在送入学生模型进行微调之前,必须经历剔除算子的处理:注入的技能文本被彻底剥离,而智能体自身展现出的深思熟虑、工具交互与精确修改记录被原汁原味地保留。学生模型(如 Qwen3.5-4B 和 9B)仅以原始的问题描述和代码库为输入,以剥离提示后的高质量轨迹为目标进行常规极大似然训练。这意味着,引导策略的“脚手架”在训练完成的一刻被完全拆除,学生模型必须把这种从容、严谨的排查行为真正内化在自身的神经网络参数中,推理时无需依赖任何外部检索机制或外挂提示词。

实验结果:用更低的Token成本撬动更大的能力边界

为了验证这套机制的实际效能,研究团队在标准评测集 SWE-bench Verified 以及考察跨语言分布外迁移的 SWE-bench MultiLingual 上进行了多维度对比。

在 SWE-bench Verified 评测中,基准 RFT 模型在 Qwen3.5-4B 尺度下的 pass@1 表现为 59.6%。当简单采用翻倍采样的“RFT + More Sampling”策略时,成绩仅微增至 61.4%,证明盲目重采样在顽固难例面前收益迅速递减;而采用直接生成实例级线索提示的“RFT + Hint”方案,得分为 62.8%。相比之下,FailForge 训练出的 4B 模型一举达到了 66.2% 的 pass@1,相比标准 RFT 基线实现了 6.6 个百分点的绝对增长。在规模更大的 Qwen3.5-9B 模型上,FailForge 同样将指标从 63.6% 刷新至 67.2%,在多次重试的 pass@5 评测中更是高达 77.0%。

在多语言基准 SWE-bench MultiLingual 上的表现进一步证实了该能力的通用性。虽然所有技能归纳和轨迹回收都仅发生在纯 Python 的 SWE-Gym 数据集上,但内化了通用排查程序的小模型在非 Python 任务上同样迎来了水涨船高式的进步,4B 和 9B 模型的 pass@5 分别冲上了 70.7% 和 74.0%,表明程序化思维的内化并未局限于特定的语法规则。

更令人印象深刻的是 FailForge 展现出的极高成本效益。直观上看,提炼高阶技能并进行大模型裁判过滤会引入额外的前期计算开销。然而分析表明,在处理 832 个顽固任务时,FailForge 每挽回一个百分点的 pass@1 提升,仅需消耗 21.2 亿教师模型 Token;相比之下,实例级线索提示方案需要 30.1 亿 Token,而翻倍采样方案更是高达 43.2 亿 Token。之所以能够实现逆势节能,核心原因在于 FailForge 回收的轨迹质量奇高,其下游训练转化率远非一般正样本可比。

为了更严谨地排除“数据量增加带来自然收益”的干扰,作者设计了一组等数据量替换实验。保持微调数据总量绝对恒定,随机抽取一部分原本的普通 RFT 成功轨迹,替换为等量由 FailForge 从顽固失败中挽回的轨迹。结果显示,微调后的模型 pass@1 从 59.6% 跃迁至 63.8%。这一对比强有力地证明:不仅是样本数量的增加在起作用,这些来自能力边界、经过方法论引导而破局的高难度轨迹,其单样本的信息熵与监督价值显著超越了普通任务。

为什么有效?行为解构与跨实例迁移验证

为了探究模型能力提升背后的深层逻辑,论文从多个微观视角剖析了 FailForge 所赋予智能体的具体行为特征。

首先是跨 Harness 迁移。智能体在训练时所接触的轨迹全部来自 OpenHands 框架,如果在推理时切换到结构完全不同的智能体架构(例如 Claude Code),模型是否会因过拟合特定的接口格式而崩溃?作者在混合了少量 Claude Code 格式轨迹作为格式底座的前提下进行测试,结果表明,FailForge 依然在 Claude Code 环境下保持了最高的解决率(Verified 上达到 62.6%),说明模型学到的是高阶的代码审视与排查思路,而非单纯记忆某些工具调用的表层字符串。

其次是极富启发性的跨实例技能洗牌实验(Guidance Shuffling)。在拥有至少两个顽固失败任务的同一个代码仓库中,研究者对比了四种引导方式对解决问题的挽回率:使用自身生成的 Hint、自身生成的 Skill、来自同仓库另一个任务的 Hint、以及来自同仓库另一个任务的 Skill。数据呈现出惊人的反差:

这一对照深刻证明了二者的本质区别:具象的 Hint 是针对单一 Bug 的“孤立解药”,一旦脱离特定代码上下文便沦为毫无用处的噪声;而 FailForge 归纳出的 Skill 则是真正的“排查方法论”,它教导模型以合乎工程规范的严谨节奏审视架构,因此在面临不同问题时依然能发挥巨大威力。

深入智能体的单次执行行为日志可以发现,经 FailForge 训练后的模型在行为模式上展现出了显著的成熟度。它在定位核心缺陷文件时的精确度远超基线,尤其是在面对那些最终未被攻克的难题时,其文件定位精准率依然显著高于其他模型,说明智能体即使未能完全修好 Bug,探索方向也没有发生漫无目的的严重偏离。同时,智能体在动手修改前运行复现代码的比例大幅攀升,而总体的编辑修改轮次中位数明显下降。这印证了人类工程师常说的“想清楚再动手”——智能体不再频繁盲改,而是转向一种谋定而后动、先复现再验证的工程直觉。

在技能合成的消融分析中,论文还揭示了一个颇具警示意义的反直觉细节:如果刻意使用重写模型把含有外部启发痕迹的思考链重新润色,使其读起来像是模型“从头自发推导出来的”,模型的最终效果反而会从 66.2% 急剧下滑到 62.0%。作者指出,粗暴的轨迹重写往往会破坏智能体真实而宝贵的排查推演节奏;只要剥离外挂技能文本本身,保留那些在良好引导下自发延展出的行动与审视过程,就足以让神经网络通过自回归监督学到最精纯的系统化问题求解能力。

对代码智能体演进的启示

FailForge 的探索对当前大模型后训练与智能体系统设计具有极强的范式参考意义。

它打破了长期以来将合成数据微调与测试时搜索简单割裂的惯性思维。在主流观念中,复杂的推理策略、自省机制与反思记忆库往往被视作推理端(Inference-time)的外挂组件;但外挂组件不可避免地受制于检索召回率的波动、上下文窗口的剧烈膨胀以及巨额的额外推理延迟。FailForge 展现了一种更加优雅的演进路径:将强大的智能体诊断与反思作为离线合成阶段的“孵化器”,在生成优质解题示范后,通过“去支架化”将高阶能力直接压缩回基础模型的权重内部。

随着基础模型在常规任务上的饱和,未来模型性能的角逐将不可避免地全面聚焦在长尾、棘手的极难样本上。如果继续沿用“做不对就丢掉”的传统 RFT 思路,数据飞轮的转速必然会随着基底模型能力的增强而迅速放缓。FailForge 证明,每一次顽固的失败都是高价值信号的载体;通过结构化诊断将具体的工程挫折提炼为通用的方法论,让模型从小样本的高难度反思中完成自我超越,正在成为推动下一代自主代码智能体突破能力边界的高效范式。