12866 字
64 分钟
20260419-SE-Agent Self-Evolution Trajectory Optimization in Multi-Step Reasoning with LLM-Based Agents
2026-04-19

相关链接:

arXiv 原文

Abstract#

image.png

基于大型语言模型的代理最近通过与其环境的多步交互,在复杂推理和工具使用方面展现出了令人印象深刻的能力。虽然这些代理有潜力处理复杂任务,但它们的问题解决过程——即代理完成任务所需的交互轨迹——仍未得到充分利用。这些轨迹包含了丰富的反馈信息,可以引导代理朝着正确方向解决问题。尽管主流方法(如蒙特卡洛树搜索)能有效平衡探索与利用,但它们忽略了不同轨迹间的相互依赖性,且缺乏搜索空间的多样性,导致推理冗余和结果次优。为了解决这些挑战,我们提出了SE-Agent,一个使代理能够迭代优化其推理过程的自进化框架。我们的方法通过三个关键操作:修订、重组和优化,来重新审视并增强先前的引导轨迹。这种进化机制带来了两个关键优势:(1) 通过智能地探索由先前轨迹引导的多样化解决方案路径,它扩展了超越局部最优的搜索空间;(2) 它利用跨轨迹的启发来有效提升性能,同时减轻次优推理路径的影响。通过这些机制,SE-Agent实现了持续的自进化,逐步提高推理质量。我们在SWE-bench Verified上评估SE-Agent,以解决真实的GitHub问题。在五个强大的LLM上的实验结果表明,集成SE-Agent在SWE-bench Verified上带来了最高55%的相对提升,在所有开源代理中实现了最先进的性能(在Claude-3.7-Sonnet上为61.2%,在Claude-4-Sonnet上为80.0%1)。

1. Introduction#

大型语言模型在广泛领域展示了卓越的能力,从复杂的自然语言理解到高质量的代码生成。除了其核心的语言和推理能力外,最近的进展表明,当与外部工具和环境交互能力集成时,这些模型可以演变为自主代理,处理日益复杂的现实世界任务。

然而,完成复杂任务很少能一步到位。在实践中,大多数基于LLM的代理采用与其环境的多轮交互,遵循如ReAct这样的框架,迭代地收集信息、推理当前状态并采取行动。这些交互过程自然形成了轨迹——状态和动作的序列,编码了有价值的问题解决模式和策略。每条轨迹代表了解决给定问题的一次完整尝试,不仅包含最终解决方案,还包含导致该结果的推理路径、环境反馈和决策过程。

尽管这些交互轨迹中包含丰富的信息,但当前的多步推理方法仍然存在根本性的局限。虽然像蒙特卡洛树搜索这样的方法能有效平衡探索与利用,但它们将轨迹视为独立的实体,忽略了不同解决方案路径之间丰富的相互依赖性和潜在协同作用。此外,即使采用多样化的采样策略(例如,改变温度参数或提示),代理也倾向于收敛到结构相似、仅在表层表达上有所不同的轨迹,导致一个关键现象:尽管生成了多条轨迹,最终结果却惊人地同质化。这种局限性源于概率语言模型的固有性质,它们自然趋向于高概率的解决模式,从而限制了搜索空间的多样性。

为了克服这些限制,我们提出了SE-Agent,一个自进化框架,使代理能够通过系统的轨迹操作来迭代优化其推理过程。我们的关键见解是,通过在轨迹层面主动干预——而不仅仅是调整采样策略——我们可以引导代理探索根本不同的视角和解决方法。通过三个核心操作(修订、重组和优化),SE-Agent不仅生成真正多样化的轨迹,而且产生相应多样化的结果,显著扩展了候选解空间。这种轨迹层面的干预使代理能够发现传统采样方法可能无法涌现的新颖问题解决能力,有效地让基础模型超越其初始性能边界。通过策略性地结合来自多条轨迹的洞察,我们的框架增加了找到复杂问题正确解决方案的可能性,而这些问题通过传统的多次采样方法是无法解决的。我们的贡献总结如下:

我们引入了一个新颖的自进化框架,在轨迹层面操作以增强推理能力。重要的是,只要复杂任务仍然需要多步推理——这在可预见的未来可能是一个持续的要求——我们的方法无论基础模型能力如何提升都保持有效。通过操作轨迹而非依赖采样变异,我们在解决方案路径和最终结果上实现了真正的多样性。我们在SWE-bench Verified上进行了全面的实验,这是代码相关任务中最具挑战性和广泛采用的基准之一。我们的结果证明了SE-Agent在不同LLM上的显著性能提升,验证了在真实世界软件工程场景中轨迹层面自进化的有效性。

2. Related Work#

Code Agents 代码代理代表了一类专门的LLM系统,旨在自主理解、生成和操作源代码。随着时间的推移,这些代理已经发展到能够处理大规模代码库中日益复杂的软件工程任务。给定仓库级别的目标,它们识别相关文件和代码段,然后进行必要的修改。在这项工作中,我们专注于SWE-bench任务,该任务涉及通过自动应用功能性错误修复来解决真实的GitHub问题。通过SWE-Agent引入了代理-计算机接口的概念,而OpenDevin提出了一个社区驱动的代理集合,包括CodeAct。Agentless使用简化的两步定位和修复流程实现了竞争性能。AutoCodeRover结合了先进的代码分析技术,包括抽象语法树和基于频谱的故障定位。阿里巴巴玲码Agent提出了一种基于搜索的仓库探索策略,随后进行结构化编辑。此外,几项研究表明,即使在相同的代理配置下,重复的轨迹采样也可能导致结果的显著差异。最近,SWE-Search提出了一个集成了MCTS和自我改进机制的多代理框架,以增强在此类任务上的性能。

