自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

手把手帶你理解OpenManus

發(fā)布于 2025-3-25 00:31
瀏覽
0收藏

我之前演示過幾個OpenManus的demo,其實也就是demo,包括manus,現(xiàn)在也就是demo階段,復雜的plan和flow,現(xiàn)在的代碼支撐和LLM的能力都有待改善,但是我們這期不是吐槽文章,是來把OpenManus給打開看看它的實現(xiàn)是怎么樣的,其實Manus也都差不多,甚至OWL也都差不多,我們看一個就夠了。

手把手帶你理解OpenManus-AI.x社區(qū)

其他的幾個目錄也沒啥特別需要看的,就看app。

手把手帶你理解OpenManus-AI.x社區(qū)

app里面有這么幾個結(jié)構(gòu):

1- agent 沒啥好解釋的

2- flow 就是來做multiagent的planning和管理任務框架的。

3- prompt 

手把手帶你理解OpenManus-AI.x社區(qū)

都是這種形式,來定義系統(tǒng)提示詞和agent的role。

4- tool

手把手帶你理解OpenManus-AI.x社區(qū)

純純干活的了。

手把手帶你理解OpenManus-AI.x社區(qū)

主要看最重要的目錄agent。

大概總體分這么幾個agent。

先看base:base.py 模塊定義了抽象基類 BaseAgent,用于管理代理的狀態(tài)、內(nèi)存、執(zhí)行循環(huán)(包括運行、步驟執(zhí)行、卡住處理)和消息,并提供初始化和配置功能,為構(gòu)建具有特定行為的代理提供基礎框架。

在看planning:planning.py模塊定義了PlanningAgent類,該代理通過PlanningTool和Terminate等工具創(chuàng)建、管理和執(zhí)行任務計劃。它具有初始化、計劃創(chuàng)建(create_initial_plan)、思考(think)、行動(act)、計劃狀態(tài)更新(update_plan_status)、步驟跟蹤(step_execution_tracker)等功能,并能根據(jù)工具執(zhí)行結(jié)果動態(tài)調(diào)整計劃,處理初始請求(run)并檢索當前計劃狀態(tài)(get_plan)。

然后是 react.py:react.py模塊定義了繼承自BaseAgent的抽象類ReActAgent,它通過think(思考,決定下一步行動) 和act(執(zhí)行行動) 兩個抽象方法(需子類實現(xiàn))以及step方法(整合think和act)來處理和執(zhí)行任務,并提供基礎的任務處理框架。

swe和tool就是 指從code和tool了

manus.py:manus.py模塊定義了Manus類,一個繼承自ToolCallAgent(實際上你前面提到了繼承自 PlanningAgent, 請確認是哪個) 的通用智能代理。Manus具有預定義的名稱、描述、系統(tǒng)提示、步驟限制(max_observe,max_steps),并利用包含PythonExecute、WebSearch、BrowserUseTool、FileSaver和Terminate等工具的available_tools集合來執(zhí)行各種任務,并通過_handle_special_tool方法處理(如清理)BrowserUseTool的結(jié)果。

好的,我們來梳理一下這些代碼的調(diào)用邏輯。這里涉及到多個Agent類(BaseAgent,ReActAgent,ToolCallAgent,PlanningAgent,SWEAgent,Manus),以及它們之間的繼承關系和方法調(diào)用。我用文字描述,并結(jié)合偽代碼(因為好解釋)來表示調(diào)用流程。

1. 總體繼承關系:

BaseAgent (抽象基類)
  └─ ReActAgent (抽象基類)
      └─ ToolCallAgent
          ├─ PlanningAgent
          ├─ SWEAgent
          └─ Manus

2.BaseAgent(核心基類):

  • 核心方法:

__init__: 初始化Agent的基本屬性(name, description, llm, memory, state, max_steps等)。

initialize_agent: 使用model_validator在對象創(chuàng)建后進行進一步初始化(設置默認的LLM和Memory)。

state_context: 一個異步上下文管理器,用于安全地更改Agent的狀態(tài)(IDLE, RUNNING, ERROR等)。

update_memory: 將消息添加到Agent的內(nèi)存中。

