Explication de l'Open Source OpenManus, avec un aperçu de l'architecture de l'agent d'intelligence artificielle qui le sous-tend
Ouverture : L'incendie de Manus et la panne d'OpenManus
L'une des grandes nouveautés dans le domaine de l'IA ces derniers temps est que le système de gestion de l'information de l'Union européenne est en train de se transformer en un système de gestion de l'information. Manus Manus, l'agent d'intelligence artificielle, a attiré beaucoup d'attention grâce à ses fonctions puissantes et à sa souplesse d'utilisation. En bref, Manus est un assistant polyvalent qui peut vous aider à programmer, à rechercher des informations, à traiter des documents ou à naviguer sur l'internet.
Cependant, il n'est pas si facile d'utiliser Manus, vous devez avoir un code d'invitation. Cela a empêché de nombreux développeurs et chercheurs d'utiliser Manus. L'équipe MetaGPT composée de @mannaandpoem, @XiangJinyu, @MoshiQAQ, et @didiforgithub a passé seulement 3 heures à mettre au point un projet open source appelé OpenManus. Vous pouvez désormais découvrir la puissance de Manus sans code d'invitation ! Ce qui est encore plus excitant, c'est qu'OpenManus est un projet open source, ce qui signifie que vous pouvez le modifier et l'étendre pour qu'il réponde à vos besoins !

