SkillForge:面向项目级 Issue 解决的自蒸馏智能体框架 SkillForge: Self-Distilling Agents for Project-Specific Issue Resolution
让仓库自合成 Issue 并蒸馏项目专属技能,破解 SWE 智能体冷启动
前置知识
SWE-bench 与 Issue 解决
SWE-bench 是 SWE 智能体标准基准:给定仓库引入 bug 前的快照和用户 Issue 描述,智能体自主改代码产出补丁,判定需 FAIL_TO_PASS 转绿且原有测试不回退。Verified 为人工校验的 500 实例子集;Pro 为多语言 731 任务。Pass@1 为一次尝试解决率。
本文所有实验指标(Pass@1、Avg Cost)、评测协议(时间隔离、fail-to-pass)以及合成实例的输出格式都建立在这一基准体系上,不理解它就无法读懂结果表与时间隔离设置。
LLM 智能体脚手架(Scaffold)
智能体脚手架是包裹 LLM 的执行框架,定义工具(bash、编辑器)、观察-行动循环与终止条件。Mini-SWE-Agent 是极简 bash 交互脚手架,智能体仅靠 shell 命令探索修改仓库,动作预算 250 步;脚手架越简单,性能差异越能归因于知识注入而非框架工程。
SkillForge 实现于 Mini-SWE-Agent 之上,其 JIT 技能注入机制直接依赖脚手架的逐步循环(监测每一步 shell 命令访问了哪些文件),理解脚手架才能理解技能如何被实时触发。
自蒸馏(Self-Distillation)
传统知识蒸馏指大模型教小模型;本文语境下的自蒸馏指同一个智能体系统通过解决自己生成的任务,把经验提炼成可复用知识再反馈给自己。关键在于合成任务由'严格掩码重写'产生——LLM 看不到原实现、只凭通用编码知识重建功能,其重写偏差暴露的正是它自身项目知识的缺口,因此蒸馏出的经验天然对准自己的弱点。
这是本文范式的名字与灵魂:知识来源既非历史 Issue 也非人工标注,而是'模型×仓库'碰撞出的自我经验,理解这一点才能把握它与 SWE-Exp、EvoCoder 等被动范式的本质区别。
代码覆盖率与执行轨迹(Coverage & Trace)
在覆盖率插桩下运行一个测试用例,可以记录它实际执行到的源文件与行范围,即执行轨迹。轨迹把'测试要验证的功能'定位到具体代码区域:只有改动这些区域内被执行的代码,才可能影响测试结果。本文用它做两件事——为重写划定候选区域,以及保证合成 bug 的失败证据可被测试观察到。
测试驱动定界是合成管线的第一步,也是'功能级多片段协同重写'的依据;不看懂这一步就看不懂为何 SkillForge 能捕捉跨函数耦合,而 SWE-Smith 只能一次改写单个函数。
BM25 稀疏检索
BM25 是基于词频与逆文档频率的稀疏检索算法,按查询词与文档词的重叠度打分排序,无需向量模型。本文用于宏观初始化:以新 Issue 描述为查询,从全局诊断技能集 $M_{ext}$ 取 top-$k_r$(默认 5)条记录(API 路径、purpose、playbook)拼进初始 prompt。
这是技能在下游生效的入口之一;超参实验($k_r$=0 时 62.3%、$k_r$=5 时峰值 69.7%、全量检索反降到 67.5%)说明检索数量本身就是关键设计变量,而非简单的工程细节。
测试时探索与在线自进化
在线自进化方法(SAGE、SWE-Debate、Live-SWE-agent)解决当前 Issue 时生成多条轨迹、组织辩论或改写脚手架,以推理算力换性能;每 Issue 需重复支付轨迹、token 与时间成本(SWE-Debate 平均 $0.382/实例),经验只在 Issue 到来后才可用。
它是本文的对立范式:SkillForge 用'一次预计算、所有后续 Issue 共享'替代'每 Issue 现场探索',主结果表中 Avg Cost 一列的对比正是围绕这一权衡展开。
研究动机
LLM 智能体(SWE-agent、OpenHands 等)在 SWE-bench 等基准上已能解决真实世界的复杂 bug,但部署到具体项目时存在冷启动问题:在没有项目专属知识之前,再强的智能体也只是一个通用仓库探索者,会反复掉进同一个项目陷阱。真实项目有强结构性规律——反复失败常集中在同样脆弱的模块,正确补丁必须保留仓库特有的 API 约定,相关 API 还通过隐式执行路径相互耦合。现有自进化方法都是被动式获取:历史驱动方法(EvoCoder、SWE-Exp、MemGovern)从历史 Issue、提交或智能体轨迹中蒸馏知识,但学习信号受限于历史轨迹的覆盖面,未被踩过的长尾组件和 API 组合几乎提供不了知识;在线方法(SAGE、SWE-Debate、Live-SWE-agent)在当前 Issue 上做测试时探索,每个目标 Issue 都要付出高昂的轨迹、token 和时间成本(如 SWE-Debate 在 Verified 上平均每实例 $0.382),而且知识要到 Issue 已经到来之后才产生,无法提前武装智能体。
本文的目标是本文的目标是解决项目级 Issue 解决的冷启动问题:不依赖历史 Issue 轨迹的积累,也不为每个真实 Issue 支付在线探索代价,而是在真实 Issue 到来之前,仅从仓库自身的代码与测试套件出发,主动合成一批项目专属的合成 Issue 并让智能体去解决,再把解决轨迹蒸馏为可复用、可检索的项目专属知识;下游解决真实 Issue 时按需注入这些知识,目标是同时提升 Pass@1,并把端到端成本(含摊销后的离线预计算)控制在接近裸智能体的水平。
与已有工作不同的是,独特切入角度是把'获取项目知识'变成'让仓库自己出题考智能体'。SkillForge 不收集历史、不现场探索,而是从测试覆盖的核心功能出发,沿执行轨迹找出共同实现同一功能的多个协同代码段,让 LLM 在严格掩码约束下(看不到原实现,只有前后几行、位置缩进与测试目标)重写这些片段:由于模型只能调用通用编码知识重建功能,重写结果与项目真实约定之间的落差会自然导致测试失败——这个失败正是'通用先验 vs 项目专属行为'差距的可执行暴露。与既有工作相比有两处根本不同:其一,合成 Issue 在这里是知识探针而非训练数据;其二,知识表示从'集中式知识库+语义相似检索'换成'实体锚定技能+按代码交互实时触发',保证指导恰好在智能体到达相关代码时出现。
核心方法
直觉:如果让一个不了解项目的智能体去修一个由'通用编码习惯'引入的 bug,它踩的坑正是它将来修真实 Issue 时会踩的坑——把这些踩坑经历系统蒸馏成技能,就得到最贴合该智能体自身的项目知识。技术路线分四阶段。阶段一,项目专属 Issue 合成:测试驱动定界与轨迹获取、LLM 选择关键片段、严格掩码重写、实例组装成 SWE-bench 格式。阶段二,Issue 解决尝试:SWE 智能体在隔离环境中接收问题陈述与带 bug 的代码库,通过补丁生成、工具执行与测试反馈迭代修复,记录动作轨迹 $T=\{(a_1,o_1),\ldots,(a_n,o_n)\}$,其中 $a_i$、$o_i$ 为第 $i$ 步的动作与环境观察。阶段三,技能蒸馏:将轨迹归一化并与仓库 AST 实体索引对齐,从中蒸馏出互补的两级技能集——全局诊断技能集 $M_{ext}$ 与局部干预技能集 $M_{int}$。阶段四,技能适配:解决新 Issue 前用 BM25 检索 $M_{ext}$ 做宏观初始化,运行中每当访问的文件命中 $M_{int}$ 就即时注入干预提示。
核心创新有三层,每层都与已有方法有本质区别。第一,'自我出题'范式:合成 Issue 不是训练数据而是知识探针——严格掩码重写迫使 LLM 只凭通用编码先验重建功能,重写与原实现的差异精确暴露'通用先验 vs 项目约定'的缺口,因此解决这些合成 Issue 获得的经验天然对准智能体自身的项目盲区,且完全不依赖历史 Issue 或人工标注。第二,功能级协同重写:与 SWE-Smith 一次只重写单个 API 函数不同,SkillForge 从测试暴露的仓库功能出发,沿执行轨迹选出多个自然协同的代码段一起重写,使合成 Issue 能捕获跨组件交互、API 耦合与项目特有的修复陷阱。第三,双重技能表示与实体锚定检索:$M_{ext}$ 用 purpose/playbook/related_apis 三个字段记录'诊断与导航'知识,$M_{int}$ 从成功与失败轨迹的对比分析中蒸馏'修改与避坑'知识;下游检索不靠集中知识库的语义相似,而是由智能体当前访问的代码实体触发,知识在到达相关代码的那一刻才出现,既降低检索歧义又避免上下文噪音。
方法步骤详情
阶段一(合成):对每个通过测试做插桩执行得轨迹,抽取连续代码段,LLM 依测试目的选 top-$k_s$ 个关键片段;严格掩码重写——LLM 只见片段前后几行、缩进与测试目标,产出保持原 API 的替代实现使测试转 FAIL;失败证据转写为不泄露实现细节的问题陈述,组装成 SWE-bench 格式实例(含 base commit、buggy/reference patch 与测试)。阶段二(求解):智能体在隔离环境修复合成 Issue,记录完整轨迹。阶段三(蒸馏):解析 shell 命令得访问坐标,对齐 AST 索引建候选实体集 $E_{cand} \subseteq R$;对每个实体 $\alpha \in E_{cand}$ 蒸馏 purpose/playbook/related_apis 构成 $M_{ext}$,对比成功与失败轨迹蒸馏 intervention_skills 构成 $M_{int}$。阶段四(适配):BM25 取 top-5 条 $M_{ext}$ 拼入初始 prompt;逐步监测 shell 命令,命中 $M_{int}$ 即注入干预提示。
技术新颖性
新颖性体现在四个对比维度。相对历史驱动方法(SWE-Exp、EvoCoder、MemGovern):不受历史覆盖面约束,作者核查发现合成 Issue 类型分布与同仓库真实 SWE-bench Issue 不重叠,学到的是更深层的函数使用偏差,可跨真实 Issue 类别迁移。相对在线方法(SAGE、SWE-Debate、Live-SWE-agent):知识在 Issue 到来前一次性预计算,在线成本接近裸智能体($0.074/$0.066 对 SWE-Debate 的 $0.382/$0.167)。相对 SWE-Smith 等合成数据工作:目的根本不同——不是造训练数据而是暴露特定 LLM 的项目知识缺口;粒度上功能级多片段重写对单函数改写,受控变体仅 68.0%/56.4% 与 68.7%/54.4%,均低于完整版 72.2%/60.6%,证明功能级合成与轨迹蒸馏缺一不可。相对'集中式记忆+语义检索'范式:实体锚定+JIT 注入把检索从语义空间搬到代码交互空间;跨 LLM 实验呈对角线,证明蒸馏物是'某模型×某仓库'的特异知识。
实验结果
RQ1:Verified 上(DeepSeek-V3.2/GPT-5-mini)达 72.2%/60.6% Pass@1,较基线(66.4%/55.0%)+5.8/+5.6 个百分点,成本 $0.074/$0.066;超最强基线 MemGovern +3.0/+2.6 及全部历史/在线基线(含 5 倍成本的 SWE-Debate)。Pro 上 34.1%/51.7%(基线 28.3%/47.6%)。RQ2:去掉 $M_{ext}$ 降 3.8/3.0,去掉 $M_{int}$ 降 4.4/3.4,二者互补;跨 LLM 迁移呈对角线:DeepSeek 用他模型技能跌至 65.2%(低于不用技能),知识不跨模型复用。RQ3:检索数 $k_r$=5 峰值 69.7%(0 时 62.3%、全量 67.5%);重写段数 $k_s$=5 最优、1 仅 63.2%。RQ4:七大仓库无回退,最高 +13.6%/+15.6%(Sphinx/Scikit-learn),SWE-Exp 三仓回退(最差 -11.8%)。案例 django-11206:基线 0/2 失败,技能版 2/2 通过。
查看结构化数据
| 任务 | 指标 | 本文 | 基线 | 提升 |
|---|---|---|---|---|
| SWE-bench Verified(DeepSeek-V3.2) | Pass@1 | 72.2% | Mini-SWE-Agent 66.4% | +5.8 个百分点(p<0.05) |
| SWE-bench Verified(GPT-5-mini) | Pass@1 | 60.6% | Mini-SWE-Agent 55.0% | +5.6 个百分点(p<0.05) |
| SWE-bench Pro(DeepSeek-V3.2) | Pass@1 | 34.1% | Mini-SWE-Agent 28.3% | +5.8 个百分点 |
| SWE-bench Pro(GPT-5-mini) | Pass@1 | 51.7% | Mini-SWE-Agent 47.6% | +4.1 个百分点 |
| SWE-bench Verified(DeepSeek-V3.2) | Pass@1 | 72.2% | 最强历史驱动基线 MemGovern 69.2% | +3.0 个百分点 |
| SWE-bench Verified(DeepSeek-V3.2) | Pass@1 | 72.2% | 在线方法 SWE-Debate 68.2% | +4.0 个百分点,成本 $0.074 vs $0.382(约 1/5) |
局限与改进
作者承认的局限:其一,外部效度——SkillForge 依赖仓库测试来合成 Issue 与蒸馏知识,可运行测试覆盖少的代码区域贡献的学习信号弱,在测试覆盖有限的仓库中效果会打折扣;其二,内部效度——问题陈述由 LLM 从失败证据生成,虽经人工核验不泄露实现细节,但仍可能与开发者撰写的真实 Issue 存在系统性风格差异。我自己的观察:离线预计算虽有摊销但真实存在(Verified 上比裸基线贵约 $0.025/$0.035),且整条管线要求仓库有可运行的隔离测试环境与插桩能力,对环境难构建的大型遗留项目不友好;知识是 LLM 特异的,更换底座模型需完全重新执行合成-求解-蒸馏全流程,无法增量复用;MemGovern 因预处理成本未知被排除在 Avg Cost 对比之外,成本对比的完备性略有折扣;技能库静态、不随仓库演化更新,代码变更后旧技能可能失效但缺少失效检测;技能质量仅靠人工抽查验证,没有自动化质量指标。
独立分析的弱点
(1) 测试依赖是单点故障——UI、配置、集成胶水代码常无测试覆盖,这些知识真空区恰是真实 Issue 高发区;可用变异测试或 LLM 生成 property-based 测试补充弱覆盖区域。(2) 严格掩码重写的缺陷分布未必等于真实开发者缺陷分布——LLM 重写倾向'规范但不符合项目惯例'的实现,蒸馏教训可能偏风格纠正而非真 bug;可用历史 commit 的真实 bug patch 校准重写策略。(3) 模型特异性使知识无法共享复用,换模型需全量重跑合成与求解,成本线性增长;可把技能拆为'仓库事实'(跨模型共享)与'模型偏差教训'(按模型索引)分别存储。(4) 检索机制简单:$M_{ext}$ 靠 BM25 词面匹配、$M_{int}$ 靠文件路径精确命中,缺乏重要性加权与冲突消解,全量检索掉点已预示低质技能会挤占上下文;可加技能有效性验证与置信度排序。(5) 技能库静态、不随仓库演化更新,长期运行必然陈旧;可结合增量 commit 流式更新与失效淘汰。
未来方向
作者明确提出的方向主要是拓展到测试覆盖有限的仓库(应对外部效度威胁)。基于成果可自然延伸的研究:(1) 把自蒸馏从上下文注入升级为参数化学习——用合成轨迹做 SFT 或构造 RL 奖励信号,把技能内化进模型权重,摆脱上下文窗口限制;(2) 跨仓库元技能:在多个仓库上蒸馏后抽象出通用 SWE 启发式,新仓库冷启动时只需少量合成即可完成 bootstrap;(3) 主动+被动混合进化:日常运行中把真实 Issue 的解决轨迹持续并入技能库,与合成知识做冲突消解和置信度融合;(4) 技能生命周期管理:自动评估每个技能在留出合成 Issue 上的边际增益,做剪枝、合并与过期检测;(5) 扩展到无测试或弱测试生态(多语言 monorepo、遗留系统),结合 Repo2Run 类环境自动构建方法;(6) 多模型协作蒸馏:用便宜模型生产'仓库事实'技能、强模型生产'推理策略'技能,降低预计算成本;(7) 把合成-Issue 机制用于对抗性基准增强,检验智能体对项目知识的真实掌握程度。
复现评估
复现条件较好:代码与数据开源于 github.com/cslsolow/SkillForge;脚手架 Mini-SWE-Agent 开源;两个底座模型(DeepSeek-V3.2、GPT-5-mini)均可 API 调用;基准 SWE-bench Verified(500 实例)与 SWE-bench Pro(731 实例)公开。关键超参已完整给出:temperature=0、250 步动作预算、BM25 top-5、重写段数峰值 $k_s$=5,Pass@1 为三次运行平均;时间隔离协议(回滚到 golden patch 之前、LLM 先筛选相关测试、再合成 577 个 Issue)也有描述。主要工程难点在于为每个目标仓库构建可运行的隔离测试环境并做覆盖率插桩,这一步最耗时耗力,也是对低测试覆盖仓库的硬约束;其余阶段是纯 API 调用(DeepSeek 成本低),无需训练 GPU。总体难度中等偏高:管线阶段多(合成→求解→蒸馏→注入),单仓库端到端预计算需要一定 API 预算,但方法不涉及任何微调,学术实验室可以复现。
论文图表
(a) 检索数 $k_r$ 从 0 到 7 及'全量'条件的 Pass@1 曲线:0 时 62.3%,$k_r$=5 达峰值 69.7%,全量检索回落至 67.5%,Django 与 Sphinx 两个仓库趋势一致;(b) 合成时重写代码段数 $k_s$ 从 0 到 7:0(等价于基线)62.3%,$k_s$=1 升至 63.2%,$k_s$=5 峰值,$k_s$=7 略降。
直接给出两个关键超参的甜点位置与'过多知识反而有害'的证据,是对复现最有实用价值的图。
500 实例上各方法在两个底座下的 Pass@1 与摊销平均成本:SkillForge 达 72.2%/$0.074 与 60.6%/$0.066,领先全部历史驱动方法(SWE-Exp 69.0%/56.6%、EvoCoder 67.0%/58.4%、MemGovern 69.2%/58.0%)与在线方法(SAGE、SWE-Debate、Live-SWE-agent),两个受控变体(SWE-Smith 版 68.0%/56.4%、LLM Summary 版 68.7%/54.4%)显著更低,多数增益 p<0.05。
主结果表,同时承载'对全部基线的范式对比'与'两个受控变体的内置消融',是论文核心证据。
731 个多语言长程实例上 SkillForge 达 34.1%/$0.069(DeepSeek-V3.2)与 51.7%/$0.087(GPT-5-mini),比 Mini-SWE-Agent(28.3%/$0.047、47.6%/$0.063)高 +5.8/+4.1 个百分点,超过 Live-SWE-agent(32.4%/49.1%)与 SWE-Exp(29.4%/48.7%)这两个该基准上可用的最强基线。
证明增益在更长程、多文件、多语言的困难设定下依然成立,说明方法不是只在 Verified 上过拟合。
组件消融:去掉全局诊断技能 $M_{ext}$ 后降至 68.4%/57.6%(-3.8/-3.0),去掉局部干预技能 $M_{int}$ 后降至 67.8%/57.2%(-4.4/-3.4),完整版为 72.2%/60.6%,说明两级知识各自必要且互补。
直接支撑双重技能表示这一核心设计,回答'为什么需要两级技能而不是只要一种'。
2×2 交叉实验(求解模型 × 知识来源模型)呈清晰对角线:DeepSeek-V3.2 用自家蒸馏技能 72.2%、换用 GPT-5-mini 技能跌至 65.2%;GPT-5-mini 用自家技能 60.6%、换用 DeepSeek-V3.2 技能跌至 55.0%,说明蒸馏出的项目专属知识是 LLM 特异的,不能跨底座复用。
揭示知识模型特异性这一关键发现,对技能库的构建与复用策略有直接指导意义。