openmanus调通案例和源码走读
背景
OpenManus 是由 MetaGPT 团队开发的一个开源的多功能 AI 助手系统,旨在复刻并优化 Manus 的核心功能。它无需邀请码即可使用,支持本地化部署,能够执行多种复杂任务,如代码生成、文件处理、网络信息检索和网页自动化操作。截止到今天,它的github星标如下,妥妥的一炮走红

安装
遵循官方的教程,我们开始安装, 首先确保你的电脑有conda,如下是在windows下安装的
-
step1:
conda create -n open_manus python=3.12conda activate open_manus
-
step2: 我们将仓库下载到本地,比如这个目录下

然后执行如下命令
cd D:\Work\pywork\openmauns\OpenManus-mainpip install -r requirements.txt
后面就是漫长的等待了。。。。,下载好了之后,我们到
修改一下config.toml文件,改为如下
# Global LLM configuration[llm]model = "moonshot-v1-8k"base_url = "https://api.moonshot.cn/v1"api_key = "sk-SCGEM75yGFGMthlW4qUCHbXWp8zBHsV2fFMoZJvTv0cMs6z9"max_tokens = 4096temperature = 0.0# [llm] #AZURE OPENAI:# api_type= 'azure'# model = "YOUR_MODEL_NAME" #"gpt-4o-mini"# base_url = "{YOUR_AZURE_ENDPOINT.rstrip('/')}/openai/deployments/{AZURE_DEPOLYMENT_ID}"# api_key = "AZURE API KEY"# max_tokens = 8096# temperature = 0.0# api_version="AZURE API VERSION" #"2024-08-01-preview"# Optional configuration for specific LLM models[llm.vision]model = "claude-3-5-sonnet"base_url = "https://api.openai.com/v1"api_key = "sk-..."
我这里用的是kimi的api,你如何申请了记得修改喜爱model base_url api_key这三个参数哦
-
step3:
cd D:\Work\pywork\openmauns\OpenManus-mainpython main.py
会出现如下的界面

我们输入我们要让它做的事

可以看到,上面开始运行了
代码走读
整个框架非常简单,如下所示

主要的就一个main文件以及app文件夹里面的一些脚本,我是小白,先看下main.py,如下

主要我们看下其最后调用的app.run。