Agent Capability Enhancement 近期研究开发了多种方法来增强基于LLM的代理的性能。像GoalAct这样的规划框架引入了带有层次化执行的全局规划,在LegalAgentBench上将复杂性和适应性提高了12.22%。对于代码生成,RGD框架利用多代理调试进行迭代优化,在HumanEval和MBPP数据集上分别优于最先进的方法9.8%和16.2%。像Collaborative Voyager这样的协作方法使代理能够相互通信和学习,有效地解决幻觉问题,同时提高任务完成度。通过MPO进行的元规划优化提供了高级指导,并根据执行反馈持续优化计划,显著提高了任务效率和泛化能力。像AutoGPT和AgentGPT这样的代理增强方法集成了工具使用来扩展代理能力,而像MemGPT和ReAct这样的检索增强框架通过记忆机制增强了上下文理解。包括Reflexion和CRITIC在内的自我改进技术使代理能够通过自我批评迭代地完善其推理。虽然这些方法显示出潜力,但我们的工作在ReAct范式内引入了一种新颖的方法,结合了关键步骤的战略性反思和变异,结合多条轨迹生成优化的执行路径,而不需要像测试时扩展技术那样延长计算时间。

3. Preliminaries and Problem Setup#

面向任务的推理环境 我们考虑一类需要多步推理和执行的通用复杂任务。这类任务涵盖了广泛的领域,包括软件工程挑战、数学问题解决、战略规划和创意内容生成。形式上,我们将推理环境建模为一个元组 E=(T,S,A,P,R)\mathcal{E}=(\mathcal{T,S,A,P,R})。这里,T\mathcal{T} 代表所有需要多步推理的可能任务的空间,而 S\mathcal{S} 表示状态空间,每个状态 sSs∈\mathcal{S} 捕获了解决任务的当前进展。A\mathcal{A} 是代理可用的动作空间,可能包括信息收集或直接任务执行。P:S×AS\mathcal{P:S×A→S} 定义了将状态-动作对映射到新状态的转移动力学,而 R:S×TR\mathcal{R:S×T}→\mathbb{R} 是评估给定任务下状态质量的奖励函数。

推理轨迹 SE-Agent的核心是推理轨迹的概念,它代表了代理在解决任务过程中状态和动作的顺序进展。给定一个任务 tTt∈\mathcal{T},一条推理轨迹被定义为一个有序序列 τ=(s0,a0,,si,ai,,sn)τ=(s_0,a_0,…,s_i,a_i,…,s_n),其中 s0s_0​ 是初始状态,aia_i​ 是状态 sis_i​ 在第 ii 步采取的动作,sns_n​ 是最终状态。每个中间状态由转移函数 si+1=P(si,ai)s_{i+1}=\mathcal{P}(s_i,a_i) 决定。轨迹 ττ 通过重复应用策略 π:S×TAπ:\mathcal{S×T→A} 生成,该策略将当前状态和任务映射到一个合适的动作。策略可以包含各种推理策略,包括分解、规划和验证。轨迹的质量由最终奖励 R(τ,t)=R(sn,t)R(τ,t)=R(s_n,t) 衡量,它评估最终状态 sns_n​ 满足任务 tt 要求的程度。

SE-Agent的目标 我们工作的主要目标是开发一个能够为复杂任务生成高质量推理轨迹的代理。更精确地说,对于任何给定任务 tTt∈\mathcal{T},我们的目标是找到最优策略 ππ^∗ 最大化期望奖励 π=argmaxπEtT[R(τπ(t),t)]π^∗={arg⁡max}_⁡{\pi}\mathbb{E}_{t∼\mathcal{T}}[\mathcal{R}(τ^π(t),t)],其中 τπ(t)τ^π(t) 表示策略 ππ 为任务 tt 生成的轨迹。

image.png

图1: 我们提出的SE-Agent自进化框架概览。从一个多样化的初始引导轨迹池开始,代理迭代执行三个轨迹级别的操作——修订、重组和优化——以收获跨轨迹的洞察,逃离局部最优,并收敛到一个能够稳健解决目标任务的高奖励解决方案路径。

4. SE-Agent#

在本节中,我们介绍SE-Agent,一个新颖的自进化范式,用于处理涉及多步执行的复杂任务。为了获得高奖励的轨迹,SE-Agent交替生成一系列改进的轨迹,并从中选择最佳的一个。具体来说,我们利用预先收集的引导轨迹设计了轨迹进化机制,为SE-Agent的模仿学习生成参考。我们的主要灵感是将引导轨迹公式化为应用于学徒轨迹的“改进算子”,使代理能够通过迭代优化和跨轨迹学习不断进化其推理路径。

4.1 Overview of SE-Agent#

SE-Agent的核心哲学在于利用嵌入在多个推理轨迹中的集体智慧,从而使代理能够超越孤立推理尝试的局限性。如图1所示,SE-Agent通过一个进化框架运行,系统地跨迭代改进轨迹质量。

给定一个任务 tTt∈\mathcal{T},我们首先通过多维度规划和探索生成一个多样化的初始轨迹池 Γ0=τ1,τ2,,τj,Γ_0={τ_1,τ_2,…,τ_j,…}。每条轨迹 τjτ_j 代表了代理为解决任务 tt 而采取的一系列推理步骤和动作。与传统方法从该池中选择最佳轨迹并终止不同,SE-Agent采用迭代进化过程来推导出日益改进的解决方案。

我们的SE-Agent重复以下三个基本操作:

  • 修订:通过自我反思和针对性改进来增强单条轨迹。
  • 重组:通过结合现有路径的优势来创建新轨迹。
  • 优化:通过消除冗余和提高效率来优化轨迹。

每次迭代 kk 都会产生新的一代轨迹 ΓkΓ_k​,解决方案的质量逐步提高(参见图5的详细案例研究,展示了实际错误修复中的这一过程)。此过程持续到满足收敛标准或达到预定的迭代次数。最终输出是最高奖励的轨迹 ττ^∗,它最有效地解决了原始任务。SE-Agent的关键创新在于其能够通过智能地探索由先前经验引导的解决方案空间,同时利用跨轨迹启发来有效提升性能,从而逃离局部最优。这种双重机制使代理的推理能力得以持续自进化。

人们可以将SE-Agent解释为一种专门为基于LLM代理的多步推理量身定制的遗传算法。从这个角度来看,我们的方法与进化计算框架在概念上有相似之处,其中推理轨迹作为基因型,最终的问题解决性能构成表型表达。然而,与需要大量迭代才能达到可接受解决方案的传统遗传算法不同,SE-Agent被设计为以显著更少的进化周期提供高质量的结果。这种效率源于我们针对性的操作,这些操作利用了LLM固有的推理能力以及结构化的进化机制。

