Abertura: O incêndio em Manus e o colapso do OpenManus
Uma das grandes coisas que têm acontecido nos círculos de IA ultimamente é que a Manus Manus, o agente de IA, atraiu muita atenção com suas funções avançadas e uso flexível. Simplificando, o Manus é como um assistente completo, seja para programar, procurar informações, processar documentos ou navegar na Internet, ele pode ajudá-lo a fazer tudo.
No entanto, não é tão fácil usar o Manus, você precisa ter um código de convite. Isso impediu muitos desenvolvedores e pesquisadores de usar o Manus. A equipe do MetaGPT formada por @mannaandpoem, @XiangJinyu, @MoshiQAQ e @didiforgithub gastou apenas 3 horas para criar um projeto de código aberto chamado OpenManus. Agora você pode experimentar o poder da Manus sem precisar de um código de convite! O que é ainda mais interessante é que o OpenManus é um projeto de código aberto, o que significa que você pode modificá-lo e estendê-lo para atender às suas necessidades!
O surgimento do OpenManus não só dá a mais pessoas a oportunidade de experimentar o charme do AI Agent, mas também injeta nova vitalidade no desenvolvimento do AI Agent. Para nós que estamos envolvidos com tecnologia, o OpenManus não é apenas uma boa ferramenta, mas também um excelente recurso de aprendizado. Ao estudar seu código, podemos obter uma compreensão mais profunda do design da estrutura e dos detalhes de implementação do AI Agent.
Estrutura do agente de IA: filosofia de design do OpenManus
A estrutura de código do OpenManus é muito clara e adota um design modular, que é como blocos de construção para combinar diferentes módulos funcionais. A vantagem desse design é que o código é altamente reutilizável e extensível, e as responsabilidades de cada módulo são claras.
Os componentes principais do OpenManus incluem:
OpenManus
Agente (camada de agente)
│ ├── BaseAgent (classe abstrata de base)
│ ├─── ReActAgent (modo pensar-agir)
│ ├── ToolCallAgent (capacidade de chamada de ferramenta)
│ ├─── PlanningAgent (Capacidade de planejamento)
│ ├─── SWEAgent (Capacidade de engenharia de software)
│ └─ Manus (agente genérico)
LLM (camada de modelagem de linguagem) │ ├─── Memória (camada de modelo de linguagem)
├─ Memória (camada de memória)
Ferramenta (camada de ferramenta)
│ ├── BaseTool (classe base da ferramenta)
│ ├─ PlanningTool (Ferramenta de planejamento)
│ ├── PythonExecute (execução de Python)
│ ├─── GoogleSearch (ferramenta de pesquisa)
│ ├─── BrowserUseTool (ferramenta de navegador)
│ └── ... (Outras ferramentas)
├─ Fluxo (camada de fluxo de trabalho) │ ├─ BaseFlow
│ ├── BaseFlow (Fluxo de base)
│ └─ PlanningFlow (Fluxo de planejamento)
Prompt (camada da palavra Prompt) │ └─ Prompt (camada da palavra Prompt)
Componentes do LLM: O cérebro do agente
Se compararmos um agente a uma pessoa, então o LLM (Large Language Model) é o cérebro do agente, responsável por entender os comandos do usuário, gerar respostas e tomar decisões. O OpenManus encapsula a interação com o LLM por meio da classe LLM.
class LLM.
_instances: Dict[str, "LLM"] = {} Implementação do padrão Singleton do #
def __init__(
self, config_name: str = "default", llm_config: Optional[LLMSettings] = None
).
if not hasattr(self, "client"): # inicializa apenas uma vez
llm_config = llm_config ou 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
)
A classe LLM oferece dois métodos principais:
perguntar
:: Envio de solicitações gerais de diálogoask_tool
:: Enviar solicitações com chamadas de ferramentas
async def ask_tool(
self,
messages: List[Union[dict, Message]], system_msgs: Optional[List[Union[dict, Message]]] = None, async
system_msgs: Optional[List[Union[dict, Message]]] = None, timeout: int = 60, async ask_tool(
system_msgs: Optional[List[List[Union[dict, Message]]] = None, timeout: int = 60,
tool_choice: Literal["none", "auto", "required"] = "auto", temperature: Optional[float] = None
temperatura: Optional[float] = None,
**kwargs.
).
# Mensagem de formatação
if system_msgs.
system_msgs = self.format_messages(system_msgs)
messages = system_msgs + self.format_messages(messages)
messages = self.format_messages(system_msgs)
messages = self.format_messages(messages)
# Enviar a solicitação
response = await self.client.chat.completions.create(
model=self.model,
messages=messages, temperature=temperature, ou self.chat.completions.create(
temperature=temperature ou self.temperature, max_tokens=self.temperature, max_tokens=self.temperature
max_tokens=self.max_tokens, tools=tools,
max_tokens=self.max_tokens, tools=tools, tool_choice=tool_choice
tool_choice=tool_choice,
timeout=timeout, **kwargs, **kwargs, **kwargs
**kwargs.
)
Componente de memória: memória do agente
O componente Memória é como um caderno para o Agente, responsável por registrar e gerenciar o histórico de diálogo do Agente. Com a Memória, o Agente pode se lembrar do que disse antes e manter a consistência do diálogo.
class Memory(BaseModel).
"""Armazena e gerencia o histórico de conversas do agente.""""
messages: List[Message] = Field(default_factory=list)
def add_message(self, message: Union[Message, dict]) -> None.
"""Adicionar uma mensagem à memória.""""
if isinstance(message, dict).
message = Message(**message)
self.messages.append(message)
def get_messages(self) -> List[Message].
"""Obter todas as mensagens na memória.""""
return self.messages
O componente de memória é o componente principal do agente e é acessado por meio do componente update_memory
para adicionar uma nova mensagem:
def update_memory(
self.
role: Literal["user", "system", "assistant", "tool"],
content: str, **kwargs, **kwargs, **kwargs
**kwargs.
) -> Nenhum.
"""Adicionar uma mensagem à memória do agente."""""
message_map = {
"user": Message.user_message, """Adicionar uma mensagem à memória do agente.""
"system": Message.system_message, "assistant": Message.
"assistente": Message.assistant_message, "ferramenta": lambda content, message_map
"tool": lambda content, **kw: Message.tool_message(content, **kw),
}
if role not in message_map.
raise ValueError(f "Função de mensagem não suportada: {role}")
msg_factory = message_map[role]
msg = msg_factory(content, **kwargs) if role == "tool" else msg_factory(content)
self.memory.add_message(msg)
Componente de ferramentas: caixa de ferramentas do agente
O componente Ferramentas é a ponte entre o Agente e o mundo externo, e o OpenManus implementa um sistema de ferramentas flexível que permite que o Agente invoque uma variedade de ferramentas para realizar tarefas.
class BaseTool(ABC, BaseModel).
nome: str
descrição: str
parâmetros: Optional[dict] = None
async def __call__(self, **kwargs) -> Any.
"""Executar a ferramenta com os parâmetros fornecidos."""""
return await self.execute(**kwargs)
@abstractmethod
async def execute(self, **kwargs) -> Any.
"""Execute a ferramenta com os parâmetros fornecidos."""""
def to_param(self) -> Dict.
"""Converte a ferramenta para o formato de chamada de função.""""
return {
"function": {
"name": self.name, "description": self.description, "function": {
"description": self.description, "parameters": self.
"parameters": self.parameters, }, return { "type": "function": { "name": self.name, "description": self.description, "parameters": self.
}, }
}
Os resultados da execução da ferramenta são representados pelo Resultado da ferramenta
para representá-la:
class ToolResult(BaseModel).
"""Representa o resultado da execução de uma ferramenta.""""
output: Any = Field(default=None)
error: Optional[str] = Field(default=None)
sistema: Optional[str] = Field(default=None)
O OpenManus fornece várias ferramentas integradas, como Ferramenta de planejamento
::
classe PlanningTool(BaseTool).
"""
Uma ferramenta de planejamento que permite que o agente crie e gerencie planos para resolver tarefas complexas.
A ferramenta oferece funcionalidade para criar planos, atualizar etapas do plano e acompanhar o progresso.
"""
nome: str = "planejamento"
descrição: str = _PLANNING_TOOL_DESCRIPTION
parâmetros: dict = {
"type": "object", "properties": {
"properties": {
"comando": {
"description": "O comando a ser executado. Comandos disponíveis: create, update, list, get, set_active, mark_step, delete.",
"enum": [
"create",
"create", "update",
"list", "get", "set_active", delete.
"get", "set_active", "set_step", "list", "get".
"delete".
], "type" (tipo).
"type": "string", },, "type".
}, .
# Outros parâmetros...
},, "required".
"required": ["command"], }, # Outros parâmetros...
}
Componente de planejamento: recursos de planejamento do agente
O componente Planejamento é a chave para a capacidade do OpenManus de lidar com tarefas complexas. Ele permite que os agentes planejem e dividam tarefas complexas em pequenas tarefas passo a passo e, em seguida, concluam-nas uma a uma.
O componente Planejamento consiste em duas partes principais:
Ferramenta de planejamento
Criação de planos: fornece recursos de criação, atualização e rastreamento de planos.PlanningAgent
: UsoFerramenta de planejamento
para realizar o planejamento e a execução de tarefas.
classe PlanningAgent(ToolCallAgent).
"""
Um agente que cria e gerencia planos para resolver tarefas.
Esse agente usa uma ferramenta de planejamento para criar e gerenciar planos estruturados e acompanha o progresso por meio de etapas individuais até a conclusão da tarefa.
Esse agente usa uma ferramenta de planejamento para criar e gerenciar planos estruturados e acompanha o progresso por meio de etapas individuais até a conclusão da tarefa.
"""
name: str = "planning" (nome: str = "planejamento")
name: str = "planning" description: str = "Um agente que cria e gerencia planos para resolver tarefas"
system_prompt: str = PLANNING_SYSTEM_PROMPT
next_step_prompt: str = NEXT_STEP_PROMPT
available_tools: ToolCollection = Field(
default_factory=lambda: ToolCollection(PlanningTool(), Terminate())
)
Rastreador de execução de etapas #
step_execution_tracker: Dict[str, Dict] = Field(default_factory=dict)
current_step_index: Optional[int] = None
PlanningAgent
A metodologia principal inclui:
async def think(self) -> bool.
"""Decidir a próxima ação com base no status do plano."""""
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))
# Obter o índice da etapa atual
self.current_step_index = await self._get_current_step_index()
result = await super().think()
# Associar uma chamada de ferramenta à etapa atual
if result and self.tool_calls:
# ... Lógica de associação...
retornar resultado
Componente de fluxo: recursos de colaboração para agentes
A função do componente Flow é coordenar vários agentes que trabalham juntos para realizar tarefas mais complexas.
class BaseFlow(BaseModel, ABC).
"""Classe base para fluxos de execução com suporte a vários agentes""""
agentes: Dict[str, BaseAgent]
ferramentas: Optional[List] = None
primary_agent_key: Optional[str] = None
@propriedade
def primary_agent(self) -> Optional[BaseAgent].
"""Obter o agente primário para o flow""""
return self.agents.get(self.primary_agent_key)
@abstractmethod
async def execute(self, input_text: str) -> str.
"""Executar o fluxo com a entrada fornecida""""
Fluxo de planejamento
é uma implementação concreta do Flow para planejamento e execução de tarefas:
class PlanningFlow(BaseFlow).
"""Um fluxo que gerencia o planejamento e a execução de tarefas usando agentes.""""
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 o fluxo de planejamento com agentes."""""
try.
# Criar o plano inicial
if input_text: await self._create_initial_plan
await self._create_initial_plan(input_text)
# Executar a etapa de planejamento
while await self._has_next_step():: # Obtenha a etapa atual.
# Obter a etapa atual
step_info = await self._get_current_step()
# Selecione o executor apropriado
executor = self.get_executor(step_info.get("type"))
# Executar a etapa
result = await self._execute_step(executor, step_info)
# Atualizar o status da etapa
await self._update_step_status(step_info["index"], "completed")
# Concluir o programa
return await self._finalise_plan()
except Exception as e.
# Tratamento de exceções
return f "Erro ao executar o fluxo: {str(e)}"
Implementação de agente do OpenManus: uma arquitetura em camadas
O agente do OpenManus usa uma arquitetura hierárquica, construída camada por camada, desde a funcionalidade básica até aplicativos especializados. Os benefícios desse design são a alta reutilização do código, a alta escalabilidade e as responsabilidades claras em cada nível.
BaseAgent (classe base abstrata)
ReActAgent (modo pensar-agir)
ToolCallAgent (capacidade de chamada de ferramenta)
PlanningAgent (capacidade de planejamento)
SWEAgent (capacidade de engenharia de software)
Manus (agente genérico)
BaseAgent: a base das bases
BaseAgent
é a base de toda a estrutura e define as principais propriedades e métodos de um agente:
class BaseAgent(BaseModel, ABC).
"""Classe base abstrata para gerenciar o estado e a execução do agente.""""
Propriedades principais do #
name: str = Field(... , description="Nome exclusivo do agente")
description: Optional[str] = Field(None, description="Descrição opcional do agente")
Prompt do #
system_prompt: Optional[str] = Field(None, description="Prompt de instrução em nível de sistema")
next_step_prompt: Optional[str] = Field(None, description="Prompt para determinar a próxima ação")
Dependências do #
llm: LLM = Field(default_factory=LLM, description="Instância do modelo de linguagem")
memory: Memory = Field(default_factory=Memory, description="Armazenamento de memória do agente")
state: AgentState = Field(default=AgentState.IDLE, description="Estado atual do agente")
Controle de execução do #
max_steps: int = Field(default=10, description="Máximo de etapas antes do término")
current_step: int = Field(default=0, description="Etapa atual na execução")
ReActAgent: o agente pensante
ReActAgent
Um modelo "pensar-agir" foi realizado, dividindo o processo de execução do agente em duas fases:
class ReActAgent(BaseAgent, ABC).
@abstractmethod
async def think(self) -> bool.
"""Processar o estado atual e decidir a próxima ação"""""
@abstractmethod
async def act(self) -> str.
"""Executar ações decididas""""
async def step(self) -> str.
"""Executar uma única etapa: pensar e agir."""""
should_act = await self.think()
if not should_act: return "Pensamento concluído - nenhuma ação.
return "Pensamento concluído - nenhuma ação necessária"
return await self.act()
ToolCallAgent: agente com capacidade para ferramentas
ToolCallAgent
Adiciona ao Agente a capacidade de usar ferramentas:
classe ToolCallAgent(ReActAgent).
"""Classe de agente básica para lidar com chamadas de ferramenta/função com abstração aprimorada"""""
available_tools: ToolCollection = ToolCollection(
CreateChatCompletion(), Terminate()
)
tool_choices: Literal["none", "auto", "required"] = "auto"
async def think(self) -> bool.
# Obter resposta LLM e seleção de ferramenta
response = await self.llm.ask_tool(
messages=self.messages,
system_msgs=[Message.system_message(self.system_prompt)]
if self.system_prompt
messages, system_msgs=[Message.system_message(self.system_prompt)
tools=self.available_tools.to_params(),
tool_choice=self.tool_choices, )
)
self.tool_calls = response.tool_calls
# Manipulação de respostas e chamadas de ferramentas
# ...
async def act(self) -> str.
# Executar chamadas de ferramenta
resultados = []
para comando em self.tool_calls:
results = await self.execute_tool(command)
# Adicionar a resposta da ferramenta à memória
# ...
results.append(result)
return "nn".join(results)
PlanningAgent: agente que planeja.
PlanningAgent
O planejamento de tarefas e o acompanhamento da execução foram alcançados:
classe PlanningAgent(ToolCallAgent).
"""
Um agente que cria e gerencia planos para resolver tarefas.
Esse agente usa uma ferramenta de planejamento para criar e gerenciar planos estruturados e acompanha o progresso por meio de etapas individuais até a conclusão da tarefa.
Esse agente usa uma ferramenta de planejamento para criar e gerenciar planos estruturados e acompanha o progresso por meio de etapas individuais até a conclusão da tarefa.
"""
# Rastreador de execução de etapas
step_execution_tracker: Dict[str, Dict] = Field(default_factory=dict)
current_step_index: Optional[int] = None
async def think(self) -> bool.
"""Decidir a próxima ação com base no status do plano."""""
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))
# Obter o índice da etapa atual
self.current_step_index = await self._get_current_step_index()
result = await super().think()
# Associar uma chamada de ferramenta à etapa atual
if result and self.tool_calls:
# ... Lógica de associação...
retornar resultado
Manus: Agente onipotente
Manus
é o principal agente do OpenManus, que integra ferramentas e recursos para lidar com uma ampla variedade de tarefas:
classe Manus(ToolCallAgent).
"""
Um agente versátil de uso geral que usa o planejamento para resolver várias tarefas.
Esse agente estende o PlanningAgent com um conjunto abrangente de ferramentas e recursos, incluindo execução em Python, navegação na Web, operações de arquivos e gerenciamento de informações.
Esse agente estende o PlanningAgent com um conjunto abrangente de ferramentas e recursos, incluindo execução em Python, navegação na Web, operações de arquivos e gerenciamento de informações. recuperação
para lidar com uma ampla gama de solicitações de usuários.
"""
nome: str = "manus"
description: str = "Um agente versátil de uso geral"
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()
)
)
Prompt: Diretrizes comportamentais para agentes
O Prompt desempenha uma função essencial na criação de um sistema de Agente, atuando como um manual de instruções que informa ao Agente o que fazer.
Prompt do sistema: definição da função de um agente
O prompt do sistema define as funções básicas e as diretrizes comportamentais para o agente:
SYSTEM_PROMPT = "Você é o OpenManus, um assistente de IA totalmente capaz, destinado a resolver qualquer tarefa apresentada pelo usuário. Você tem várias ferramentas à sua disposição Você tem várias ferramentas à sua disposição que podem ser usadas para concluir com eficiência solicitações complexas. Seja programação, recuperação de informações, processamento de arquivos ou navegação na Web, você pode lidar com tudo isso."
O Prompt informa ao Agente que ele é um assistente de IA multifuncional que pode usar uma variedade de ferramentas para atender à solicitação do usuário.
Prompt de planejamento: orienta o agente no planejamento
O prompt de planejamento informa ao agente como dividir tarefas complexas em tarefas menores com um plano de execução:
PLANNING_SYSTEM_PROMPT = """
Você é um agente de planejamento especializado encarregado de resolver problemas complexos criando e gerenciando planos estruturados.
Seu trabalho é.
1. analisar solicitações para entender o escopo da tarefa
2. criar planos claros e acionáveis com a ferramenta `planning`.
3. executar etapas usando as ferramentas disponíveis, conforme necessário
4. acompanhar o progresso e adaptar os planos de forma dinâmica
5. usar `finish` para concluir quando a tarefa estiver concluída
As ferramentas disponíveis variam de acordo com a tarefa, mas podem incluir.
- `planning`: criar, atualizar e rastrear planos (comandos: create, update, mark_step, etc.)
- `finish`: encerrar a tarefa quando concluída
Divida as tarefas em etapas lógicas e sequenciais. Pense nas dependências e nos métodos de verificação.
"""
Esse Prompt informa ao Agent que ele é um especialista em planejamento e precisa usar o planejamento
ferramentas para criar, atualizar e monitorar planos.
Prompt de uso da ferramenta: Informa ao agente como usar a ferramenta.
O prompt de uso da ferramenta descreve em detalhes as funções e os cenários de uso de cada ferramenta para ajudar o agente a escolher a ferramenta certa:
NEXT_STEP_PROMPT = """Você pode interagir com o computador usando o PythonExecute, salvar arquivos de conteúdo e informações importantes por meio do FileSaver, abrir navegadores com o BrowserUseTool e recuperar informações usando o GoogleSearch.
PythonExecute: executa código Python para interagir com o sistema do computador, processamento de dados, tarefas de automação, etc.
FileSaver: salve arquivos localmente, como txt, py, html, etc.
BrowserUseTool: abrir, navegarSe você abrir um arquivo HTML local, deverá fornecer o caminho absoluto para o arquivo.
GoogleSearch: execute a recuperação de informações da Web
Com base nas necessidades do usuário, selecione proativamente a ferramenta ou a combinação de ferramentas mais adequada. Para tarefas complexas, você pode dividir o problema e usar ferramentas diferentes, passo a passo, para resolvê-lo. Para tarefas complexas, você pode dividir o problema e usar diferentes ferramentas, passo a passo, para resolvê-lo. Depois de usar cada ferramenta, explique claramente os resultados da execução e sugira as próximas etapas.
"Depois de usar cada ferramenta, explique claramente os resultados da execução e sugira as próximas etapas.
Prompt dinâmico: tornando os agentes mais flexíveis
Os prompts no OpenManus não podem ser apenas estáticos, mas também podem ser gerados dinamicamente. Por exemplo, na seção PlanningAgent
no Prompt, o sistema adiciona o status do plano atual ao Prompt:
async def think(self) -> bool.
"""Decidir a próxima ação com base no status do plano."""""
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))
Esse Prompt dinâmico permite que o Agente tome decisões mais racionais com base na situação atual.
Resumo: Insights do OpenManus
Ao analisar o código do OpenManus, podemos resumir vários componentes-chave da estrutura do AI Agent:
- AgenteDesign hierárquico, do básico ao profissional, para atingir diferentes níveis de competência.
BaseAgent
Gerenciamento de estado básico e loops de execução: fornece gerenciamento de estado básico e loops de execução.ReActAgent
Realização do modelo think-act.ToolCallAgent
Adicionar recursos de chamada de ferramentas.- Agente profissional: por exemplo
PlanningAgent
eAgente da SWEA
responder cantandoManus
.
- LLMEncapsulamento da interação com grandes modelos de linguagem, fornecendo recursos de diálogo e de invocação de ferramentas.
- Suporte para diálogo normal e chamadas de ferramentas.
- Implementar mecanismo de repetição e tratamento de erros.
- Há suporte para resposta de fluxo contínuo.
- MemóriaGerenciar o histórico e o contexto do diálogo.
- Armazenar e recuperar mensagens.
- Manter o contexto do diálogo.
- FerramentaInterface: Fornece uma interface para interagir com o mundo externo.
- Abstração básica de ferramentas.
- Várias ferramentas especializadas para conseguir isso.
- Processamento de resultados de ferramentas.
- PlanejamentoPermitir o planejamento de tarefas e o rastreamento da execução.
- Criação e gerenciamento de planos.
- Rastreamento do status da etapa.
- Programas de ajuste dinâmico.
- FluxoGerenciar a colaboração entre vários agentes.
- Atribuição de tarefas.
- Integração de resultados.
- Controle de processos.
- PromptGuia o comportamento e a tomada de decisões do agente.
- O prompt do sistema define a função.
- O Professional Prompt orienta as decisões.
- Geração dinâmica de prompts.
Com seu design claro e código bem estruturado, o OpenManus é um excelente exemplo para aprender sobre implementações de agentes de IA. Seu design modular permite que os desenvolvedores ampliem e personalizem facilmente seus agentes.
O OpenManus é um bom ponto de partida para os desenvolvedores que desejam saber mais sobre os agentes de IA ou criar seus próprios sistemas de agentes. Ao aprender sobre sua arquitetura e implementação, podemos entender melhor como os AI Agents funcionam e como são projetados.