深入解析 mini-swe-agent:极简架构下的强大AI软件工程代理

📅 2026/7/6 3:25:00
深入解析 mini-swe-agent:极简架构下的强大AI软件工程代理
mini-swe-agent这个项目是 SWE-agent 团队推出的一个极简但功能强大的 AI 软件工程代理Agent。它旨在用极简的代码实现核心的智能体循环同时保持强大的代码修复能力。一、核心实现架构与技术细节mini-swe-agent的实现非常精炼核心就是一个 while 循环和一套基于异常的信号传递机制否是异常信号处理Submitted成功提交LimitsExceeded达到资源限制FormatError模型输出格式错误开始: 接收问题如GitHub Issue初始化环境与提示LLM推理思考行动执行工具Bash/编辑器捕获观察结果与异常信号循环终止判断输出最终补丁或结果1.1 控制流异常驱动的循环主循环用一个 while 不断调用 LLM 获取下一个动作然后执行该动作并获取观察结果。终止信号循环的终止不是通过复杂的条件判断而是通过抛出和捕获特定的异常来实现。定义了InterruptAgentFlow异常层级包含submitted成功提交LimitsExceeded达到操作次数或时间限制FormatError模型输出格式无法解析消息传递这些异常不仅用于控制流还能携带消息有效载荷。run()方法会捕获这些异常将消息注入对话历史然后根据异常类型决定是继续循环如格式错误是可以重试的还是终止循环如成功提交就可以正常终止。这种设计将控制逻辑和业务逻辑清晰分离。1.2 工具系统YAMLBASH工具定义工具签名、文档字符串和参数说明通过一个 YAML 配置文件定义。这使其能渲染为函数调用的JSON Schema 或系统提示词中的工具文档工具实现每个工具就是一个独立的 BASH 脚本bin/目录。这样有三大好处通用可移植性Bash 脚本可以在 Linux 容器中运行安装简单只需将工具目录复制到沙箱环境并运行一个install.sh脚本文档自动生成工具的文档直接源自 YAML 定义无需手动维护状态共享工具之间不共享 Python 对象状态而是通过环境变量、文件系统和_state命令的 JSON 输出进行通信一个工具包的最小规范示例根据其设计协议一个自定义工具包至少需要包含一下文件tools/my_bundle/ ├── config.yaml # 工具定义 ├── bin/ │ └── my_command # 工具实现Bash脚本 └── install.sh # 依赖安装脚本可选config.yamltools:my_command:signature:my_command arg1 [arg2]docstring:这个工具的功能描述给 LLM 看arguments:-{name:arg1,type:string,required:true,description:第一个参数的说明}-{name:arg2,type:integer,required:false,description:第二个参数的说明可选}state_command:_my_state# 可选每次动作后运行的命令用于输出状态 JSONenv_variables:# 可选注入到运行时的环境变量MY_VAR:default_valuebin/my_command#!/usr/bin/env_basharg1$1arg2${2:-}# 这里实现工具的具体逻辑echo执行 my_command参数1:$arg1, 参数2:$arg21.3 提示词工程结构化与过程化引导精心设计的提示词模板极简系统提示词“You are a helpful assistant that can interact with a computer to solve tasks.”。所有与具体任务相关的上下文如问题描述、仓库路径都放在实例提示词中。这样能让系统提示词被 LLM KV 缓存。过程化指令明确引导 LLM 遵循一个类似人类工程师的五步工作流阅读与理解首先阅读和代码库中与问题描述相关的代码复现问题创建一个脚本来复现错误并用python filename.py执行它编辑修复编辑仓库的源代码来解决问题验证修复重新运行复现的脚本并确认错误已被修复考虑边缘情况思考边缘情况确保你的修复也能处理他们无演示Zero-shot二、项目拆解分析初始化调用返回结果/环境信息支撑模型与环境层LLM 模型抽象models/执行环境抽象environments/核心智能体循环DefaultAgentagents/default.pyAgent Loopwhile True提示构建与模板渲染LLM 推理调用动作解析与执行观察结果与异常处理入口与配置层CLI / Python APIrun/mini.py配置加载与合并config/2.1 生命周期初始化系统首先从配置文件和命令行参数中加载和合并配置随后根据配置实例化模型、环境和智能体本身运行Agent 的run()方法被调用启动核心的智能体循环。循环内部不断进行思考-行动-观察ReAct 的迭代直到完成或达到某个限制终止循环通过异常机制优雅推出整个执行轨迹消息、动作、成本等序列化为一个 JSON 文件保存下来便于分析和回放。2.2 Agent Loop# 伪代码源于default.py的run方法defrun(self,task):# 初始化消息历史self.messages[system_message,instance_message]whileTrue:try:# 1. 调用LLM获取下一步动作responseself.model.query(self.messages)# 2. 解析动作并执行action,observationself.env.execute(response)# 3. 将结果添加到历史self.messages.append({role:assistant,content:response})self.messages.append({role:user,content:observation})exceptInterruptAgentFlowase:# 4. 捕获特定异常来控制流程ifisinstance(e,Submitted):break# 成功完成退出循环elifisinstance(e,(LimitsExceeded,TimeExceeded)):break# 达到限制退出循环elifisinstance(e,FormatError):# 处理格式错误可能重试self.n_consecutive_format_errors1ifself.n_consecutive_format_errorsself.config.max_consecutive_format_errors:break2.3 Tool执行逻辑在环境中通过命令行调用实现。环境负责接收 LLM 的工具调用指令并将其映射为具体的系统命令执行然后捕获输出返回给 Agent2.4 Environment核心类local.py实现了在本地文件系统上执行命令的LocalEnvironment这是最常用的环境。此外singularity.py等提供了在容器如 Singularity中执行的环境用于隔离和安全性。职责环境的职责时执行动作并返回观察结果它接收来自 Agent 的字符串执行如 Bash 命令或一个编辑指令在目标工作目录中执行并将命令的输出、执行状态等信息格式化后返回给 Agent作为下一轮循环的输入。2.5 Prompt通过模板变量的方式分离了结构和内容模板定义提示词的骨架模板定义在配置文件如config/mini.yaml中。system_template系统提示定义 Agent 的角色、能力和行为规范。instance_template示例提示包含具体的任务描述。变量填充与渲染在运行时Agent 的get_template_vars()方法会收集来自配置、环境、模型以及当前状态的所有变量合并成一个dict用Jinja2模板引擎进行渲染生成最终发送给 LLM 的完整提示词。动态上下文模板可以引用动态变量例如{{working_dir}}当前工作目录{{problem_statement}}问题描述2.6 Memory非常直接用完整的消息历史列表存储位置记忆保存在DefualtAgent实例的self.messages属性中这是一个list按顺序存储完整的对话历史内容遵循 OpenAI 的消息格式[{role:system, content:系统提示}]持久化运行结束后这个完整的 messages 列表会被序列化为 JSON。2.7 LLM 调用models模块中模型抽象该目录定义了模型接口调用各种 LLM API 基于 LiteLLM调用点在 Agent Loop 的每一次迭代中self.model.query(self.messages)会被调用query 方法接收完整历史消息返回模型响应。配置模型名称、API 密钥、参数如温度Top-p并在模型初始化时传入2.8 各个模块之间如何通信模块间通信遵循“依赖注入”和“显式方法调用”的原则清晰且低耦合Agent 初始化时接收实例化的Model和Environment对象。Agent 调用 Model通过self.model.query()。Agent 调用 EnvironmentAgent 将 LLM 的响应传递给self.env.execute()。Environment 执行命令后将观察结果字符串返回给 Agent。配置作为 “胶水”YMAL 配置指定了要使用的模型类、环境类及其初始化参数。get_model和get_enviroment等工厂函数根据配置动态创建相应实例