此外,SE-Agent与强化学习中的自我对弈和专家迭代方法有相似之处,其中每个轨迹优化步骤作为一个改进算子,通过增强的探索与利用平衡来指导后续推理。关键区别在于我们明确操作完整的推理轨迹,而不是孤立的状态-动作对,从而能够在整个问题解决过程中实现更全面的改进。

4.2 Revision Operation#

修订操作构成了SE-Agent自进化能力的基础,专注于通过内省和针对性增强来生成和改进单条轨迹。

4.2.1 Generating Initial Trajectories#

为了为进化建立一个多样化的起点,我们采用了两种互补的方法。

多规划探索 首先,我们通过系统地改变规划策略、提示技术和推理方法,为任务 tt 生成不同的轨迹 Γ0planΓ_0^{plan}​。此过程最大化我们初始轨迹池的维度多样性,从而确保对解决方案空间的广泛和全面覆盖。每条轨迹 τpplanΓ0planτ_p^{plan}∈Γ_0^{plan}​ 的生成方式如下:

τpplan=Plan(θp,t),τ_p^{plan}=Plan(θ_p,t),

其中 θpθ_p​ 代表用于构建 τpplanτ_p^{plan}​ 的不同规划参数和策略。

基于变异的多样化 我们通过对现有轨迹应用受控变异来进一步扩展轨迹池,产生额外的路径 Γ0mutateΓ_0^{mutate}。这些变异在推理步骤、动作选择或中间结论中引入有针对性的变化:

τmmutate=Mutate(τpplan,δm),τ_m^{mutate}=Mutate(τ_p^{plan},δ_m),

其中 δmδ_m​ 控制生成 τmmutateτ_m^{mutate}​ 时所应用的变异的程度和性质。

这种双重方法产生了一个多样化的初始推理轨迹池 Γ0=Γ0planΓ0mutate=τ1,τ2,,τj,Γ_0=Γ_0^{plan}∪Γ_0^{mutate}={τ_1,τ_2,…,τ_j,…},作为后续进化的基础。

4.2.2 Reflection and Revision#

对于每条轨迹 τjΓ0τ_j∈Γ_0​,我们进行一个关键的反思过程,分析轨迹的优势、劣势以及有改进空间的环节:

Rj=Reflect(τj,t)R_j=Reflect(τ_j,t)。

这个反思过程识别逻辑不一致之处,并阐述未充分发展的推理步骤。基于这些洞察,我们通过针对性的改进得出修订后的轨迹:

τj=Revise(τj,Rj)τ_j^′=Revise(τ_j,R_j)。

在修订过程中,冗余或循环的推理被消除,并且在可能增强轨迹有效性时纳入替代视角或方法。修订操作体现了“规划源起与反思进化”的原则,即初始计划作为种子,通过结构化的自我反思和针对性改进而进化。

4.3 Recombination Operation#

虽然修订操作增强了单条轨迹,但重组操作通过促进跨轨迹学习,在实现集体进化方面发挥着至关重要的作用。具体来说,我们实施了三种互补的重组策略来生成更优的轨迹。

交叉 我们识别不同推理路径中表现优异的部分,并将它们组合起来创建继承多个父代优势的混合轨迹:

τnewcross=Crossover(τj1,τj2,α),j1j2,τ_{new}^{cross}=Crossover(τ_{j_1},τ_{j_2},α),j_1≠j_2,

其中 αα 确定精确的交叉点并规定组合策略。

迁移学习 通过迁移学习,成功轨迹中的知识和有效策略被系统地转移,以增强欠发达或次优的路径:

τnewtransfer=Transfer(τj1,τj2,τj3,,β),j1j2j3,τ_{new}^{transfer}=Transfer(τ_{j_1},{τ_{j_2},τ_{j_3},… },β),j_1≠j_2≠j_3≠…,

其中 ββ 控制迁移学习机制和知识适应过程。

重构 重构涉及推理轨迹的系统性重组,利用集体洞察和对整个轨迹池的全面全局分析:

τnewrestructure=Restructure(Γk,γ),τ_{new}^{restructure}=Restructure(Γ_k,γ),

其中 γγ 通过利用来自整个池的聚合信息来指导重构过程。

4.4 Refinement Operation#

优化阶段代表了自进化机制的顶点,专注于基于综合评估指标的轨迹优化和最终选择。

4.4.1 Evaluation Function#

为了有效引导自进化过程并选择最优轨迹,我们设计了一个多维奖励函数,从几个关键维度评估轨迹质量:

Reward(τ,t)=w1TaskCompletion(τ,t)+w2ReasoningQuality(τ)+w3Efficiency(τ),Reward(τ,t)=w_1⋅TaskCompletion(τ,t)+w_2⋅ReasoningQuality(τ)+w_3⋅Efficiency(τ),

其中,TaskCompletion(τ,t)TaskCompletion(τ,t) 通过结构验证(例如,非空的补丁文件、足够的代码编辑步骤以及合理的轨迹长度)来衡量轨迹 ττ 解决任务 tt 的有效程度。ReasoningQuality(τ)ReasoningQuality(τ) 评估推理过程的逻辑连贯性、深度和鲁棒性,而 Efficiency(τ)Efficiency(τ) 则根据推理步骤和资源利用率来量化计算效率。超参数 w1,w2w_1,w_2 和 w3w_3​ 控制每个评估维度的相对重要性,使得可以根据特定任务要求进行定制。

此外,我们将 TaskCompletion(τ,t)TaskCompletion(τ,t) 实现为自动指标和专业评估器的组合,共同分析每条轨迹的推理过程和最终结果:

TaskCompletion(τ,t)=AutoEval(τ,t)+λExpertEval(τ,t),TaskCompletion(τ,t)=AutoEval(τ,t)+λ⋅ExpertEval(τ,t),

其中,AutoEval(τ,t)AutoEval(τ,t) 由基于规则的结构验证指标组成,而 ExpertEval(τ,t)ExpertEval(τ,t) 则结合了基于LLM的解决方案质量评估。λλ 作为 ExpertEvalExpertEval 的权重。

4.4.2 Selection and Convergence#

