ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SWE-agent Tool Bundle 配置详解:从 BundleConfig、Command 到 Argument 的完整实践指南

2026/9/13 22:57:07 拓冰建站 浏览量
SWE-agent Tool Bundle 配置详解:从 BundleConfig、Command 到 Argument 的完整实践指南 SWE-agent Tool Bundle 配置详解从 BundleConfig、Command 到 Argument 的完整实践指南【免费下载链接】SWE-agentSWE-agent takes a GitHub issue and tries to automatically fix it, using your LM of choice. It can also be employed for offensive cybersecurity or competitive coding challenges. [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/sw/SWE-agent导读在 SWE-agent 中Agent 的能力边界由一组可执行工具tools决定而这组工具的组织与管理正是通过Tool Bundle工具包机制实现的。本文以仓库文档 docs/reference/bundle_config.md 为主体结合源码 sweagent/tools/bundle.py、sweagent/tools/commands.py 及仓库内的真实 bundle 配置系统讲解 Tool Bundle 的配置模型顶层BundleConfig如何声明工具与状态命令Command如何定义可执行命令及其签名Argument如何描述命令参数。读完本文你将掌握如何阅读、编写、校验和扩展一个 SWE-agent 工具包为 Agent 定制专属工具集。一、概念澄清Tool Bundle 配置 ≠ 工具配置在深入配置字段之前必须先厘清一个容易混淆的概念边界。仓库文档在开头就明确提示这是用于配置tool bundle的页面而不是配置 Agent 正在使用的工具的页面。后者请参见 tools configuration。也就是说SWE-agent 中工具相关的配置分两层层级对应文档作用对象核心内容工具配置ToolConfigdocs/reference/tools_config.mdAgent 运行时启用哪些 bundle、环境变量、超时、解析函数、过滤规则等工具包配置BundleConfigdocs/reference/bundle_config.md本文bundle 目录内的config.yaml声明工具命令集合与状态命令从源码看二者的关系非常清晰ToolConfig中有一个bundles: list[Bundle]字段见 sweagent/tools/tools.py而Bundle对象在加载时会读取其所在目录下的config.yaml并解析为BundleConfig。因此可以这样理解bundle 配置是生产工具的配方工具配置是装配工具的清单。二、BundleConfigbundle 配置的顶层模型BundleConfig定义在 sweagent/tools/bundle.py 中是整个 bundle 配置文件config.yaml对应的 Pydantic 数据模型class BundleConfig(BaseModel): tools: dict[str, dict] state_command: str | None None它只有两个字段tools必填一个字典key 是工具命令名value 是对应的Command配置字典。例如searchbundle 的 tools/search/config.yaml 中定义了find_file、search_dir、search_file三个工具。state_command可选一个特殊的命令名在每次 Agent 动作之后执行用于输出环境状态详见下文第四部分。2.1 Bundle 的加载与校验流程BundleConfig通常不是直接被使用者手动构造的而是由Bundle模型在加载时自动解析。Bundle的validate_tools校验器sweagent/tools/bundle.py#L22-L41完成了如下步骤将path转换为绝对路径校验 bundle 目录存在校验目录下存在config.yaml读取并yaml.safe_load该文件构造BundleConfig校验hidden_tools隐藏工具列表中的每一项都真实存在于tools键集合中否则抛出ValueError。2.2 hidden_tools动态隐藏工具Bundle还支持hidden_tools: list[str]字段用于在不修改 bundle 配置文件的情况下屏蔽其中的某些工具。其实现位于Bundle.commands属性sweagent/tools/bundle.py#L52-L57property def commands(self) - list[Command]: return [ Command(nametool, **tool_config.model_dump() if isinstance(tool_config, Command) else tool_config) for tool, tool_config in self.config.tools.items() if tool not in self.hidden_tools ]注意这里的关键细节tools中的每个配置字典会被展开为Command(nametool, **tool_config)构造为命令对象同时过滤掉hidden_tools中列出的名称。hidden_tools的用法在测试 tests/test_run_single.py#L48-L63 中有直接体现Bundle(pathTOOLS_DIR / windowed, hidden_tools[scroll_up])—— 加载windowedbundle 但隐藏其scroll_up工具。这种机制特别适合在不改动公共 bundle 的前提下为不同任务场景裁剪工具面。2.3 state_command 属性透传Bundle通过state_command属性直接透传config.state_commandsweagent/tools/bundle.py#L43-L45而ToolConfig.state_commandssweagent/tools/tools.py#L158-L164会聚合所有 bundle 的 state_command 并在每个动作后依次执行。三、Command定义一个可执行命令Command类是 bundle 中每个工具的核心模型定义在 sweagent/tools/commands.py#L79-L205。其字段如下字段类型默认值含义namestr必填命令名Agent 在回复中以此调用工具docstringstr | None必填命令的人类可读描述会注入模型提示词signaturestr | NoneNone自定义调用签名覆盖默认的name arg1 arg2 ...end_namestr | NoneNone多行命令的终止标记一旦设置即表示这是多行命令argumentslist[Argument][]命令接受的参数列表3.1 单行命令与多行命令Command的end_name字段是区分两类命令的关键单行命令end_name为None命令在一行内完成如find_file、scroll_up多行命令end_name非空命令体可以跨越多个行并以end_name作为终止标记。这类命令的完整定义可以在 sweagent/tools/parsing.py 与 sweagent/tools/utils.py 的解析逻辑中看到ToolHandler.guard_multiline_input会利用end_name以 heredoc 形式包裹多行参数发送到 bashsweagent/tools/tools.py#L382-L409。ToolConfig.model_post_init会收集所有带end_name的命令构造multi_line_command_endings字典供解析器使用sweagent/tools/tools.py#L201-L213。3.2 invoke_format调用格式的生成Command.invoke_formatsweagent/tools/commands.py#L102-L131决定了如何把参数拼进命令字符串。其逻辑分两种情况提供signature时先校验每个参数名确实以name、[name]、{name}或--name中的某一种形式出现在签名中然后通过正则re.sub(rf\[?({ARGUMENT_NAME_PATTERN})\]?, r{\1}, self.signature)把尖括号占位符替换为 Python format 占位符未提供signature时按默认格式name {arg1} {arg2} ...拼接。以 tools/search/config.yaml 为例find_file: signature: find_file file_name [dir] arguments: - name: file_name type: string required: true - name: dir type: string required: false这里file_name必填与[dir]可选展示了签名中两种占位符的写法invoke_format会将其转换为find_file {file_name} {dir} 。3.3 validate_arguments编写命令时的自检约束Command.validate_argumentssweagent/tools/commands.py#L167-L205在模型构造时执行多项校验编写自定义命令时需注意必填参数必须在可选参数之前否则报错Required argument ... cannot come after optional arguments参数名不得重复参数名必须匹配正则[a-zA-Z_][a-zA-Z0-9_-]*sweagent/tools/commands.py#L30签名/调用格式中的占位符集合必须与arguments的参数名集合完全一致否则报错_extract_keys通过string.Formatter解析出格式字符串中的所有字段名。3.4 get_function_calling_tool与 Function Calling 的桥接当parse_function配置为 function calling 解析器时Command.get_function_calling_toolsweagent/tools/commands.py#L133-L165会把命令转换为 OpenAI 风格的 function schema工具名 command.name描述 docstring每个Argument映射为一个 JSON Schema 属性含type、description、可选的items、enumrequired: true的参数进入required列表。这正是ToolConfig.tools属性sweagent/tools/tools.py#L193-L195的实现基础[command.get_function_calling_tool() for command in self.commands]。四、Argument参数的类型化描述Argument类定义在 sweagent/tools/commands.py#L52-L76为命令参数提供类型化描述字段如下字段类型默认值含义namestr必填参数名需匹配[a-zA-Z_][a-zA-Z0-9_-]*typestr必填参数类型如string、integeritemsdict[str, str] | NoneNone数组元素类型的描述如{type: string}descriptionstr必填参数的人类可读描述requiredbool必填是否必填enumlist[str] | NoneNone可枚举的取值白名单argument_formatstr{{value}}参数在命令中的渲染格式必须使用 Jinja 语法{{value}}而非{value}argument_format有一个专门的校验器validate_argument_formatsweagent/tools/commands.py#L73-L76调用 sweagent/utils/jinja_warnings.py 中的_warn_probably_wrong_jinja_syntax来提醒开发者避免误用单花括号。在实际配置中enum常用于约束参数取值范围。从源码注释可见其设计意图它既会进入 function calling schema 的enum字段帮助模型在结构化输出时只选择合法值。五、实战完整的 bundle 配置范例结合上述三个模型一个真实且完整的 bundle 配置应同时具备tools与可选的state_command。下面以仓库中的 tools/windowed/config.yaml 为例展示全貌tools: goto: signature: goto line_number docstring: moves the window to show line_number arguments: - name: line_number type: integer description: the line number to move the window to required: true open: signature: open path [line_number] docstring: opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line arguments: - name: path type: string description: the path to the file to open required: true - name: line_number type: integer description: the line number to move the window to (if not provided, the window will start at the top of the file) required: false create: signature: create filename docstring: creates and opens a new file with the given name arguments: - name: filename type: string description: the name of the file to create required: true scroll_up: signature: scroll_up docstring: moves the window up {WINDOW} lines arguments: [] scroll_down: signature: scroll_down docstring: moves the window down {WINDOW} lines arguments: [] state_command: _state这个范例展示了几个常见模式无参数命令scroll_up、scroll_down的arguments为空列表其docstring中的{WINDOW}由 sweagent/tools/utils.py 的文档生成逻辑结合env_variables渲染generate_command_docs会把环境变量传入文档模板必填/可选参数组合open的path必填、line_number可选对应签名中path与[line_number]的写法差异整数参数line_number的类型是integer在 function calling schema 中会生成{type: integer}。再对比 tools/diff_state/config.yamltools: {} state_command: _state_diff_state该 bundle 不定义任何工具只注册一个state_command用于在每个动作后输出 diff 相关状态——这证明了tools与state_command是两个正交的维度。六、state_command动作后的状态采集机制state_command是 bundle 配置中一个极易被忽视但作用关键的字段。其工作流程在 sweagent/tools/tools.py#L337-L348 的ToolHandler.get_state中体现依次执行所有 bundle 的state_command读取环境中的/root/state.json解析 JSON 并返回状态字典供提示词模板格式化使用。在 docs/config/tools.md 中给出了经典 SWE-agent 窗口工具的状态命令实现_state脚本它通过 registry 读取当前打开的文件输出{open_file: ..., working_dir: ...}这样的 JSON。该状态字典随后可用于模板中的占位符例如在提示词里展示当前工作目录与当前打开文件。state_command也可以叠加多个 bundle 使用ToolConfig.state_commands会把所有 bundle 的state_command收集起来依次执行最终合并读取/root/state.json的内容sweagent/tools/tools.py#L158-L164。七、将 bundle 接入 Agent在 ToolConfig 中装配了解了 bundle 自身的配置模型后最后一步是把它接入 Agent。在 Agent 配置如 config/default.yaml的tools.bundles中按路径引用即可tools: bundles: - path: tools/registry - path: tools/edit_anthropic - path: tools/review_on_submit_m enable_bash_tool: true parse_function: type: function_calling装配后ToolConfig.commandssweagent/tools/tools.py#L167-L191会若enable_bash_tool为 true先加入内置的BASH_COMMAND定义在 sweagent/tools/commands.py#L209-L223即Command(namebash, signaturecommand, ...)遍历所有 bundle 的命令检测重名工具同一命令名在不同 bundle 中重复定义会直接抛错错误信息会指出首次定义与重复定义的来源路径。ToolHandler._install_commandssweagent/tools/tools.py#L292-L312则负责把 bundle 上传到容器执行install.sh并逐一校验命令在容器中可用which command。八、小结围绕 docs/reference/bundle_config.md 的三个核心类本文完成了从理论到实践的完整梳理BundleConfigsweagent/tools/bundle.py#L12-L15bundle 配置文件的顶层模型tools必填、state_command可选Commandsweagent/tools/commands.py#L79-L205定义命令名、文档、签名、多行终止标记与参数并通过invoke_format生成调用格式、get_function_calling_tool桥接结构化输出构造时还有严格的参数顺序与签名一致性校验Argumentsweagent/tools/commands.py#L52-L76类型化参数描述支持type、required、enum、items与 Jinja 风格的argument_format。三个类共同构成了 SWE-agent 工具扩展的最小可编程单元。如果你希望新增一个自定义工具推荐的路径是先阅读 docs/config/tools.md 了解 bundle 目录结构与装配方式再参照本文的字段规范编写config.yaml最后参考 docs/usage/adding_custom_tools.md 的教程完成落地。每一个字段的合法性都由 Pydantic 校验器在加载时守护出错信息会直接指出问题所在这让自定义工具的开发过程既灵活又可控。【免费下载链接】SWE-agentSWE-agent takes a GitHub issue and tries to automatically fix it, using your LM of choice. It can also be employed for offensive cybersecurity or competitive coding challenges. [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/sw/SWE-agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考