前言
2025/3/5 凌晨一点半前后,手机里陆续收到一些公众号推文,Manus,Leave it to Manus,感觉一片喧哗,有点Agent里面的Deepseek类似赶脚,索性去注册了,Sorry,需要邀请码,而闲鱼上的邀请码,被吵到了5位数,洗洗睡吧~
2025/3/6上午 又有传,有团队三小时复刻Manus,What?这是什么节奏,OpenManus 的团队这么拼,这么厉害的吗?于是赶紧去围观,具体见 “
https://github.com/mannaandpoem/OpenManus”
以下是围观过程,请接收:
应用安装
创建新的 conda 环境
conda create -n open_manus python=3.12
conda activate open_manus
克隆仓库
git clone https://github.com/mannaandpoem/OpenManus.git
cd OpenManus
安装依赖
pip install -r requirements.txt
中间过程很丝滑,没有报错。
应用配置
cd config
cp config.example.toml config.toml
vim config.toml 添加 API 密钥和自定义设置:
这里配置openai的模型是不太可能了,
这里有这些方式,
1、本地通过启动Ollama 快速配置一个小模型,不建议,效果不好
2、AutoDL 部署类似有卡的平台(要租)
3、使用 硅基流动 阿里云百炼 注册(模型有的充值、有的免费)
硅基流动参考:
阿里云百炼参考
补充说明
可能有同学问,模型Deepseek R1,
我用了,报这个
为啥呢,因为Deepseek 团队,说过函数调用能力R1不支持,但是可以尝试V3,欢迎有同学尝试
运行(执行 python main.py)
首次试试(报错,缺东西)
首次执行,过程中报错如下:
提示没有 playwriter
直接安装执行 playwriter install 即可
继续试试(分析网页)
内容他爬到了,这个尚可
继续试试(写总结报告)
写啊写啊......
到第30步
我去看了看,貌似生成了,但是打不开,说文件损坏了
好吧,如上就是尝试过程,确实存在一些问题,7号晚上围观了下他们在datawhale的直播,来自MetaGPT团队,小组成员非常年轻,5个人,夜战3小时,值得令人佩服,向他们学习,向他们致敬。
向他们学习,以下是OpenManus的一些源码解析,供学习参考
源码解构详细介绍
OpenManus 是一个强大的 AI 代理系统,它能够执行各种复杂任务,包括代码生成、网络搜索、文件操作和浏览器交互等。下面我将详细介绍 OpenManus 的架构和核心组件,帮助大家更好地理解和使用这个系统。
1. 整体架构
总体来讲,OpenManus 当前的版本,采用多Agent模式+RcAct模式 + Tools
主要 工具如下:
- python_execute.py - Python代码执行工具
- google_search.py - Google搜索工具
- browser_use_tool.py - 浏览器交互工具
- file_saver.py - 文件保存工具
- terminate.py - 终止执行工具
这里有一个进行中的版本,感觉会改为PlanAndSolver(Plan-and-Excute)模型。好有Manus过程中用到了 Anthropic推出了 “computer use” 功能,OpenManus也可能会快速的怼上去。
OpenManus 采用了模块化的设计,主要包含以下几个核心模块:
- Agent 模块:定义了不同类型的代理,负责执行具体任务
- Tool 模块:提供各种工具,供代理调用以完成特定功能
- Flow 模块:协调多个代理的工作,管理复杂任务的执行流程(感觉主要为了扩展PlanAndSolve)
- Prompt 模块:定义了各种提示模板,指导代理的行为
- Schema 模块:定义了系统中的数据结构和通信格式
- LLM 模块:封装了与大型语言模型的交互
整体架构遵循了清晰的层次结构:
应用层 → Flow层 → Agent层 → Tool层 → 外部服务/资源
2. 核心模块详解
2.1 Agent 模块
Agent 是 OpenManus 的核心执行单元,负责理解用户请求并执行相应操作。
2.1.1 BaseAgent
OpenManus/OpenManus/app/agent/base.py
定义了所有代理的基类,提供了状态管理、记忆管理和执行循环等基础功能。主要特性包括:
- 状态管理(IDLE、RUNNING、FINISHED、ERROR)
- 记忆系统(存储对话历史)
- 执行控制(步数限制、当前步骤跟踪)
- 抽象方法 step(),子类必须实现
2.1.2 ToolCallAgent
OpenManus/OpenManus/app/agent/toolcall.py 是一个能够执行工具调用的代理,它扩展了 BaseAgent,添加了工具调用的能力。
2.1.3 Manus
OpenManus/OpenManus/app/agent/manus.py 是系统的主要代理,它继承自 ToolCallAgent,配备了多种工具:
available_tools: ToolCollection = Field(
default_factory=lambda: ToolCollection(
PythonExecute(), GoogleSearch(), BrowserUseTool(), FileSaver(), Terminate()
)
)
这些工具使 Manus 能够执行 Python 代码、进行网络搜索、使用浏览器和保存文件。
2.1.4 其他专业代理
- PlanningAgent:专注于任务规划的代理
- ReActAgent:使用 ReAct 范式的代理
- SWEAgent:专注于软件工程任务的代理
2.2 Tool 模块
Tool 模块提供了各种工具,供代理调用以完成特定功能。
2.2.1 BaseTool
OpenManus/OpenManus/app/tool/base.py 定义了所有工具的基类,提供了工具的基本结构和接口:
class BaseTool(ABC, BaseModel):
name: str
description: str
parameters: Optional[dict] = None
async def execute(self, **kwargs) -> Any:
"""Execute the tool with given parameters."""
2.2.2 主要工具
- PythonExecute:执行 Python 代码
- GoogleSearch:进行网络搜索
- BrowserUseTool:浏览器交互
- FileSaver:保存文件
- Terminate:终止执行
- PlanningTool:创建和管理任务计划
- Bash:执行 bash 命令
2.2.3 ToolCollection
OpenManus/app/tool/tool_collection.py 是工具的集合,提供了统一的接口来管理和执行多个工具:
class ToolCollection:
def __init__(self, *tools: BaseTool):
self.tools = tools
self.tool_map = {tool.name: tool for tool in tools}
async def execute(self, *, name: str, tool_input: Dict[str, Any] = None) -> ToolResult:
tool = self.tool_map.get(name)
if not tool:
return ToolFailure(error=f"Tool {name} is invalid")
try:
result = await tool(**tool_input)
return result
except ToolError as e:
return ToolFailure(error=e.message)
2.3 Flow 模块
Flow 模块负责协调多个代理的工作,管理复杂任务的执行流程。
2.3.1 BaseFlow
/OpenManus/OpenManus/app/flow/base.py 定义了所有流程的基类,提供了管理多个代理的基础功能:
class BaseFlow(BaseModel, ABC):
agents: Dict[str, BaseAgent]
tools: Optional[List] = None
primary_agent_key: Optional[str] = None
@abstractmethod
async def execute(self, input_text: str) -> str:
"""Execute the flow with given input"""
2.3.2 PlanningFlow
/OpenManus/OpenManus/app/flow/planning.py 是一个基于规划的流程,它能够将复杂任务分解为多个步骤,并为每个步骤选择合适的执行者:
class PlanningFlow(BaseFlow):
llm: LLM = Field(default_factory=lambda: LLM())
planning_tool: PlanningTool = Field(default_factory=PlanningTool)
executor_keys: List[str] = Field(default_factory=list)
active_plan_id: str = Field(default_factory=lambda: f"plan_{int(time.time())}")
current_step_index: Optional[int] = None
PlanningFlow 的执行流程:
- 创建初始计划
- 循环执行计划中的步骤
- 为每个步骤选择合适的代理
- 执行步骤并更新状态
- 完成计划并生成总结
2.3.3 FlowFactory
/OpenManus/app/flow/flow_factory.py 是一个工厂类,用于创建不同类型的流程:
class FlowFactory:
@staticmethod
def create_flow(
flow_type: FlowType,
agents: Union[BaseAgent, List[BaseAgent], Dict[str, BaseAgent]],
**kwargs,
) -> BaseFlow:
flows = {
FlowType.PLANNING: PlanningFlow,
}
flow_class = flows.get(flow_type)
if not flow_class:
raise ValueError(f"Unknown flow type: {flow_type}")
return flow_class(agents, **kwargs)
2.4 Prompt 模块
Prompt 模块定义了各种提示模板,指导代理的行为。
2.4.1 manus.py
/OpenManus/app/prompt/manus.py 定义了 Manus 代理的提示模板:
- SYSTEM_PROMPT:定义了 Manus 的身份和能力
- NEXT_STEP_PROMPT:详细描述了可用的工具和使用策略
2.4.2 planning.py
/OpenManus/app/prompt/planning.py 定义了规划代理的提示模板:
- PLANNING_SYSTEM_PROMPT:定义了规划代理的身份和工作流程
- NEXT_STEP_PROMPT:引导代理思考下一步行动
2.5 Schema 模块
/OpenManus/app/schema.py 定义了系统中的数据结构和通信格式。
2.5.1 主要数据结构
- AgentState:代理的状态枚举
- Function:函数信息
- ToolCall:工具调用
- Message:对话消息
- Memory:对话历史记忆
2.5.2 Message 类
Message 类是系统中最核心的消息模型,表示对话中的一条消息:
class Message(BaseModel):
role: Literal["system", "user", "assistant", "tool"]
content: Optional[str] = None
tool_calls: Optional[List[ToolCall]] = None
name: Optional[str] = None
tool_call_id: Optional[str] = None
Message 类提供了多种便捷方法:
- user_message():创建用户消息
- system_message():创建系统消息
- assistant_message():创建助手消息
- tool_message():创建工具消息
- from_tool_calls():从工具调用创建消息
2.6 LLM 模块
/OpenManus/app/llm.py 封装了与大型语言模型的交互。
class LLM:
def __init__(
self, config_name: str = "default", llm_config: Optional[LLMSettings] = None
):
if not hasattr(self, "client"):
llm_config = llm_config or config.llm
llm_config = llm_config.get(config_name, llm_config["default"])
self.model = llm_config.model
self.max_tokens = llm_config.max_tokens
self.temperature = llm_config.temperature
self.client = AsyncOpenAI(
api_key=llm_config.api_key, base_url=llm_config.base_url
)
LLM 类提供了多种方法与语言模型交互:
- ask():发送消息并获取回复
- ask_tool():发送消息并获取工具调用
- stream():流式获取回复
3. 执行流程
3.1 单代理执行流程
- 用户发送请求
- 代理接收请求并添加到记忆中
- 代理执行循环:
- 调用 LLM 生成响应或工具调用
- 如果是工具调用,执行工具并将结果添加到记忆中
- 如果是普通响应,将其添加到记忆中并返回
- 返回最终结果
3.2 多代理协作流程(通过 Flow)
- 用户发送请求
- Flow 接收请求并创建初始计划
- Flow 执行循环:
- 获取当前未完成的步骤
- 根据步骤类型选择合适的代理
- 让选定的代理执行该步骤
- 标记步骤为已完成
- 所有步骤完成后,生成总结并返回
4. 系统特点
4.1 模块化设计
OpenManus 采用了高度模块化的设计,各个组件之间职责明确,耦合度低,便于扩展和维护。
4.2 多代理协作
通过 Flow 模块,OpenManus 支持多个代理协同工作,每个代理可以有不同的专长和职责。
4.3 丰富的工具集
OpenManus 提供了丰富的工具集,包括 Python 执行、网络搜索、浏览器交互、文件操作等,使代理能够完成各种复杂任务。
4.4 灵活的提示系统
通过不同的提示模板,OpenManus 可以指导代理的行为,适应不同的任务需求。
4.5 状态管理
OpenManus 提供了完善的状态管理机制,能够跟踪代理的执行状态和任务进度。
5. 使用示例
5.1 使用单个代理
from app.agent.manus import Manus
# 创建 Manus 代理
agent = Manus()
# 执行任务
result = await agent.run("创建一个简单的网页爬虫")
print(result)
5.2 使用多代理协作
from app.agent.manus import Manus
from app.agent.swe import SWEAgent
from app.flow.base import FlowType
from app.flow.flow_factory import FlowFactory
# 创建多个代理
manus_agent = Manus()
swe_agent = SWEAgent()
# 创建 PlanningFlow
flow = FlowFactory.create_flow(
FlowType.PLANNING,
{
"general": manus_agent,
"code": swe_agent
}
)
# 执行任务
result = await flow.execute("创建一个分析网页数据的 Python 脚本")
print(result)
6. 总结一下
虽然Manus具体实现细节我们还不清楚,但是OpenManus的实现给我们提供了很多思路,
通过模块化设计、多代理协作和丰富的工具集,能够完成各种复杂任务?长尾任务。
感觉这个框架的有这些优势:
- 灵活的代理系统:不同类型的代理适用于不同类型的任务
- 强大的工具集:丰富的工具扩展了系统的能力范围
- 智能的规划能力:能够将复杂任务分解为可管理的步骤
- 健壮的错误处理:多层异常捕获和降级策略确保系统稳定性
- 高度可扩展性:易于添加新工具、新代理和新流程
当然整体还在构建中,还不成熟,不过通过深入理解 OpenManus 的架构和工作原理,我们作为开发者可以更好地利用和扩展这个系统,创建更强大的 Agent应用。