Trae Agent Selector Agent 实战指南:面向仓库级 Issue 解决的 Agent 集成补丁选择方法
2026/9/23 9:39:42 网站建设 项目流程

Trae Agent Selector Agent 实战指南:面向仓库级 Issue 解决的 Agent 集成补丁选择方法

【免费下载链接】trae-agentTrae Agent is an LLM-based agent for general purpose software engineering tasks.项目地址: https://gitcode.com/gh_mirrors/tr/trae-agent

本文以 Trae Agent 仓库中的 evaluation/patch_selection/README.md 为主体,结合其配套源码与示例数据,系统讲解 Selector Agent 的设计动机、输入输出格式、命令行参数、运行流程与结果解读。读完本文,你将能够在自己的 SWE-bench 类评测任务上,用 Trae Agent 的 Selector Agent 从大量候选补丁中自动挑选出正确修复补丁,并用配套脚本实时分析与可视化选择结果。

一、Selector Agent 是什么:解决"哪个补丁是对的"

Trae Agent 是一款面向通用软件工程任务的 LLM Agent。在多 Agent 或单 Agent 多次采样的软件开发流程中,一个 repository 级别的 issue 常常会产生多个候选补丁(candidate patches),其中既有正确的也有错误的。Selector Agent 正是为此设计的第一种基于 Agent 的集成推理(agent-based ensemble reasoning)方案:它将"从候选补丁中选出正确补丁"这一目标形式化为一个最优解搜索问题,并通过"生成(generation)—剪枝(pruning)—选择(selection)"的模块化 Agent 组合,应对两个关键挑战:

  • 大规模集成空间(large ensemble spaces):候选补丁可能多达几十个,直接让模型在全部候选中做判断既消耗 token 又难以收敛;
  • 仓库级理解(repository-level understanding):判断补丁是否正确,需要真正读懂 issue、阅读相关代码库上下文,甚至动手运行测试,而非仅凭 diff 文本表面判断。

在 Trae Agent 仓库中,这套方法被落地为一个独立可运行的评测子项目,位于 evaluation/patch_selection 目录,核心组件如下:

组件路径作用
入口脚本selector.py解析命令行参数、加载配置与候选数据、编排整个评测流程
Agent 实现trae_selector/selector_agent.py定义 SelectorAgent 类、系统提示词、工具调用解析与答案提取
评测编排trae_selector/selector_evaluation.py分组、回归测试筛选、补丁去重、多数投票、并发调度
沙箱trae_selector/sandbox.py基于 Docker 启动 SWE-bench 镜像并在其中执行 agent 工具
工具集trae_selector/tools/toolsbash 与基于字符串替换的编辑工具,供 Agent 在容器内验证补丁
数据分析analysis.py聚合 statistics 输出并可视化各分组的选择成功率

二、整体工作流程

从源码结构(selector_evaluation.py)可以看出,Selector Agent 对一个 instance 的处理大致分为以下阶段:

  1. 切分组:将num_candidate个候选按group_size切成若干组(如 50 个候选、每组 10 个,得到 5 组);
  2. 预剪枝:先利用可选的回归测试结果(regressions字段)保留通过回归测试的候选;再对候选补丁做清洗去重(基于clean_patch得到的规范形式);
  3. 沙箱就绪:以该 instance 的 base commit 启动对应的 SWE-bench Docker 镜像,并把工具脚本复制进容器;
  4. Agent 选择:让 SelectorAgent 在容器内阅读代码、运行测试,最后以固定格式输出所选的Patch-x
  5. 多数投票(可选):对每个候选组重复多次选择,取被选频率最高的补丁作为该组最终答案;
  6. 落盘:将所选补丁写入patch目录、将是否正确写入statistics目录,同时把完整 LLM 交互历史写入log目录、把标准输出写入output目录。

三、环境准备

3.1 前置依赖

  • Python 3.10+(仓库使用pyproject.toml管理依赖,可用uvpip安装);
  • Docker 与 Docker Python SDK(sandbox.py通过docker.from_env()创建并管理容器);
  • 一个可用的 LLM 服务配置(通过trae_config.yaml之类的配置文件提供,见下文第 5 节)。

3.2 下载 Python 3.12 运行时(必须)

README 特别强调:需要从官方文档提供的下载链接获取一个 Python 3.12 的预打包目录,并将其解压到如下位置:

evaluation/patch_selection/trae_selector/tools/py312