L'émergence d'OpenManus permet non seulement à un plus grand nombre de personnes de découvrir le charme de l'agent d'intelligence artificielle, mais insuffle également une nouvelle vitalité au développement de l'agent d'intelligence artificielle. Pour ceux d'entre nous qui sont impliqués dans la technologie, OpenManus n'est pas seulement un bon outil, mais aussi une excellente ressource d'apprentissage. En étudiant son code, nous pouvons mieux comprendre la conception du cadre et les détails de la mise en œuvre de l'agent d'intelligence artificielle.
Cadre pour les agents d'intelligence artificielle : philosophie de conception d'OpenManus
La structure du code d'OpenManus est très claire et adopte une conception modulaire, qui s'apparente à des blocs de construction permettant de combiner différents modules fonctionnels. L'avantage de cette conception est que le code est hautement réutilisable et extensible, et que les responsabilités de chaque module sont claires.
Les principaux composants d'OpenManus sont les suivants :
OpenManus
├── Agent (代理层)
│ ├── BaseAgent (基础抽象类)
│ ├── ReActAgent (思考-行动模式)
│ ├── ToolCallAgent (工具调用能力)
│ ├── PlanningAgent (规划能力)
│ ├── SWEAgent (软件工程能力)
│ └── Manus (通用代理)
├── LLM (语言模型层)
├── Memory (记忆层)
├── Tool (工具层)
│ ├── BaseTool (工具基类)
│ ├── PlanningTool (规划工具)
│ ├── PythonExecute (Python 执行)
│ ├── GoogleSearch (搜索工具)
│ ├── BrowserUseTool (浏览器工具)
│ └── ... (其他工具)
├── Flow (工作流层)
│ ├── BaseFlow (基础流程)
│ └── PlanningFlow (规划流程)
└── Prompt (提示词层)
Composantes du LLM : le cerveau de l'agent
Si nous comparons un agent à une personne, le LLM (Large Language Model) est le cerveau de l'agent, qui est chargé de comprendre les commandes de l'utilisateur, de générer des réponses et de prendre des décisions. OpenManus encapsule l'interaction avec le LLM à travers la classe LLM.
class LLM:
_instances: Dict[str, "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
)
La classe LLM propose deux méthodes principales :
ask
: : Envoi de demandes de dialogue généralask_tool
: : Envoyer des requêtes avec des appels d'outils
async def ask_tool(
self,
messages: List[Union[dict, Message]],
system_msgs: Optional[List[Union[dict, Message]]] = None,
timeout: int = 60,
tools: Optional[List[dict]] = None,
tool_choice: Literal["none", "auto", "required"] = "auto",
temperature: Optional[float] = None,
**kwargs,
):
# 格式化消息
if system_msgs:
system_msgs = self.format_messages(system_msgs)
messages = system_msgs + self.format_messages(messages)
else:
messages = self.format_messages(messages)
# 发送请求
response = await self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=temperature or self.temperature,
max_tokens=self.max_tokens,
tools=tools,
tool_choice=tool_choice,
timeout=timeout,
**kwargs,
)
Composante mémoire : mémoire de l'agent
Le composant Mémoire est comme un carnet de notes pour l'agent, responsable de l'enregistrement et de la gestion de l'historique du dialogue de l'agent. Grâce à la mémoire, l'agent peut se souvenir de ce qu'il a dit auparavant et maintenir la cohérence du dialogue.
class Memory(BaseModel):
"""Stores and manages agent's conversation history."""
messages: List[Message] = Field(default_factory=list)
def add_message(self, message: Union[Message, dict]) -> None:
"""Add a message to memory."""
if isinstance(message, dict):
message = Message(**message)
self.messages.append(message)
def get_messages(self) -> List[Message]:
"""Get all messages in memory."""
return self.messages
Le composant Mémoire est le composant central de l'agent, et il est accessible par le biais de la fonction update_memory
pour ajouter un nouveau message :
def update_memory(
self,
role: Literal["user", "system", "assistant", "tool"],
content: str,
**kwargs,
) -> None:
"""Add a message to the agent's memory."""
message_map = {
"user": Message.user_message,
"system": Message.system_message,
"assistant": Message.assistant_message,
"tool": lambda content, **kw: Message.tool_message(content, **kw),
}
if role not in message_map:
raise ValueError(f"Unsupported message role: {role}")
msg_factory = message_map[role]
msg = msg_factory(content, **kwargs) if role == "tool" else msg_factory(content)
self.memory.add_message(msg)
Composante outils : boîte à outils de l'agent
Le composant Outils est le pont entre l'agent et le monde extérieur, et OpenManus met en œuvre un système d'outils flexible qui permet à l'agent d'invoquer une variété d'outils pour accomplir des tâches.
class BaseTool(ABC, BaseModel):
name: str
description: str
parameters: Optional[dict] = None
async def __call__(self, **kwargs) -> Any:
"""Execute the tool with given parameters."""
return await self.execute(**kwargs)
@abstractmethod
async def execute(self, **kwargs) -> Any:
"""Execute the tool with given parameters."""
def to_param(self) -> Dict:
"""Convert tool to function call format."""
return {
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.parameters,
},
}
Les résultats de l'exécution de l'outil sont représentés par les éléments suivants ToolResult
pour la représenter :
class ToolResult(BaseModel):
"""Represents the result of a tool execution."""
output: Any = Field(default=None)
error: Optional[str] = Field(default=None)
system: Optional[str] = Field(default=None)
OpenManus fournit un certain nombre d'outils intégrés tels que PlanningTool
: :
class PlanningTool(BaseTool):
"""
A planning tool that allows the agent to create and manage plans for solving complex tasks.
The tool provides functionality for creating plans, updating plan steps, and tracking progress.
"""
name: str = "planning"
description: str = _PLANNING_TOOL_DESCRIPTION
parameters: dict = {
"type": "object",
"properties": {
"command": {
"description": "The command to execute. Available commands: create, update, list, get, set_active, mark_step, delete.",
"enum": [
"create",
"update",
"list",
"get",
"set_active",
"mark_step",
"delete",
],
"type": "string",
},
# 其他参数...
},
"required": ["command"],
}
Composante de planification : capacités de planification de l'agent
Le composant Planification est la clé de la capacité d'OpenManus à gérer des tâches complexes. Il permet aux agents de planifier et de décomposer les tâches complexes en petites tâches étape par étape, puis de les réaliser une par une.
Le volet Planification se compose de deux parties principales :
PlanningTool
Le système d'information sur la gestion des ressources humaines : Il permet de créer, de mettre à jour et de suivre les plans.PlanningAgent
: UtilisationPlanningTool
pour effectuer la planification et l'exécution des tâches.
class PlanningAgent(ToolCallAgent):
"""
An agent that creates and manages plans to solve tasks.
This agent uses a planning tool to create and manage structured plans,
and tracks progress through individual steps until task completion.
"""
name: str = "planning"
description: str = "An agent that creates and manages plans to solve tasks"
system_prompt: str = PLANNING_SYSTEM_PROMPT
next_step_prompt: str = NEXT_STEP_PROMPT
available_tools: ToolCollection = Field(
default_factory=lambda: ToolCollection(PlanningTool(), Terminate())
)
# 步骤执行跟踪器
step_execution_tracker: Dict[str, Dict] = Field(default_factory=dict)
current_step_index: Optional[int] = None
PlanningAgent
La méthodologie de base comprend
async def think(self) -> bool:
"""Decide the next action based on plan status."""
prompt = (
f"CURRENT PLAN STATUS:n{await self.get_plan()}nn{self.next_step_prompt}"
if self.active_plan_id
else self.next_step_prompt
)
self.messages.append(Message.user_message(prompt))
# 获取当前步骤索引
self.current_step_index = await self._get_current_step_index()
result = await super().think()
# 关联工具调用与当前步骤
if result and self.tool_calls:
# ...关联逻辑...
return result
Élément de flux : capacités de collaboration pour les agents
Le rôle de la composante "flux" est de coordonner plusieurs agents travaillant ensemble pour accomplir des tâches plus complexes.
class BaseFlow(BaseModel, ABC):
"""Base class for execution flows supporting multiple agents"""
agents: Dict[str, BaseAgent]
tools: Optional[List] = None
primary_agent_key: Optional[str] = None
@property
def primary_agent(self) -> Optional[BaseAgent]:
"""Get the primary agent for the flow"""
return self.agents.get(self.primary_agent_key)
@abstractmethod
async def execute(self, input_text: str) -> str:
"""Execute the flow with given input"""
PlanningFlow
est une implémentation concrète de Flow pour la planification et l'exécution des tâches :
class PlanningFlow(BaseFlow):
"""A flow that manages planning and execution of tasks using agents."""
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
async def execute(self, input_text: str) -> str:
"""Execute the planning flow with agents."""
try:
# 创建初始计划
if input_text:
await self._create_initial_plan(input_text)
# 执行计划步骤
while await self._has_next_step():
# 获取当前步骤
step_info = await self._get_current_step()
# 选择合适的执行者
executor = self.get_executor(step_info.get("type"))
# 执行步骤
result = await self._execute_step(executor, step_info)
# 更新步骤状态
await self._update_step_status(step_info["index"], "completed")
# 完成计划
return await self._finalize_plan()
except Exception as e:
# 处理异常
return f"Error executing flow: {str(e)}"
Mise en œuvre de l'agent OpenManus : une architecture en couches
L'agent OpenManus utilise une architecture hiérarchique, construite couche par couche, de la fonctionnalité de base aux applications spécialisées. Les avantages de cette conception sont une grande réutilisation du code, une grande évolutivité et des responsabilités claires à chaque niveau.
BaseAgent (抽象基类)
└── ReActAgent (思考-行动模式)
└── ToolCallAgent (工具调用能力)
├── PlanningAgent (规划能力)
├── SWEAgent (软件工程能力)
└── Manus (通用代理)
BaseAgent : la base des bases
BaseAgent
est le fondement de l'ensemble du cadre et définit les propriétés et les méthodes essentielles d'un agent :
class BaseAgent(BaseModel, ABC):
"""Abstract base class for managing agent state and execution."""
# 核心属性
name: str = Field(..., description="Unique name of the agent")
description: Optional[str] = Field(None, description="Optional agent description")
# 提示词
system_prompt: Optional[str] = Field(None, description="System-level instruction prompt")
next_step_prompt: Optional[str] = Field(None, description="Prompt for determining next action")
# 依赖组件
llm: LLM = Field(default_factory=LLM, description="Language model instance")
memory: Memory = Field(default_factory=Memory, description="Agent's memory store")
state: AgentState = Field(default=AgentState.IDLE, description="Current agent state")
# 执行控制
max_steps: int = Field(default=10, description="Maximum steps before termination")
current_step: int = Field(default=0, description="Current step in execution")
ReActAgent : l'agent pensant
ReActAgent
Un modèle "penser-agir" a été réalisé, divisant le processus d'exécution de l'agent en deux phases :
class ReActAgent(BaseAgent, ABC):
@abstractmethod
async def think(self) -> bool:
"""Process current state and decide next action"""
@abstractmethod
async def act(self) -> str:
"""Execute decided actions"""
async def step(self) -> str:
"""Execute a single step: think and act."""
should_act = await self.think()
if not should_act:
return "Thinking complete - no action needed"
return await self.act()
ToolCallAgent : Agent capable d'utiliser un outil
ToolCallAgent
Ajoute la capacité d'utiliser des outils à l'agent :
class ToolCallAgent(ReActAgent):
"""Base agent class for handling tool/function calls with enhanced abstraction"""
available_tools: ToolCollection = ToolCollection(
CreateChatCompletion(), Terminate()
)
tool_choices: Literal["none", "auto", "required"] = "auto"
async def think(self) -> bool:
# 获取 LLM 响应和工具选择
response = await self.llm.ask_tool(
messages=self.messages,
system_msgs=[Message.system_message(self.system_prompt)]
if self.system_prompt
else None,
tools=self.available_tools.to_params(),
tool_choice=self.tool_choices,
)
self.tool_calls = response.tool_calls
# 处理响应和工具调用
# ...
async def act(self) -> str:
# 执行工具调用
results = []
for command in self.tool_calls:
result = await self.execute_tool(command)
# 添加工具响应到内存
# ...
results.append(result)
return "nn".join(results)
PlanningAgent : Agent qui planifie.
PlanningAgent
La planification des tâches et le suivi de l'exécution ont été réalisés :
class PlanningAgent(ToolCallAgent):
"""
An agent that creates and manages plans to solve tasks.
This agent uses a planning tool to create and manage structured plans,
and tracks progress through individual steps until task completion.
"""
# 步骤执行跟踪器
step_execution_tracker: Dict[str, Dict] = Field(default_factory=dict)
current_step_index: Optional[int] = None
async def think(self) -> bool:
"""Decide the next action based on plan status."""
prompt = (
f"CURRENT PLAN STATUS:n{await self.get_plan()}nn{self.next_step_prompt}"
if self.active_plan_id
else self.next_step_prompt
)
self.messages.append(Message.user_message(prompt))
# 获取当前步骤索引
self.current_step_index = await self._get_current_step_index()
result = await super().think()
# 关联工具调用与当前步骤
if result and self.tool_calls:
# ...关联逻辑...
return result
Manus : Agent omnipotent
Manus
est l'agent principal d'OpenManus, qui intègre des outils et des capacités permettant de gérer une grande variété de tâches :
class Manus(ToolCallAgent):
"""
A versatile general-purpose agent that uses planning to solve various tasks.
This agent extends PlanningAgent with a comprehensive set of tools and capabilities,
including Python execution, web browsing, file operations, and information retrieval
to handle a wide range of user requests.
"""
name: str = "manus"
description: str = "A versatile general-purpose agent"
system_prompt: str = SYSTEM_PROMPT
next_step_prompt: str = NEXT_STEP_PROMPT
available_tools: ToolCollection = Field(
default_factory=lambda: ToolCollection(
PythonExecute(), GoogleSearch(), BrowserUseTool(), FileSaver(), Terminate()
)
)
Invitation : Lignes directrices sur le comportement des agents
L'invite joue un rôle essentiel dans la construction d'un système d'agents, en agissant comme un manuel d'instructions qui indique à l'agent ce qu'il doit faire.
System Prompt : Définir le rôle d'un agent
L'invite système définit les rôles de base et les règles de comportement des agents :
SYSTEM_PROMPT = "You are OpenManus, an all-capable AI assistant, aimed at solving any task presented by the user. You have various tools at your disposal that you can call upon to efficiently complete complex requests. Whether it's programming, information retrieval, file processing, or web browsing, you can handle it all."
L'invite indique à l'agent qu'il s'agit d'un assistant IA polyvalent qui peut utiliser toute une série d'outils pour répondre à la demande de l'utilisateur.
Invitation à la planification : guide l'agent dans la planification
L'invite de planification indique à l'agent comment décomposer des tâches complexes en tâches plus petites assorties d'un plan d'exécution :
PLANNING_SYSTEM_PROMPT = """
You are an expert Planning Agent tasked with solving complex problems by creating and managing structured plans.
Your job is:
1. Analyze requests to understand the task scope
2. Create clear, actionable plans with the `planning` tool
3. Execute steps using available tools as needed
4. Track progress and adapt plans dynamically
5. Use `finish` to conclude when the task is complete
Available tools will vary by task but may include:
- `planning`: Create, update, and track plans (commands: create, update, mark_step, etc.)
- `finish`: End the task when complete
Break tasks into logical, sequential steps. Think about dependencies and verification methods.
"""
Cette invite indique à l'agent qu'il est un expert en planification et qu'il doit utiliser l'outil de planification. planning
des outils pour créer, mettre à jour et suivre les plans.
Invite à l'utilisation de l'outil : indique à l'agent comment utiliser l'outil.
L'invite d'utilisation de l'outil décrit en détail les fonctions et les scénarios d'utilisation de chaque outil afin d'aider l'agent à choisir le bon outil :
NEXT_STEP_PROMPT = """You can interact with the computer using PythonExecute, save important content and information files through FileSaver, open browsers with BrowserUseTool, and retrieve information using GoogleSearch.
PythonExecute: Execute Python code to interact with the computer system, data processing, automation tasks, etc.
FileSaver: Save files locally, such as txt, py, html, etc.
BrowserUseTool: Open, browse, and use web browsers.If you open a local HTML file, you must provide the absolute path to the file.
GoogleSearch: Perform web information retrieval
Based on user needs, proactively select the most appropriate tool or combination of tools. For complex tasks, you can break down the problem and use different tools step by step to solve it. After using each tool, clearly explain the execution results and suggest the next steps.
"""
Dynamic Prompt : Rendre les agents plus flexibles
Dans OpenManus, les invites peuvent être non seulement statiques, mais aussi générées de manière dynamique. Par exemple, dans la fenêtre PlanningAgent
dans l'invite, le système ajoute l'état actuel du plan à l'invite :
async def think(self) -> bool:
"""Decide the next action based on plan status."""
prompt = (
f"CURRENT PLAN STATUS:n{await self.get_plan()}nn{self.next_step_prompt}"
if self.active_plan_id
else self.next_step_prompt
)
self.messages.append(Message.user_message(prompt))
Cette invite dynamique permet à l'agent de prendre des décisions plus rationnelles en fonction de la situation actuelle.
Synthèse : Aperçu d'OpenManus
En analysant le code d'OpenManus, nous pouvons résumer plusieurs éléments clés du cadre de l'agent d'intelligence artificielle :
- AgentLes compétences : conception hiérarchique de la base au professionnel pour atteindre différents niveaux de compétence.
BaseAgent
Le système de gestion des états et des boucles d'exécution est un élément de base de la gestion des états.ReActAgent
Le modèle de l'acte de penser : Réalisation du modèle de l'acte de penser.ToolCallAgent
Ajouter des capacités d'appel d'outils.- Agent professionnel : par exemple
PlanningAgent
,SWEAgent
répondre en chantantManus
.
- LLMLes modèles linguistiques : Encapsuler l'interaction avec de grands modèles linguistiques, en fournissant des capacités de dialogue et d'invocation d'outils.
- Prise en charge du dialogue normal et des appels d'outils.
- Mettre en œuvre un mécanisme de relance et de traitement des erreurs.
- La réponse en continu est prise en charge.
- MémoireLes questions relatives à la gestion de l'histoire et du contexte du dialogue : Gérer l'histoire et le contexte du dialogue.
- Stocker et récupérer des messages.
- Maintenir le contexte du dialogue.
- OutilLes services d'information et de communication : ils fournissent une interface permettant d'interagir avec le monde extérieur.
- Abstraction de l'outil de base.
- Plusieurs outils spécialisés pour y parvenir.
- Traitement des résultats des outils.
- PlanificationLes services d'aide à la décision : Permettre la planification des tâches et le suivi de l'exécution des tâches.
- Création et gestion de plans.
- Suivi de l'état d'avancement des étapes.
- Programmes d'ajustement dynamique.
- DébitLes agents : Gérer la collaboration entre plusieurs agents.
- Tasking.
- Intégration des résultats.
- Contrôle des processus.
- PromptIl oriente le comportement et la prise de décision de l'agent.
- L'invite système définit le rôle.
- L'incitation professionnelle guide les décisions.
- Génération dynamique d'invites.
Avec sa conception claire et son code bien structuré, OpenManus est un excellent exemple pour l'apprentissage des implémentations d'agents d'intelligence artificielle. Sa conception modulaire permet aux développeurs d'étendre et de personnaliser facilement leurs agents.
OpenManus constitue un bon point de départ pour les développeurs qui souhaitent en savoir plus sur les agents d'intelligence artificielle ou créer leurs propres systèmes d'agents. En découvrant son architecture et sa mise en œuvre, nous pouvons mieux comprendre comment les agents d'intelligence artificielle fonctionnent et comment ils sont conçus.
© déclaration de droits d'auteur
Article copyright Cercle de partage de l'IA Tous, prière de ne pas reproduire sans autorisation.
Articles connexes
Pas de commentaires...