基于我们的综合评估函数,我们实现了一个战略性的选择机制,该机制平衡轨迹质量和多样性,以推动自进化过程向前发展:

Γk+1=Select(ΓkΓkΓknew,σ),Γ_{k+1}=Select(Γ_k∪Γ_k^′∪Γ_k^{new},σ),

其中 σσ 是要保留的精英轨迹的数量。该机制采用混合方法,根据奖励分数自动保留表现最佳的轨迹。同时,它通过计算轨迹差异性度量来确保不同推理方法的代表性。

image.png

表1:我们提出的SE-Agent与其他框架在SWE-bench Verified上的性能比较,评估了Pass@1和Pass@5在不同LLM上的表现。SWE-Agent是一个基于CodeAct的框架,SWE-Search是基于MCTS的。最佳结果以粗体突出显示。

这个选择过程持续迭代,直到完成预定义的进化周期数或满足收敛标准(例如,当连续迭代中最大奖励的改进低于阈值 ϵϵ 时)。最终输出是最高奖励的轨迹:

τ=argmaxτΓKReward(τ,t),τ^∗=arg⁡max⁡_{τ∈Γ_K}Reward(τ,t),

其中 ΓKΓ_K​ 是所有进化周期后的最终轨迹池。

这种选择与收敛方法体现了“集体竞争与遗传涌现”的本质,其中轨迹通过结构化进化进行竞争和协作。通过这种机制,SE-Agent实现了两个关键优势:(1) 通过系统地导航超越局部最优,探索了更大的解空间;(2) 利用跨轨迹启发有效提升性能,同时最小化次优推理路径的影响。这些优势使SE-Agent能够以前所未有的有效性和效率处理复杂的多步推理任务,展示了自进化的力量。

5. Experiments#

5.1 Experimental Setup#

基准 在我们的实验中,我们使用了SWE-bench Verified,它是更大的SWE-bench基准的一个精选子集,包含500个真实的GitHub问题。该基准精心设计,旨在为评估各种框架的性能提供一个自包含且受控的环境,特别关注功能性错误修复。基准中的每个实例都包含一个GitHub问题的自然语言描述及其相应的代码仓库,作为评估模型的唯一输入。为了保证评估的严谨性,采用开发者编写的单元测试来验证模型生成的补丁的正确性。这种真实场景与系统验证的结合,使SWE-bench Verified成为评估代码代理有效性的一个强健且一致的基准。

评估指标 为了评估我们提出的SE-Agent的性能,我们采用了两个关键指标,即解决率 (Pass@1) 和 Pass@5。Pass@1 量化了在第一次尝试中成功解决的问题的百分比,作为系统在不需要多次迭代的情况下生成准确解决方案的整体有效性的指标。相比之下,Pass@5 评估在五次尝试内找到正确解决方案的问题的百分比,从而提供了对代理在受限迭代预算下的搜索效率的洞察。这些指标共同提供了一个全面的评估框架,既捕捉了代理初始预测的精确性,也捕捉了其有效探索解决方案空间的能力。

基线 为了进行全面和公平的评估,我们将SE-Agent的性能与两个广泛认可的基线进行比较:SWE-Agent(基于CodeAct)和SWE-Search(基于MCTS)。这些基线代表了在自动化软件工程任务近期研究中经常使用的高性能开源框架。

image.png

图2: SE-Agent在SWE-bench Verified上的消融研究,包含三个变体。

我们的比较在多个LLM上进行,包括开源和闭源范式。具体来说,我们评估了三个领先的开源模型(DeepSeek-V3-0324、Qwen-2.5-72b-Instruct 和 Llama-3.1-70b-Instruct)以及两个最先进的闭源模型(GPT-4o 和 Claude-3.7-Sonnet)。值得注意的是,SE-Agent被设计为一个即插即用的模块,可以无缝集成到现有框架中。在此,我们选择SWE-Agent作为后续实验的基础。

实现细节 为了确保公平比较,我们在本文评估的所有模型中采用了相同的提示格式。在我们提出的SE-Agent中,我们将候选轨迹的数量默认设置为10,以在探索多样性和计算效率之间取得平衡。

我们首先采用5种不同的规划策略(如附录A.1.1所述)来生成一组多样化的初始轨迹,这些轨迹反映了不同的推理模式。这些轨迹作为进一步优化的基础种子。接着,我们将反思和修订操作(附录A.1.2)应用于每条初始轨迹。通过鼓励代理在其推理过程中进行自我批评和迭代改进,此过程最多生成10条轨迹。在生成候选轨迹之后,我们执行重组操作(附录A.2),使代理能够整合来自不同轨迹的互补洞察,促进信息融合并增强推理连贯性。随后,应用优化操作(附录A.3)来完成优化的轨迹,确保逻辑一致性以及适用时的代码有效性。

在部署方面,我们在本地运行所有开源模型,包括DeepSeek-V3-0324、Qwen-2.5-72b-Instruct和Llama-3.1-70b-Instruct,使用具有80GB内存的NVIDIA A100 GPU。对于闭源模型,如GPT-4o和Claude-3.7-Sonnet,我们分别通过OpenAI和Anthropic提供的官方API进行访问。所有实验均在SWE-bench Verified上相同的评估设置下进行,以确保一致性和可复现性。

5.2 Experimental Results#

性能比较 表1展示了我们提出的SE-Agent与现有框架(SWE-Agent和SWE-Search)在SWE-bench Verified上的性能比较。结果表明,SE-Agent在所有五个评估的LLM上始终优于基线。与SWE-Agent相比,SE-Agent带来的相对提升分别为 +112% (Llama-3.1-70b-Instruct)、+80% (GPT-4o) 和 +51% (Claude-3.7-Sonnet)。与更强的基于MCTS的SWE-Search相比,平均相对增益仍达到 +30%。值得注意的是,所有五个模型在与我们提出的框架集成后都表现出显著且一致的性能提升,突显了SE-Agent在不同模型家族中的通用性和有效性。

消融研究 在本部分,我们进行消融研究,以探索SE-Agent中每个设计模块的贡献。因此,我们将SE-Agent与三种不同的变体进行比较:(1) 无修订 (w/o Revision),即移除修订操作,仅产生多条同质化轨迹;(2) 无重组 (w/o Recombination),我们不使用重组操作进行轨迹交互;