这个 Python 3.12 运行时用于在 Docker 容器内执行 Agent 工具(bash 工具与字符串替换编辑工具)。从 selector_agent.py 可以看到,工具命令正是通过/home/swe-bench/py312/bin/python3 execute_str_replace_editor.py/home/swe-bench/py312/bin/python3 execute_bash.py这样的路径在容器内触发的,因此该目录必须就位,否则工具调用会失败。

3.3 回归测试(可选)

如果你需要对候选补丁做回归测试选择,README 说明可参考 Agentless 的 SWE-bench 回归测试流程(对应其 README 中的README_swebench.md)。这里的关键约定是:结果条目中的regression字段描述测试结果——

  • 空数组[]:该补丁通过了全部回归测试;
  • 非空数组:该补丁导致了测试失败,数组内为失败的具体测试名。

3.4 输入数据准备

  • 实例文件(如swebench-verified.json):SWE-bench 风格的问题实例列表,每个实例需包含instance_idproblem_statementbase_commit等字段(源码中分别用于构造镜像名、注入 issue 描述与 checkout 基线提交);
  • 候选补丁文件:JSON Lines 格式,详见下一节。

四、输入格式:候选补丁 JSONL

补丁候选存放在一个 JSON Lines 文件中,每行一个实例,结构如下:

{ "instance_id": "django__django-14017", "issue": "Issue description....", "patches": [ "patch diff 1", "patch diff 2", "...", "patch diff N" ], "success_id": [ 1, 0, "...", 1 ], "regressions": [ [regression_test_names for patch diff 1..], [regression_test_names for patch diff 2..], "...", [regression_test_names for patch diff N..] ] }

字段说明:

字段含义是否必填
instance_id与实例文件中一致的实例 ID,用于关联与文件命名
issueIssue 描述文本
patchesN 个候选补丁的 diff 字符串列表
success_idpatches一一对应的正确性标签,1表示该补丁是正确的,0表示错误
regressionspatches一一对应的回归测试结果列表,空数组表示通过全部回归测试

说明:success_id的作用在于离线评估——一旦 Selector Agent 选出某个补丁,就可以立刻对照success_id判断这次选择是否正确。regressions为可选项;如果你已经用 Agentless 做过回归测试选择,可以在这里填入筛选出的回归测试名。若数据中没有regressions字段,selector.py 会自动为每个候选补丁填充空数组。

仓库自带的示例数据 evaluation/patch_selection/example/example.jsonl 就是一个真实样例:astropy__astropy-14369(astropy 的 CDS 单位解析 bug),包含 10 个候选补丁,success_id[0, 1, 1, 0, 1, 1, 1, 0, 1, 1],其中 7 个是正确的、3 个是错误的。

五、运行 Patch Selection

5.1 标准命令

在仓库根目录执行:

python3 evaluation/patch_selection/selector.py \ --instances_path "path/to/swebench-verified.json" \ --candidate_path "path/to/patch_candidates.jsonl" \ --result_path "path/to/save/results" \ --num_candidate NUMBER_OF_PATCH_CANDIDATES_PER_INSTANCE \ --max_workers 10 \ --group_size GROUP_SIZE \ --max_retry 20 \ --max_turn 200 \ --config_file trae_config.yaml \ --model_name MODEL_NAME_IN_CONFIG_FILE \ --majority_voting

5.2 参数详解

对照 selector.py 中的 argparse 定义,各参数的默认值与说明如下:

