mini-swe-agent源码解读(进行中)

发布于:2025-08-03 ⋅ 阅读:(16) ⋅ 点赞:(0)

https://github.com/SWE-agent/mini-swe-agent
虽然声称100行代码的Agent(The 100 line AI agent),但实际上这个仓库几万行代码
在这里插入图片描述
说实在的,我读的速度都没有他写的速度快。

前置准备:

1、知道使用litellm调用大模型
2、prompt_toolkit来获取用户的终端输入
3、使用from rich.console import Console进行终端的输出
4、使用platformdirs获取用户目录,finding the right location to store user data and configuration varies per platform
5、typer: typer命令行工具开发库,说起typer你可能不知道,但是fastapi可能听过,typer和fastapi的主要开发者都是tiangolo。

6、变成系统命令
[project.scripts]
mini = “minisweagent.run.mini:app”
mini-swe-agent = “minisweagent.run.mini:app”
mini-extra = “minisweagent.run.mini_extra:main”
mini-e= “minisweagent.run.mini_extra:main”
7、使用dotenv从.env加载环境变量

dotenv.load_dotenv(dotenv_path=global_config_file)
8、使用subprocess.run来执行命令,这个是此agent能起作用的核心
(我们好奇cursor生成文件和修改文件用的是什么?)
9、from jinja2 import Template模版的渲染

入口

python run/mini.py -t “say hello world”

代码中抽象出了几个概念
model
agent:代理中有执行环境和model
Environments: 这个不是环境变量,这个分为本地环境和docker环境,环境可以执行命令

先从最令人激动的点模型调用说起

LitellmModel

model.query封装了litellm,这块可以理解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

role有: system user assistant
当通过api来调用大模型的时候,就这三个
剩下的就是你怎么利用大模型的返回值了

然后看看对话是怎么处理的?

初始 self.messages: list[dict] = []是空的

system_template: str = "You are a helpful assistant that can do anything."
instance_template: str = (
    "Your task: {{task}}. Please reply with a single shell command in triple backticks. "
    "To finish, the first line of the output of the shell command must be 'MINI_SWE_AGENT_FINAL_OUTPUT'."
)
 self.messages = []
    self.add_message("system", self.config.system_template)
    self.add_message("user", self.render_template(self.config.instance_template, task=task))

第一次增加系统提示词和用户提示词
对话完成后,会把大模型的返回值,存储到self.messages里面,这样下次继续带着对话。

agent.run

    def run(self, task: str) -> tuple[str, str]:
        """Run step() until agent is finished. Return exit status & message"""
        self.messages = []
        self.add_message("system", self.config.system_template)
        self.add_message("user", self.render_template(self.config.instance_template, task=task))
        while True:
            try:
                self.step()
            except NonTerminatingException as e:
                self.add_message("user", str(e))
            except TerminatingException as e:
                self.add_message("user", str(e))
                return type(e).__name__, str(e)

这是随便找的一个,你看在同一个对话下的数据实际上都携带着呢
在这里插入图片描述

查看流程图

在这里插入图片描述

execute前进行确认

在这里插入图片描述

# 这段代码学到了
        match user_input := self._prompt_and_handle_special(prompt).strip():
            case "" | "/y":
                pass  # confirmed, do nothing
            case "/u":  # Skip execution action and get back to query
                raise NonTerminatingException("Command not executed. Switching to human mode")
            case _:
                raise NonTerminatingException(
                    f"Command not executed. The user rejected your command with the following message: {user_input}"
                )

mode有三种
_MODE_COMMANDS_MAPPING = {“/u”: “human”, “/c”: “confirm”, “/y”: “yolo”}

命令的解析和执行
output = self.execute_action(self.parse_action(response))


好多人
在这里插入图片描述


思考:

意图识别、对话压缩

可以增加意图识别,因为用户的输入不一定就是任务,可以在任务前增加一个意图识别的过程。

如果即将超出上下文的显示可以对对话进行压缩