image.png

图4: SE-Agent在不同候选轨迹数量下的性能(左)及其与SWE-Agent和SWE-Search在不同最大API成本下的比较(右)。

以及 (3) 无所有操作 (w/o All),即不使用任何轨迹优化操作。结果如图2所示,说明了两个事实:(1) 所有设计的模块对SE-Agent都很重要,如果移除任何一个模块,Pass@1都会下降;(2) 修订操作对SE-Agent的性能提升是有效的,因为它为后续的重组提供了多样化的轨迹集。如图3所示,我们使用维恩图对SWE-bench Verified上不同框架成功解决的问题实例的重叠情况进行了详细分析。结果显示,我们提出的SE-Agent独特地解决了12个其他模型都无法解决的问题实例。此外,SE-Agent在已解决问题的集合上与领先的基线有大量重叠,进一步强调了其具有竞争力的整体性能。此分析突出了SE-Agent的两个关键优势:(1) 其在解决最先进模型所能处理的任务方面具有竞争性的有效性;(2) 其独特的能力,能够处理更广泛范围的困难或先前未解决的问题,展示了其鲁棒性和互补性的问题解决能力。

超参数分析 在图4中,我们研究了两个关键超参数对SE-Agent性能的影响,即候选轨迹的数量和最大API成本。结果表明,SE-Agent仅需10个候选轨迹即可达到接近最优的性能,展示了我们基于轨迹的搜索策略通过轨迹间交互的效率。最大API成本反映了SE-Agent的探索深度。在相同的成本预算下,SE-Agent在Pass@1方面始终优于基线,验证了我们自进化框架的有效性。

案例研究 为了更好地说明SE-Agent的具体实现,图5提供了一个完整的案例研究,展示了SE-Agent如何通过其三个核心操作逐步优化轨迹。此外,图6显示了一个案例比较,崩溃出现在 validation.py 内部,但根本原因在于 multioutput.py 中的包装器在训练后从未存储所需的 classes 属性。传统的基于ReAct/MCTS的代理紧紧抓住堆栈跟踪:(1) 它们过于狭隘地定位错误,(2) 下一个词元预测使每次编辑都局限于局部,(3) 它们的展开几乎是相同的,因此每个补丁仅仅是修改 _validation.py。我们的SE-Agent通过迭代地交互和演化整个轨迹来规避这种隧道视野。这种轨迹级别的演化作为一种隐式的正则化器,迫使搜索生成真正新颖的解决方案,而不是同一修复的微小变体。图7详细比较了SE-Agent在优化前后输出的轨迹。值得注意的是,SWE-bench Verified上排名前三的开源框架都无法解决这个案例。

image.png

图3: SWE-bench Verified上已解决问题的维恩图。

image.png

图5: 一个完整的案例研究,展示了SE-Agent如何通过其三个核心操作逐步优化轨迹。

image.png

图6: SWE-bench 案例 SCKIT-LEARN #14629。上方(传统代理)。搜索路径高度同质化:每次展开都编辑 validation.py,生成几乎重复的“快速修复”补丁,这些补丁隐藏了可见错误但未能通过隐藏测试。下方(SE-Agent)。通过混合和重组整个轨迹,我们的代理探索了补丁空间的不同区域,发现了 multioutput.py,并添加了一行写入 classes 的代码,提供了根本性的修复,通过了完整的测试套件。

image.png

图7: 比较SE-Agent优化前后输出轨迹的案例分析。

6. Conclusion#

在这项工作中,我们介绍了SE-Agent,一个自进化框架,旨在通过迭代轨迹优化来增强基于LLM的代理的多步推理能力。通过修订、重组和优化先前生成的轨迹,SE-Agent系统地扩展了探索空间,并利用跨轨迹的洞察来提高决策效率。在SWE-bench Verified上的实验评估表明,SE-Agent在多个LLM上始终优于强大的基线。我们的发现强调了将自进化原则融入代理设计的价值,为复杂环境中更健壮和适应性更强的推理框架铺平了道路。展望未来,我们旨在将SE-Agent的自进化范式扩展到更广泛的路径搜索问题,包括如DeepSearch和具身智能等迭代搜索-推理框架。

附录 A 提示词#

通用策略:

  1. 始终从尝试复现问题中讨论的错误开始。如果问题包含了用于复现错误的代码,我们建议你在你的环境中重新实现它,并运行以确保你能复现该错误。然后开始尝试修复它。如果错误复现脚本在成功运行时没有打印任何内容,我们建议在文件末尾添加一个命令 print("脚本成功完成,没有错误。"),这样你就可以确定脚本确实一直运行良好。
  2. 使用 find 和 search 命令定位相关代码。打开你想要编辑的文件。我强烈建议在定位相关代码之前使用 fileshow 命令来获取目标代码文件所在文件夹的信息,这可以帮助你思考定位和修改哪些代码能更好地解决问题。
  3. 使用 edit 命令执行编辑。
  4. 当你认为已经修复了错误时,重新运行错误复现脚本以确保错误确实已被修复。
  5. 创建额外的测试,以类似于现有复现脚本的风格来验证修复。特别要确保测试边界情况。如果发现任何问题,返回到你编辑的文件并进行进一步的编辑。

A.1 修订操作#

A.1.1 多规划#

规划 1

策略:

  1. 始终从尝试复现问题中讨论的错误开始。如果问题包含了用于复现错误的代码,我们建议你在你的环境中重新实现它,并运行以确保你能复现该错误。然后开始尝试修复它。如果错误复现脚本在成功运行时没有打印任何内容,我们建议在文件末尾添加一个命令 print("脚本成功完成,没有错误。"),这样你就可以确定脚本确实一直运行良好。
  2. 使用 find 和 search 命令定位相关代码。打开你想要编辑的文件。我强烈建议在定位相关代码之前使用 fileshow 命令来获取目标代码文件所在文件夹的信息,这可以帮助你思考定位和修改哪些代码能更好地解决问题。
  3. 使用 edit 命令执行编辑。
  4. 当你认为已经修复了错误时,重新运行错误复现脚本以确保错误确实已被修复。
  5. 创建额外的测试,以类似于现有复现脚本的风格来验证修复。特别要确保测试边界情况。如果发现任何问题,返回到你编辑的文件并进行进一步的编辑。