run: Agent的主執(zhí)行循環(huán)。它會循環(huán)調(diào)用step()方法,直到達到max_steps或狀態(tài)變?yōu)镕INISHED。

step:抽象方法,必須由子類實現(xiàn)。執(zhí)行Agent的單個步驟。

is_stuck: 檢查智能體是否卡住。

handle_stuck_state: 處理卡住的狀態(tài)。

messages: 屬性,用于獲取和設置消息。

  • 調(diào)用流程 (以run方法為例):

async run(request):
  if state != IDLE:
    raise RuntimeError


  if request:
    update_memory(USER, request)


  async with state_context(RUNNING):
    while current_step < max_steps and state != FINISHED:
      current_step += 1
      step_result = await step()  # 調(diào)用子類的 step() 方法
      if is_stuck():
         handle_stuck_state()


      results.append(step_result)


    if current_step >= max_steps:
      state = IDLE
      results.append("Terminated: Reached max steps")


  return "\n".join(results)

3.ReActAgent(ReAct模式的基類):

  • 繼承自:?BaseAgent
  • 核心方法:

think:抽象方法,由子類實現(xiàn)。思考下一步行動。

act:抽象方法,由子類實現(xiàn)。執(zhí)行行動。

step: 實現(xiàn)了BaseAgent的step方法。依次調(diào)用think()和act()。

  • 調(diào)用流程 (以step方法為例):

4.ToolCallAgent(支持工具調(diào)用的Agent):

async step():
  should_act = await think()  # 調(diào)用子類的 think()
  if should_act:
    return await act()  # 調(diào)用子類的 act()
  else:
    return "Thinking complete - no action needed"


  • 繼承自:?ReActAgent
  • 核心方法:

__init__: 初始化工具相關的屬性 (available_tools, tool_choices, special_tool_names, tool_calls等)。

think: 根據(jù)當前狀態(tài)和可用工具,決定是否調(diào)用工具。使用LLM進行決策。

act: 執(zhí)行工具調(diào)用,并處理工具的輸出。

execute_tool: 執(zhí)行具體的工具調(diào)用。

_handle_special_tool: 處理特殊工具。

  • 調(diào)用流程 (以think和act為例):

async think():
  # ... (準備消息和工具信息) ...
  response = await llm.ask_tool(...) # 讓LLM決定是否調(diào)用工具,以及調(diào)用哪個工具
  if response.tool_calls:
     self.tool_calls = response.tool_calls
     return True # 需要執(zhí)行工具
  else:
     return False


async act():
   if self.tool_calls:
      tool_call = self.tool_calls.pop(0) # 取出第一個工具調(diào)用
      result = await execute_tool(tool_call)
      await _handle_special_tool(tool_call.function.name,result) # 如果是特殊工具,則處理。
      update_memory(TOOL, result, tool_call_id=tool_call.id)
      return result
   else:
       return "No tool to execute"

5.PlanningAgent(規(guī)劃型Agent):

  • 繼承自:?ToolCallAgent
  • 核心方法:
  • initialize_plan_and_verify_tools: 初始化計劃ID并驗證是否有PlanningTool。
  • think: 獲取當前計劃狀態(tài),并讓LLM決定下一步行動(包括是否調(diào)用工具)。
  • act: 執(zhí)行工具調(diào)用,并更新計劃狀態(tài)。
  • get_plan: 獲取當前計劃。
  • create_initial_plan: 根據(jù)用戶請求創(chuàng)建初始計劃。
  • update_plan_status: 根據(jù)工具執(zhí)行結(jié)果更新計劃步驟的狀態(tài)。
  • _get_current_step_index: 獲取當前計劃中第一個未完成步驟的索引。
  • 調(diào)用流程 (更詳細,以run->think->act為例):

async run(request):
  if request:
     await create_initial_plan(request)
  return await super().run()  # 調(diào)用 ToolCallAgent.run() -> ReActAgent.run() -> BaseAgent.run()




