[AIGC] AI agent 框架簡單比較

在一個多如繁花的framework時代

Posted by 李定宇 on Saturday, July 6, 2024

前言

目前關於LLM的應用,AI Agent算是討論度十分高的主題;而市面上也有許多開源的agent、multi-agent 框架前仆後繼的出現在開發者眼前,方興未艾。以下探討了幾個framework,簡單聊一下其中的運行邏輯。

MetaGPT

MetaGPT算是我深入研究的一個Multi-Agent framework,我特別用Typescript把官方的Python版本重寫了一遍(MetaGPT-ts repo),來深入了解裡面的細節。

其中MetaGPT最主要的,就是把Agent抽象為 Role、然後Role可以有不同的Action,這些Action才是呼叫LLM、或者其他tool function的執行函數。而不同的Role如果要進行「溝通」,則會在創建時「訂閱」Action。

而運行,是在Enviroment(或者 Team)物件,註冊要參與運行的Role,然後運行;在Environment運行時,會把上一個batch中、Role產生的message 發佈到各個Role的 buffer中,而在下一個batch、Role會檢測這個message是否是來自訂閱的Action,如果有的話,就會參考該message,形成「溝通」。

但我覺得其中缺點在於,MetaGPT需要先設定這個Environment/Team 要run幾個batch;還有就是 role.run 後,Role是把結果拋到Environment 中、而不是返回action的結果,所以一些副作用函數可能就要直接定義在Action裡面,比較難接入到原有的工作流中。

CrewAI

CrewAI跟MetaGPT的方式有點像,但是是一個Agent只處理一個Task;然後把所有Agent都在Crew下註冊。

Crew 的 kickoff 函數是整個entry;接著整理crew下的agent,把一些空屬性給付上。然後有兩種 process type:hierarchical 和 sequential。

  • 如果是 sequential的話,就是順序執行 (_run_sequential_process);
    • 順序執行task 的 execute 方法
    • task 會有 self.context 來記憶之前的agent輸出。
    • 如果定義為異步執行,就交給 thread處理;如果是同步,就直接處理。
    • 讓task中的agent執行 execute_task,中間還會從Crew中獲取memory、放入prompt中,然後執行LLM
  • 如果是 hierarchical,就會有個Boss agent,目標是監控agent的動作有沒有符合goal。

目前看起來,是跟MetaGPT有點像,只是在Agent的定義上、和memory的存取方式有點差別

LangGraph

LangGraph,是直接把Agent的交互方式,抽象為有向圖。雖然是Langchain下的專案,但沒有跟LangChain強綁定,而是使用了LangChain定義好的類型作為交互的 Interface。

但我覺得,與其說LangGraph是一個Multi-Agent的framework,不如說他是對工作函數高度抽象的low-code library。原本是想深入研究其原始碼,但由於在 LangGraph-js 原始碼中看到很多LangChain的type,感覺還需要更多時間解析,就留到下一次吧。。。

思考

現在的Multi-Agent framework,我覺得比較像是對實際工作流的抽象、然後用Prompt engineering的方式讓LLM扮演人類的角色,只是如何抽象、細節如何實現、如何讓Agent進行溝通,是不同framework特殊的地方。

然而,如果真的有一個商業機會是需要抽象化一個工作流,那麼懂該工作流的工程師應該可以直接自己調用函數、LLM SDK,然後自己排列就好,不太需要Multi-Framework的參與。就像Langchain封裝了多個LLM SDK,看起來統一了接口,但也限制了如何使用、修改內部Prompt的操作。但目前LLM的應用發展還在早期階段,在現在就定義並且優化框架,我覺得有點過早。

像是各個 ORM 對數據庫的封裝,因為可以抽象出各個關係型數據庫的大宗操作,而個別數據庫的特殊操作(如鎖)那就在特殊處理就好,所以開發者可以很容易上手各個開源的 ORM library。

又或者,有一個、或者多個很強的用原生LLM SDK開發的Agent應用,然後它們之間有寫共通性、可以抽象出來寫成框架,可能這個時候再進行優化效益應該會比較高。

ChangeLog

  • 20240712–初稿