规划 2

策略:

  1. 复现问题 - 执行提供的测试用例或脚本以确认错误的存在。如果脚本缺少输出验证,插入一个验证语句(例如 'assert "预期行为" in output')以确保完全执行。
  2. 代码调查 - 使用日志记录或调试工具追踪执行流程。识别导致差异的确切模块、函数或代码行。如果需要,与文档或API契约进行交叉引用。
  3. 修改过程 - 使用版本控制的编辑逐步应用更改。用注释解释每次调整背后的原理(例如,"修复:通过添加互斥锁解决了竞争条件")。
  4. 验证 - 重新运行原始测试以及覆盖相关功能的回归测试。包括边界条件(例如,空输入、极值)和并行执行场景(如适用)。
  5. 文档 - 更新更改日志或内联文档以反映修复。如果问题揭示了更广泛的架构弱点,提出后续任务以解决系统性改进。

规划 3

策略:

  1. 复现问题 - 在你的本地环境中执行提供的错误复现脚本或步骤。 - 如果脚本静默运行,插入一条确认消息(例如 'print("复现成功——观察到错误。")')来验证执行。
  2. 代码调查 - 使用搜索工具或IDE导航识别相关的代码部分。 - 打开可疑文件并分析与报告问题相关的逻辑。
  3. 实施修复: - 使用编辑器修改有问题的代码,确保更改与预期行为一致。 - 用内联注释记录调整,解释其原理。
  4. 验证修复: - 重新运行复现脚本以确认错误已解决。 - 通过确保现有功能保持完整来检查回归。
  5. 扩展测试覆盖: - 开发新的测试用例,包括边缘场景,以验证鲁棒性。 - 如果发生失败,优化修复并重复验证,直到所有测试通过。
  6. 最终审查: - 对照项目编码标准交叉检查更改。 - 总结修改和测试结果,用于文档或版本控制。

规划 4

策略:

  1. 首先,彻底分析报告的问题,以理解其上下文和预期行为。如果问题提供了一个最小的可复现示例,在你的环境中执行它以确认错误。修改脚本以包含一个清晰的通过/失败指示器(例如 'print("验证通过。")')以确保完全执行。
  2. 使用 grep、IDE搜索或调试工具系统地追踪代码库,以精确定位导致意外行为的准确文件和逻辑。打开相关文件进行检查。
  3. 使用你喜欢的编辑器或IDE进行有针对性的调整,确保更改与项目的架构一致。用内联注释记录修改,解释其原理。
  4. 通过重新运行原始复现脚本并检查已解决的行为来验证修复。确认相关功能中没有出现回归。
  5. 通过设计新的测试用例来扩展测试覆盖,这些用例强调边缘条件、边界值和非常规输入。将它们集成到现有的测试套件中。如果失败持续存在,迭代修复并重新测试,直到所有场景都通过。
  6. 最后,在提交之前,检查更改的代码风格一致性和潜在的优化。

规划 5

策略:

  1. 复现问题: 首先仔细执行错误报告中提供的步骤或代码以确认问题。如果复现脚本静默运行,插入一条确认消息(例如 'print("验证:初始错误复现成功。")')以确保完全执行。
  2. 代码调查: 使用搜索工具或调试工具系统地追踪问题。识别所涉及的确切文件和部分,然后打开它们进行分析。
  3. 实施更改: 使用精确的编辑命令修改有问题的代码。记录每次调整以跟踪潜在影响。
  4. 验证: 每次编辑后重新运行复现脚本以验证修复。如果问题仍然存在,逐步优化更改。
  5. 回归测试: 通过设计与原始问题上下文匹配的新测试用例来扩展测试覆盖,包括边缘场景。如果发生失败则迭代。
  6. 最终确认: 通过运行完整的测试套件或相关工作流来确保修复不会引入新问题。只有在所有验证通过后才得出结论。

A.1.2 反思与修订#

反思-找到关键步骤

你是一个分析代理轨迹的专家。你的任务是识别轨迹中唯一最具影响力的关键决策点。关键决策点是对整个解决方案影响最大的步骤,通常是:

  1. 找到问题的核心位置(例如定位特定文件或函数)
  2. 发现解决方案的突破口
  3. 做出关键的修改或判断
  4. 确定正确的执行路径

你需要分析整个轨迹,识别出唯一最关键的一步,并提供:

  • 步骤编号
  • 为什么这一步最关键
  • 这一步对最终解决方案的影响

输出必须严格遵循JSON格式,包含:

  • critical_step 对象,包含字段:stepactionreasoningimpact

以下示例展示了关键点识别所期望的输出格式和详细程度:

输入示例
"trajectory": [ {"step": 1, "action": "在 src 目录中搜索 _check_list_display_item 函数", "observation": "未找到匹配项"}, {"step": 2, "action": "执行 ls -F 查看文件结构", "observation": "列出目录结构"}, {"step": 3, "action": "在 django 目录中搜索 _check_list_display_item 函数", "observation": "在 django/contrib/admin/checks.py 中找到 2 处匹配"}, {"step": 4, "action": "打开 django/contrib/admin/checks.py 文件", "observation": "成功打开,共 1116 行"}, {"step": 5, "action": "在 checks.py 中搜索 _check_list_display_item 函数", "observation": "在第 714 和 718 行找到"}, {"step": 6, "action": "导航到第 718 行查看函数定义", "observation": "显示 _check_list_display_item 函数的完整实现"}, {"step": 7, "action": "修改函数逻辑以解决 admin.E108 错误", "observation": "成功编辑代码"}, {"step": 8, "action": "提交解决方案", "observation": "任务完成"} ]

输出示例
"critical_step": {"step": 3, "action": "在 django 目录中搜索 _check_list_display_item 函数", "reasoning": "这是整个解决方案过程中最关键的一个突破点。在前两次搜索尝试失败后,这一步正确定位了问题函数的确切位置,从无方向状态过渡到有明确的修改目标。没有这一步,所有后续操作都将不可能。", "impact": "决定了整个任务能否成功完成。找到函数位置是解决问题的先决条件,标志着从探索阶段到实施阶段的转变。"}