参数默认值说明
--instances_pathswe_bench/swebench-verified.jsonSWE-bench 实例 JSON 文件路径
--candidate_path必填候选补丁 JSONL 文件路径
--result_path必填结果保存目录(会在其中创建log/output/patch/statistics四个子目录)
--num_candidate10每个实例的候选补丁数量
--max_workers10并发处理实例的最大进程数(底层使用ProcessPoolExecutor
--group_size10每个分组的候选补丁数量
--max_retry3单个实例处理失败后的最大重试次数(每次重试会重新启动沙箱容器)
--max_turn50Selector Agent 单次选择的最大对话轮数
--majority_voting关闭是否启用多数投票模式(BooleanOptionalAction
--config_fileconfig.yamlLLM 配置文件路径
--model_namedefault_model配置文件中要使用的模型名

5.3 LLM 配置要求

selector.py启动时会读取--config_file指定的配置文件(仓库提供trae_config.yaml.exampletrae_config.json.example作为模板),并校验:

  • 配置中必须包含models字段,否则抛出No models found in config file.
  • --model_name必须存在于models中,否则抛出Model {name} not found in config file.

随后它会取出对应的llm_config并调用resolve_config_values()完成环境变量等值的解析,最终用于构造 LLMClient 与 Agent 的工具集。

5.4 group_size 与多数投票:应对大规模集成空间

README 给出了一个典型调优场景:如果候选补丁很多(例如 50 个),可以将group_size设为 10。此时 50 个候选会被切成 5 组(selector_evaluation.py中的range(0, num_candidate, group_size)逻辑),每组独立运行一次选择,每组产出一个所选补丁;如果需要,再对这 5 个结果做二次选择。

--majority_voting是可选项。开启后,对每个候选组会进行多次独立的选择实验,最终以被选中频率最高的补丁作为该组的最终答案。从 selector_evaluation.py 的实现看,多数投票模式还有提前终止优化:当某个补丁的选中次数超过num_candidate / 2时即停止继续投票,降低开销。README 也明确提醒:该模式会消耗更多 token,适合对选择质量要求高、预算充足的场景。

六、运行结果与产物解读

6.1 结果目录结构

README 说明,用 example.jsonl 运行后,在result_path下会得到如下文件结构:

├── log │ └── group_0 │ └── astropy__astropy-14369_voting_0_trail_1.json ├── output │ └── group_0 │ └── astropy__astropy-14369.log ├── patch │ └── group_0 │ └── astropy__astropy-14369_1.patch └── statistics └── group_0 └── astropy__astropy-14369.json

各目录含义:

目录内容用途
log每个实例每次选择的LLM 交互历史(JSON,由TrajectoryRecorder写入,文件名形如<instance_id>_voting_<idx>_trail_<n>.json审计、调试与复盘 Agent 的推理过程
output每个实例处理过程的原始标准输出与标准错误.log文件)排查运行错误、查看重试过程
patch被选中的补丁(diff 文本,文件名形如<instance_id>_<n>.patch直接可用的修复补丁产物
statistics选择结果统计(JSON:instance_idpatch_idis_successis_all_successis_all_failed判断所选补丁是否正确、供分析脚本聚合

6.2 断点续跑与跳过逻辑

从 selector_evaluation.py 的实现可以看出两个值得注意的行为:

  • 断点续跑:如果某实例某分组的 statistics JSON 已存在且非空,则该组会被跳过(has already been processed. Skipping...),因此中断后重跑不会重复消耗 token;
  • 全对/全错跳过:如果一组候选全部正确(all_success)或全部错误(all_failed),则无需 Agent 选择,直接取第一个候选并写入统计(is_all_success/is_all_failed标记为 true)。这也意味着statisticsneed_to_select概念指的是"确实需要靠选择来区分正误"的分组。

6.3 用 analysis.py 可视化统计结果

selector.py运行过程中(或运行结束后),都可以用分析脚本实时查看中间结果:

python3 analysis.py --output_path "path/to/save/results"

analysis.py 会扫描statistics目录下的所有分组,聚合出以下指标并以 rich 表格打印,同时写入analysis.csv

指标含义
total该分组已处理的实例数
completion_rate完成率(total除以总实例数,脚本中默认分母为 500,可按需调整)
all_success/all_failed候选全部正确 / 全部错误而跳过的实例数
need_to_select真正需要 Agent 做出选择的实例数
success_selection选对(is_success == 1)的实例总数
success_selection_in_need_to_select在"需要选择"的实例中选对的个数
success_rate_in_need_to_select需要选择场景下的选择成功率
success_rate_among_all全量实例上的成功率

表格中会用下划线加粗标出success_rate_in_need_to_selectsuccess_rate_among_all最高的分组,方便横向对比不同分组/不同投票策略的效果。也支持通过--group_id只分析某个指定分组。

七、源码级原理:Selector Agent 是怎么"选"的

7.1 系统提示词与四步工作流

selector_agent.py 中的build_system_prompt将 Agent 定义为"专家代码评估者"(expert code evaluator),并给出明确的工作流程:

  1. 理解 Issue 与代码库:阅读 issue 描述,必要时检查 issue 引用的代码、每个补丁修改的原始代码、同一文件未改动部分,以及与被改代码交互的相关文件、函数、模块;
  2. 分析候选补丁:逐个分析每个补丁的逻辑与意图,判断改动是否与 issue 描述及编码规范一致;
  3. 验证功能(可选但推荐):必要时编写并运行单元测试,评估每个补丁的正确性与潜在副作用;
  4. 选择最佳补丁:选出"以最小引入新问题风险解决 issue"的补丁。

提示词还强制规定了三条原则与输出格式:不得回避选择;不得提出新补丁;候选集中至少存在一个正确补丁。最终报告必须形如:

### Status: succeed ### Result: Patch-x ### Analysis: [Explain why Patch-x is correct.]

Agent 的输入由三部分组成:上述系统提示词 + 代码库路径与 issue 描述 + 按Patch-1Patch-2……编号的候选补丁列表(selector_agent.py)。

7.2 工具调用与答案解析

SelectorAgent 只配备两个工具(selector_agent.py):

  • bash:在容器内执行任意命令(底层对应 trae_selector/tools/tools/execute_bash.py);
  • str_replace_based_edit_tool:基于字符串替换的代码编辑工具(对应 trae_selector/tools/tools/execute_str_replace_editor.py)。

在每一轮对话中(最多max_turn轮):

  1. LLM 返回文本或工具调用;
  2. 若返回的工具名合法,parse_tool_response会把参数拼接成容器内命令,例如cd /home/swe-bench/tools/ && /home/swe-bench/py312/bin/python3 execute_str_replace_editor.py --command ...,通过沙箱会话执行并读回Tool Call Status: 0/-1与输出(selector_agent.py);
  3. 若返回文本中匹配到Status: success/succeed/...Result: Patch-x的模式(正则见 selector_agent.py),则结束循环,返回对应补丁;若Patch-x编号不合法则回退到第一个候选。

每一轮交互都会被TrajectoryRecorder完整记录到log目录,供事后复盘。

7.3 沙箱:仓库级理解的"动手"基础

trae_selector/sandbox.py 负责为每个实例构建隔离环境:

  • 镜像名为swebench/sweb.eval.x86_64.<instance_id 中 "__" 替换为 "_1776_">:latest
  • 启动后执行git checkout <base_commit>,把代码库恢复到 issue 对应的基线提交;
  • trae_selector/tools目录通过docker cp复制到容器内/home/swe-bench/,与 py312 运行时配合形成可执行的 Agent 工具环境;
  • 每次选择前后都会执行git reset --hard HEAD,确保代码库状态干净。

7.4 候选预处理:回归筛选与去重

在启动 Selector Agent 之前,selector_evaluation.py 会对候选做两道预处理:

  1. 回归测试筛选:跳过 diff 为空串的候选;若某个候选的regressions为空(即通过了回归测试),则优先只保留这些通过回归的候选(candidate_list_regression);
  2. 补丁去重:用 utils.py 中的clean_patch将每个补丁规范化为"去除注释与空白后的增删行序列",以此作为去重键,保证同一思路的多个等价补丁只保留一份。

八、常见问题与注意事项

  • 运行前务必确认 py312 目录就位:未解压 Python 3.12 包是工具调用失败的最常见原因;
  • 镜像缺失:Selector Agent 依赖本机已存在的sweb.eval.x86_64.*SWE-bench 镜像,需要提前按 SWE-bench 官方流程构建对应实例的 Docker 镜像;
  • token 成本控制:候选越多、--majority_voting开启、--max_turn越大,token 消耗越高。建议先用小规模候选(如--num_candidate 10 --group_size 10)跑通流程,再逐步放大;
  • 结果可复现log目录保留了全部交互历史,statistics目录支持断点续跑,出现异常时可结合output目录的原始日志定位问题;
  • 配置校验:确保--config_file中的models非空且--model_name在其中,否则入口脚本会直接报错退出。

九、结语

Selector Agent 把"从候选补丁中找正确修复"建模为一次在真实代码库环境中的推理搜索,用模块化的生成—剪枝—选择流程化解了集成空间过大与仓库理解不足两大难题。结合本仓库的 selector.py、example.jsonl 与 analysis.py,你可以立即在自己的 SWE-bench 评测上复现这一流程,并将其作为 Trae Agent 各类软件工程任务评测链路中的"最后一公里"组件。

【免费下载链接】trae-agentTrae Agent is an LLM-based agent for general purpose software engineering tasks.项目地址: https://gitcode.com/gh_mirrors/tr/trae-agent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询