async create_initial_plan(request):
  # 1. 構(gòu)造消息,讓 LLM 創(chuàng)建計劃
  messages = [...]
  response = await llm.ask_tool(..., tool_choice=ToolChoice.AUTO)


  # 2. 處理 LLM 的響應,提取工具調(diào)用(應該是 planning 工具的調(diào)用)
  for tool_call in response.tool_calls:
    if tool_call.function.name == "planning":
      result = await execute_tool(tool_call) # 執(zhí)行 planning 工具
      # 3. 將工具執(zhí)行結(jié)果(計劃)存入內(nèi)存
      update_memory(TOOL, result, tool_call_id=tool_call.id)




async think():
    prompt = f"CURRENT PLAN STATUS:\n{await self.get_plan()}\n\n{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() # 調(diào)用 ToolCallAgent 的 think()


    if result and self.tool_calls:
       # 記錄工具和步驟的關聯(lián)
       latest_tool_call = self.tool_calls[0]
       if latest_tool_call 不是 planning tool 且 不是 special tool:
           self.step_execution_tracker[latest_tool_call.id] = {
               "step_index": self.current_step_index,
               "tool_name": latest_tool_call.function.name,
                "status": "pending"
           }
    return result


async act():
   result = await super().act() # 調(diào)用 ToolCallAgent 的 act()
   if self.tool_calls:
       latest_tool_call = self.tool_calls[0]
       if latest_tool_call.id in self.step_execution_tracker:
          self.step_execution_tracker[latest_tool_call.id]["status"] = "completed"
          self.step_execution_tracker[latest_tool_call.id]["result"] = result


          if latest_tool_call 不是 planning tool 且 不是 special tool:
              await self.update_plan_status(latest_tool_call.id)
   return result




async update_plan_status(tool_call_id):
  # 1. 檢查 tool_call_id 是否在 tracker 中,以及狀態(tài)是否為 completed
  # 2. 調(diào)用 planning 工具的 mark_step 命令,將對應步驟標記為 completed


async _get_current_step_index():
   # 1. 獲取當前計劃 (文本)
   # 2. 解析計劃文本,找到第一個 [ ] 或 [→] 的步驟
   # 3. 調(diào)用 planning 工具的 mark_step 命令,將當前步驟設置為 in_progress
   # 4. 返回步驟索引

6.SWEAgent(軟件工程師Agent):

  • 繼承自:?ToolCallAgent
  • 核心方法:

think: 更新工作目錄,并使用格式化的next_step_prompt。然后調(diào)用父類的think。

  • 調(diào)用流程 (以think為例):

async think():
  self.working_dir = await self.bash.execute("pwd")  # 獲取當前工作目錄
  self.next_step_prompt = self.next_step_prompt.format(current_dir=self.working_dir) # 更新提示
  return await super().think()  # 調(diào)用 ToolCallAgent 的 think()


7.Manus(通用Agent):

  • 繼承自:?ToolCallAgent
  • 特點:擁有更廣泛的工具集 (PythonExecute, WebSearch, BrowserUseTool, FileSaver, Terminate)。
  • _handle_special_tool: 重寫此方法,處理BrowserUseTool的清理工作。

那么好,我們總結(jié)一下:

  • BaseAgent提供了Agent的基本框架和執(zhí)行循環(huán)。
  • ReActAgent引入了 "思考-行動" 模式。
  • ToolCallAgent增加了工具調(diào)用的能力。
  • PlanningAgent、SWEAgent和Manus是ToolCallAgent的具體實現(xiàn),分別針對不同的任務類型。
  • 調(diào)用邏輯主要通過繼承和重寫think、act和step方法來實現(xiàn)。
  • PlanningAgent具有更復雜的內(nèi)部狀態(tài)管理,用于跟蹤計劃的執(zhí)行。


畫出來就是下圖這樣:

手把手帶你理解OpenManus-AI.x社區(qū)


總體調(diào)用的抽象感覺就是下圖這樣:

手把手帶你理解OpenManus-AI.x社區(qū)

好了今天這節(jié)課就解釋到這,大家可以結(jié)合我的解釋自己去run一下代碼,甚至自己按著這個邏輯來新寫一套multi-agents的框架也不是特別難的事。

本文轉(zhuǎn)載自??熵減AI??,作者:周博洋


收藏
回復
舉報
回復
相關推薦