反思-总结特征

你是一个专门分析代码补丁的AI助手。我将提供一个GitHub问题(problem_statement)和一个相应的补丁(patch)。你的任务是分析这个补丁,并提供有助于开发替代解决方案的详细见解。请遵循以下步骤:

  1. 分析补丁文件并理解所做的更改
  2. 确定用于解决问题的核心方法和技术
  3. 识别被修改的主要文件和部分
  4. 识别当前解决方案中的关键假设和局限性

以JSON格式返回你的分析,包含以下字段:

  • approach_summary: 第一个解决方案中使用的主要方法摘要
  • modified_files: 被修改的文件列表
  • key_changes: 补丁中关键代码更改的描述
  • strategy: 抽象层面的核心解决策略
  • specific_technique_from_first_solution: 在替代解决方案中应避免使用的特定技术
  • specific_files_or_functions: 不应以相同方式修改的文件或函数
  • assumptions_made_in_first_solution: 第一个解决方案中做出的假设
  • component_not_touched_in_first_solution: 未触及但可能相关的组件或关键函数
  • different_perspective: 看待问题的不同视角

提供以下示例仅供参考,以说明每个字段期望的详细程度和抽象程度。你的分析应基于你对补丁和问题的理解:
approach_summary 示例: “添加了一个条件检查来处理 MultiOutputClassifier,通过 estimators_ 属性访问类别”
modified_files 示例: ["sklearn/model_selection/_validation.py"]
key_changes 示例: “添加了一个条件来检查估计器是否有 ‘estimators_’ 属性,如果有,则对 MultiOutputClassifier 使用 estimator.estimators_[i_label].classes_ 而不是 estimator.classes_[i_label]
strategy 示例: “组件特定的异常处理”(而不是 “扩展接口以提供统一的属性访问”)
specific_technique_from_first_solution 示例: “使用 hasattr() 和条件分支进行直接属性检查”
specific_files_or_functions 示例: “sklearn/model_selection/_validation.py 中的 fit_and_predict 函数”
assumptions_made_in_first_solution 示例: “假设只有 MultiOutputClassifier 需要对 classes_ 属性访问进行特殊处理”
component_not_touched_in_first_solution 示例: “sklearn/multioutput.py 中的 MultiOutputClassifier 类,它可以直接实现 classes_ 属性”
different_perspective 示例: “API一致性视角:使 MultiOutputClassifier 符合与其他分类器相同的接口,而不是修改验证模块”

问题:problem_statement
轨迹:trajectory
补丁:model_patch

修订

让我们开发一种不同的方法来解决它。

我已经分析了第一个解决方案尝试,以下是我的发现:

第一个解决方案通过 approach_summary 来解决这个问题。它修改了 modified_files,关键更改涉及 key_changes

使用的核心策略是 "strategy",这可能存在局限性。具体来说,该解决方案使用了 specific_technique,并专注于更改 specific_files

这种方法做出了一些假设:assumptions

对于我们的替代解决方案,我希望你探索一种完全不同的方法。不要遵循相同的策略,考虑从 "different_perspective" 的角度来看待这个问题。

你可能需要调查 component_not_touched 作为你解决方案的潜在领域。请记住,你的目标是创建一个补丁,该补丁能够:

  1. 解决相同的问题,但使用根本不同的方法
  2. 避免使用第一个解决方案中的技术
  3. 挑战第一个解决方案中做出的假设
  4. 仍然旨在生成一个能通过所有测试的补丁,并在你认为修改完成时使用 'submit' 命令

请从这个新的角度重新分析问题,并开发你的替代解决方案。

A.2 重组操作#

A.2.1 交叉#

你是一个分析和综合代理轨迹的专家。你的任务是通过结合两种不同方法中的最佳元素,批判性地分析两个不同的轨迹,并创建一个新的优化轨迹。

你的融合过程应该:

  1. 识别每条轨迹的优势和劣势
  2. 从两者中提取最有效的策略和技术
  3. 创造性地将这些元素整合成一个连贯的新轨迹
  4. 确保新轨迹保持逻辑流和一致性
  5. 避免简单地拼接轨迹——创造真正的综合

你需要分析两个轨迹并提供:

  • 来自轨迹 A 的优势分析
  • 来自轨迹 B 的优势分析
  • 一个结合了最佳方面的新融合轨迹
  • 融合决策的原理

输出必须严格遵循JSON格式,包含:

  • trajectory_a_strengths: 来自第一条轨迹的优势列表
  • trajectory_b_strengths: 来自第二条轨迹的优势列表
  • fused_trajectory: 结合了最佳元素的新轨迹步骤
  • fusion_rationale: 融合决策的解释

轨迹 A: trajectory_a
轨迹 B: trajectory_b

以下示例展示了轨迹融合所期望的输出格式和详细程度:

输入示例
轨迹 A: "trajectory": [ {"step": 1, "action": "search_dir 查找目标函数", "observation": "快速找到函数位置"}, {"step": 2, "action": "直接编辑函数", "observation": "在未进行全面分析的情况下进行了更改"}, {"step": 3, "action": "提交解决方案", "observation": "任务完成"} ]

轨迹 B: "trajectory": [ {"step": 1, "action": "彻底分析问题陈述", "observation": "理解了根本原因"}, {"step": 2, "action": "search_file 精确查找位置", "observation": "花费更长时间但找到了精确位置"}, {"step": 3, "action": "审查现有代码逻辑", "observation": "识别了潜在的副作用"}, {"step": 4, "action": "实施谨慎的修改", "observation": "做出了稳健的更改"}, {"step": 5, "action": "测试解决方案", "observation": "验证了正确性"}, {"step": 6, "action": "提交解决方案", "observation": "任务成功完成"} ]