该函数位于app/agent目录下,在此目录下的文件还有
-
manus.py -
planning.py(负责规划) -
react.py(自我反思是自主智能体) -
swe.py(SWEAgent是OpenManus项目中的一个组件,主要负责编程相关的任务) -
base.py(管理agent的抽象类)
我们挨个来看每个py文件
manus.py
classManus(ToolCallAgent):""" 一个多功能通用代理,通过规划来解决各种任务。 该代理扩展了 PlanningAgent,具备一套全面的工具和能力, 包括 Python 执行、网页浏览、文件操作和信息检索, 以处理广泛的用户请求。 """
父类是ToolCallAgent,顾名思义ToolCallAgent就是工具调用的agent,当然,Manus这个类里面还有很多参数,我们有时间继续看
planning,py
classPlanningAgent(ToolCallAgent):""" 一个创建并管理计划以解决任务的代理。 该代理使用规划工具来创建和管理结构化计划, 并通过各个步骤跟踪进度,直到任务完成。 """
父类是ToolCallAgent
react.py
这个类是比较重要的,是一个基于 ReAct(Reasoning and Acting)框架 的代理类。它通过交替进行 思考(Think) 和 行动(Act) 来完成任务。具体来说:
-
思考(Think):分析当前状态并决定是否需要采取行动。 -
行动(Act):执行具体的行动并返回结果。
classReActAgent(BaseAgent, ABC):""" 一个基于 ReAct(思考-行动)框架的代理。 该代理通过交替进行思考(Think)和行动(Act)来完成任务。 它继承自 BaseAgent 并实现了 ReAct 模式的核心逻辑。 """# 代理的核心属性 name: str # 代理的唯一名称 description: Optional[str] = None# 代理的简要描述(可选) system_prompt: Optional[str] = None# 系统级别的提示(可选) next_step_prompt: Optional[str] = None# 用于决定下一步行动的提示(可选) llm: Optional[LLM] = Field(default_factory=LLM) # 语言模型实例 memory: Memory = Field(default_factory=Memory) # 代理的记忆存储 state: AgentState = AgentState.IDLE # 代理的当前状态,默认为 IDLE max_steps: int = 10# 最大执行步骤数 current_step: int = 0# 当前执行步骤 @abstractmethodasyncdefthink(self) -> bool:""" 处理当前状态并决定下一步行动。 返回: bool: 是否需要执行行动(True 表示需要行动,False 表示不需要)。 """pass @abstractmethodasyncdefact(self) -> str:""" 执行已决定的行动。 返回: str: 行动的结果描述。 """passasyncdefstep(self) -> str:""" 执行单一步骤:思考并行动。 返回: str: 步骤执行的结果描述。 """# 调用 think 方法决定是否需要行动 should_act = await self.think()ifnot should_act:return"Thinking complete - no action needed"# 如果不需要行动,返回提示# 如果需要行动,调用 act 方法并返回结果returnawait self.act()
这个类虽然重要,但是也是很多类的子类
swe.py
SWEAgent 是一个专门用于 代码执行和自然对话 的代理类。它基于 ToolCallAgent,具备与计算机直接交互的能力,能够执行 Bash 命令、编辑文本以及终止任务。以下是其核心功能:
代码执行:通过 Bash 工具执行命令。
自然对话:通过 system_prompt 和 next_step_prompt 实现与用户的交互。
任务管理:支持任务终止(通过 Terminate 工具)。
如下所示:
classSWEAgent(ToolCallAgent):""" 一个实现 SWEAgent 范式的代理,用于执行代码和进行自然对话。 该代理是一个自主的 AI 程序员,能够直接与计算机交互以完成任务。 """# 代理的核心属性 name: str = "swe"# 代理的名称 description: str = "an autonomous AI programmer that interacts directly with the computer to solve tasks."# 代理的描述# 提示模板 system_prompt: str = SYSTEM_PROMPT # 系统提示 next_step_prompt: str = NEXT_STEP_TEMPLATE # 下一步行动提示模板# 可用工具集合 available_tools: ToolCollection = ToolCollection( Bash(), StrReplaceEditor(), Terminate() )# 特殊工具名称列表 special_tool_names: List[str] = Field(default_factory=lambda: [Terminate().name])# 最大执行步骤数 max_steps: int = 30# Bash 工具实例 bash: Bash = Field(default_factory=Bash)# 当前工作目录 working_dir: str = "."asyncdefthink(self) -> bool:""" 处理当前状态并决定下一步行动。 返回: bool: 是否需要执行行动(True 表示需要行动,False 表示不需要)。 """# 更新当前工作目录 self.working_dir = await self.bash.execute("pwd")# 格式化下一步行动提示,插入当前目录 self.next_step_prompt = self.next_step_prompt.format( current_dir=self.working_dir )# 调用父类的 think 方法returnawait super().think()
toolcall.py

几个主要函数的功能如下
think
-
作用:处理当前状态并决定下一步行动,使用工具调用。 -
关键逻辑: -
如果存在 next_step_prompt,将其作为用户消息添加到记忆。 -
调用语言模型( llm.ask_tool)获取响应,包括工具调用选项。 -
根据 tool_choices模式(none、auto、required)决定是否使用工具。 -
记录日志并返回是否需要执行行动。
act
-
作用:执行工具调用并处理结果。 -
关键逻辑: -
如果没有工具调用,返回最后一条消息的内容。 -
遍历工具调用列表,逐个执行工具并记录结果。 -
将工具执行结果添加到记忆。 -
返回所有工具执行结果的汇总。
execute_tool
-
作用:执行单个工具调用,并提供健壮的错误处理。 -
关键逻辑: -
检查工具调用是否有效。 -
解析工具调用的参数。 -
调用工具并获取结果。 -
处理特殊工具(如 Terminate)。 -
返回工具执行结果或错误信息。
_handle_special_tool
-
作用:处理特殊工具的执行和状态变更。 -
关键逻辑: -
检查工具是否为特殊工具。 -
如果是特殊工具且满足完成条件,将代理状态设置为 FINISHED。
_should_finish_execution
-
作用:判断工具执行是否应终止代理。 -
关键逻辑: -
默认返回 True,表示工具执行应终止代理。 -
可根据需要被子类重写以实现自定义逻辑。
_is_special_tool
-
作用:检查工具名称是否在特殊工具列表中。 -
关键逻辑: -
比较工具名称与 special_tool_names列表中的名称(忽略大小写)。 -
返回布尔值,表示是否为特殊工具。
流程走通
-
先进入到main.py函数里面执行程序 -
调用.run函数,查看代码结构,发现.run函数在base.py里面的BaseAgent里面

-
run函数调用.step,查看代码,发现.step在react.py里面

好了,搞清楚了,先self.think一下,怎么想,用代码想啊

想的过程就要将工具加进来了
加进来后就采取act,需要act的话,就self.act

需要act的话,就要操作工具了,openmanus提供了很多的工具,


夜雨聆风