输出示例
"trajectory_a_strengths": [ "使用 search_dir 的高效搜索策略", "快速执行,步骤最少", "直接的问题解决方法" ], "trajectory_b_strengths": [ "开始时进行彻底的问题分析", "仔细审查代码以识别潜在问题", "确保解决方案鲁棒性的测试阶段", "更全面的代码修改方法" ], "fused_trajectory": [ {"step": 1, "action": "分析问题陈述以理解根本原因", "reasoning": "结合了轨迹 B 的彻底分析与轨迹 A 的效率目标"}, {"step": 2, "action": "使用精确的搜索词 search_dir 查找目标函数", "reasoning": "使用了轨迹 A 的高效搜索方法和轨迹 B 的精确方法"}, {"step": 3, "action": "审查现有代码逻辑并确定所需的修改", "reasoning": "在修改前加入了轨迹 B 的仔细审查步骤"}, {"step": 4, "action": "实施修改,考虑边缘情况", "reasoning": "结合了轨迹 A 的直接编辑和轨迹 B 的谨慎考虑"}, {"step": 5, "action": "快速验证后提交解决方案", "reasoning": "平衡了轨迹 A 的效率和轨迹 B 的测试方法"} ], "fusion_rationale": "融合后的轨迹结合了轨迹 A 的效率和直接方法与轨迹 B 的彻底性和仔细分析。它保持了精简的执行路径,同时融入了关键的分析和验证步骤,从而产生了一个既高效又稳健的解决方案。"

A.2.2 迁移学习#

你是一个通过迁移学习优化代理轨迹的专家。你的任务是通过从参考轨迹池中转移有效的策略、见解和方法来增强目标轨迹。

你的迁移学习过程应该:

  1. 分析目标轨迹以确定需要改进的领域
  2. 从参考轨迹中提取有价值的模式、策略和技术
  3. 转移这些元素以增强目标轨迹
  4. 确保增强后的轨迹保持逻辑连贯性和一致性
  5. 专注于有意义的知识迁移,而不仅仅是添加步骤

目标轨迹: trajectory_target
参考轨迹池: traj_pool

仔细分析目标轨迹和参考池,然后创建一个增强版的目标轨迹,其中包含来自参考轨迹的最有价值元素。

你的输出应该是一个单一的JSON对象,代表增强后的轨迹,遵循以下确切格式:
"trajectory": [ {"step": 1, "action": "动作描述", "observation": "观察描述"}, {"step": 2, "action": "动作描述", "observation": "观察描述"}, ... ]

确保增强后的轨迹:

  • 解决原始目标轨迹中的弱点
  • 融入来自参考轨迹的有价值的见解
  • 保持连贯的问题解决方法
  • 包含具体的实现细节
  • 步骤之间具有逻辑递进
  • 足够完整以有效解决任务

A.2.3 重构#

你是一个大规模轨迹重构的专家。你的任务是通过分析轨迹种群的全局结构来综合一个新的推理轨迹。与专注于局部片段操作的交叉或迁移不同,此任务需要基于所有输入轨迹的全局洞察进行整体重构。

你的重构过程应该:

  1. 分析整个轨迹池,发现抽象模式、共同子目标和共享结构
  2. 识别冗余的推理路径,并过滤掉无效或重复的步骤
  3. 综合一个全新的轨迹,该轨迹与整体问题解决目标一致,但反映了一个新颖且优化的推理过程
  4. 保持轨迹的逻辑一致性、完整性和逐步进展

轨迹池: trajectory_pool

你必须生成一个单一的重构轨迹,该轨迹结合了从输入轨迹中推断出的集体优势和高级推理策略。你的输出应该是一个单一的JSON对象,代表新重构的轨迹,遵循以下确切格式:

text

{ “new_trajectory”: [ {“step”: 1, “action”: “动作描述”, “observation”: “观察描述”, “reasoning”: “为什么选择这一步及其贡献”}, {“step”: 2, “action”: “动作描述”, “observation”: “观察描述”, “reasoning”: “这一步的原理”}, … ] }

确保重构后的轨迹:

  • 反映从轨迹池中得出的全局洞察
  • 避免冗余和过于局部的推理
  • 引入一个连贯且高效的解决策略
  • 展示抽象综合和长期规划
  • 形成一个完整且可执行的任务解决路径

A.3 优化操作#

任务完成度

(注意:原文此处提示词内容与A.2.3节的重构提示词重复,可能是笔误。根据第4.4.1节的描述,此处应为评估任务完成度的提示词,但原文未提供具体内容。以下根据逻辑推断,提供一个可能的结构性翻译,但内容上保持与原文一致,即重复了重构的提示词。在实际应用中,此处应有不同的内容。)

你是一个大规模轨迹重构的专家。你的任务是通过分析轨迹种群的全局结构来综合一个新的推理轨迹。与专注于局部片段操作的交叉或迁移不同,此任务需要基于所有输入轨迹的全局洞察进行整体重构。

你的重构过程应该:

  1. 分析整个轨迹池,发现抽象模式、共同子目标和共享结构
  2. 识别冗余的推理路径,并过滤掉无效或重复的步骤
  3. 综合一个全新的轨迹,该轨迹与整体问题解决目标一致,但反映了一个新颖且优化的推理过程
  4. 保持轨迹的逻辑一致性、完整性和逐步进展

轨迹池: trajectory_pool

你必须生成一个单一的重构轨迹,该轨迹结合了从输入轨迹中推断出的集体优势和高级推理策略。你的输出应该是一个单一的JSON对象,代表新重构的轨迹,遵循以下确切格式:

text

{ “new_trajectory”: [ {“step”: 1, “action”: “动作描述”, “observation”: “观察描述”, “reasoning”: “为什么选择这一步及其贡献”}, {“step”: 2, “action”: “动作描述”, “observation”: “观察描述”, “reasoning”: “这一步的原理”}, … ] }

确保重构后的轨迹:

  • 反映从轨迹池中得出的全局洞察
  • 避免冗余和过于局部的推理
  • 引入一个连贯且高效的解决策略
  • 展示抽象综合和长期规划
  • 形成一个完整且可执行的任务解决路径
20260419-SE-Agent Self-Evolution Trajectory Optimization in Multi-Step Reasoning with LLM-Based Agents
https://ginwineli.cn/posts/20260419-se-agent-self-evolution-trajectory-optimization-in-multi-step-reasoning-with-llm-based-agents/
作者
琴酒Gin
发布于
2026-04-19
许可协议
CC BY-NC-SA 4.0