我們的 Transformers 程式碼代理擊敗 GAIA 基準!
摘要
經過一些實驗,Transformers Agents在構建Agent系統方面的表現給我們留下了深刻印象,因此我們想看看它到底有多好!我們使用使用該庫構建的程式碼Agent在GAIA基準測試中進行了測試,GAIA無疑是最困難、最全面的Agent基準測試……結果我們名列前茅!
本部落格文章中使用的 `transformers.agents` 框架現已升級為獨立庫 smolagents!這兩個庫的API非常相似,因此切換很容易。請訪問 此處 閱讀 `smolagents` 介紹部落格。
GAIA:Agent的嚴峻基準測試
什麼是Agent?
一句話概括:Agent是任何基於大型語言模型(LLM)的系統,它可以根據當前用例的需求呼叫或不呼叫外部工具,並根據LLM的輸出迭代執行後續步驟。工具可以包括從網路搜尋API到Python直譯器的任何內容。
用視覺類比來說:所有程式都可以被描述為圖。先做A,再做B。if/else語句是圖中的分支,但它們不改變圖的結構。我們將**Agent**定義為LLM輸出會改變圖的結構的系統。Agent決定呼叫工具A或工具B,或者什麼都不做;它決定是否再執行一步:這些都會改變圖的結構。您可以將LLM整合到固定工作流中,例如在LLM judge中,但它不是Agent系統,因為LLM的輸出不會改變圖的結構。
以下是執行檢索增強生成的兩種不同系統的圖示:一種是經典的,其圖是固定的。另一種是Agent式的,圖中的一個迴圈可以根據需要重複。
Agent系統賦予了大型語言模型超能力。欲瞭解更多詳情,請閱讀我們之前關於Transformers Agents 2.0釋出的部落格文章。
GAIA是Agent最全面的基準測試。GAIA中的問題非常困難,並突出了基於LLM的系統面臨的一些困難。
這是一個棘手問題的例子
2008年畫作“烏茲別克刺繡”中展示的水果,哪些曾出現在1949年10月為後來被用作電影“最後一次航行”浮動道具的遠洋客輪提供的早餐選單上?請以逗號分隔列表的形式給出這些水果,並根據它們在畫作中從12點鐘位置順時針排列的順序進行排序。請使用每種水果的複數形式。
你可以看到這個問題涉及到幾個難點
- 以受限格式回答。
- 從影像中讀取水果的多模態能力
- 需要收集幾條資訊,有些資訊依賴於其他資訊
- 圖片中的水果
- 用作“最後一次航行”浮動道具的遠洋客輪的身份
- 上述遠洋客輪的1949年10月早餐選單
- 上述要求正確的解決路徑需要使用多個鏈式步驟。
解決這個問題既需要高層次的規劃能力,也需要嚴謹的執行力,而這正是LLM難以應對的兩個領域。
因此,它是Agent系統的一個極佳測試集!
在GAIA的公開排行榜上,GPT-4-Turbo的平均得分未達到7%。排名第一的提交(之前)是基於Autogen的解決方案,它採用複雜的多Agent系統,並利用OpenAI的工具呼叫函式,達到了40%。
讓我們來挑戰他們。🥊
構建合適的工具 🛠️
我們使用三種主要工具來解決GAIA問題
a. 網頁瀏覽器
對於網頁瀏覽,我們主要重用了Autogen團隊提交中的Markdown網頁瀏覽器。它包含一個儲存當前瀏覽器狀態的`Browser`類,以及幾個用於網頁導航的工具,如`visit_page`、`page_down`或`find_in_page`。這個工具返回當前視口的markdown表示。使用markdown大大壓縮了網頁資訊,這可能會導致一些遺漏,與截圖並使用視覺模型等其他解決方案相比。然而,我們發現該工具總體表現良好,且使用或編輯起來不會過於複雜。
注:我們認為將來改進此工具的好方法是使用selenium包而不是requests來載入頁面。這將允許我們載入javascript(許多頁面沒有javascript無法正常載入)並接受cookie以訪問某些頁面。
b. 檔案檢查器
許多GAIA問題依賴於各種型別(如.xls、.mp3、.pdf等)的附件。這些檔案需要正確解析。我們再次使用了Autogen的工具,因為它執行得非常好。
非常感謝Autogen團隊開源了他們的工作。使用這些工具,我們的開發過程加快了幾周!🤗
c. 程式碼直譯器
我們不需要這個,因為我們的Agent天生就能生成並執行Python程式碼:詳見下文。
程式碼Agent 🧑💻
為什麼選擇程式碼Agent?
正如Wang et al. (2024)所示,讓Agent以程式碼形式表達其行為相比使用JSON等字典式輸出具有多項優勢。對我們而言,主要優勢在於**程式碼是一種高度最佳化的方式,能夠表達複雜的行為序列**。可以說,如果存在比我們當前程式語言更好、更嚴謹地表達詳細行為的方式,那它早就成為一門新的程式語言了!
請看他們論文中給出的這個例子:

它突出了使用程式碼的幾個優點
- 程式碼動作比JSON**更簡潔**。
- 需要執行4個並行流,每個流包含5個連續動作?在JSON中,您需要生成20個JSON物件,每個都在其單獨的步驟中;而在程式碼中,只需1個步驟。
- 平均而言,該論文顯示程式碼操作所需的步驟比JSON少30%,這相當於生成的token也減少了30%。由於LLM呼叫通常是Agent系統的主要成本,這意味著您的Agent系統執行成本大約降低了30%。
- 程式碼能夠重用通用庫中的工具。
- 在基準測試中,使用程式碼能獲得更好的效能,原因有二:
- 這是一種更直觀的表達行為的方式
- LLM的訓練資料中包含大量程式碼,這可能使它們在程式碼編寫方面比JSON編寫更流暢。
我們在agent_reasoning_benchmark的實驗中證實了這些觀點。
從我們最近構建transformers Agent的實驗中,我們還觀察到其他優點:
- 在程式碼中將元素儲存為命名變數要容易得多。例如,需要儲存工具生成的這張石頭圖片以供以後使用?
- 在程式碼中沒問題:使用“rock_image = image_generation_tool(“一塊石頭的圖片”)”將把變數儲存在變數字典中名為“rock_image”的鍵下。之後,LLM可以透過再次引用“rock_image”在其任何程式碼塊中使用其值。
- 在JSON中,你必須做一些複雜的變通來建立一個名稱來儲存這張圖片,以便LLM以後知道如何再次訪問它。例如,將影像生成工具的任何輸出儲存為“image_{i}.png”,並相信LLM以後會理解image_4.png是它在記憶體中前一個工具呼叫的輸出?或者讓LLM也輸出一個“output_name”鍵來選擇儲存變數的名稱,從而使你的動作JSON的結構複雜化?
- 代理日誌的可讀性大大提高。
Transformers Agents CodeAgent 的實現
大型語言模型(LLM)生成的程式碼直接執行起來可能非常不安全。如果你讓LLM在沒有防護措施的情況下編寫和執行程式碼,它可能會產生幻覺:例如,你的所有個人檔案都需要被《沙丘》傳奇的副本擦除,或者你唱歌《冰雪奇緣》主題曲的音訊需要分享到你的部落格上!
因此,對於我們的Agent,我們必須確保程式碼執行安全。通常的方法是從上到下:“使用功能齊全的Python直譯器,但禁止某些操作”。
為了更安全,我們更傾向於反其道而行之,**從頭開始構建一個LLM安全的Python直譯器**。給定LLM提供的Python程式碼塊,我們的直譯器從`ast` Python模組給出的程式碼的抽象語法樹(AST)表示開始。它逐個執行樹節點,遵循樹結構,並在遇到任何未經明確授權的操作時停止。
例如,一個`import`語句將首先檢查該匯入是否明確地列在使用者定義的`authorized_imports`列表中:如果不在,則不執行。我們包含一個預設的內建標準Python函式列表,其中包括`print`和`range`。除了使用者明確授權的任何內容,都不會被執行。例如,`open`(如`with open("path.txt", "w") as file:`)是不允許的。
當遇到函式呼叫(`ast.Call`)時,如果函式名是使用者定義的工具之一,則使用呼叫的引數呼叫該工具。如果是之前定義並允許的其他函式,則正常執行。
我們還進行了一些調整,以幫助LLM使用直譯器:
- 我們限制了執行中的運算元量,以防止LLM生成程式碼中的問題導致的無限迴圈:每次操作,計數器都會遞增,如果達到某個閾值,執行就會中斷。
- 我們限制了列印輸出中的行數,以避免用垃圾資訊淹沒LLM的上下文長度。例如,如果LLM讀取了一個1M行的文字檔案並決定列印每一行,那麼在某個時候,這個輸出將被截斷,從而防止Agent的記憶體爆炸。
基本多Agent編排
網頁瀏覽是一種上下文非常豐富的活動,但大多數檢索到的上下文實際上是無用的。例如,在上面的GAIA問題中,唯一重要的資訊是繪畫“烏茲別克刺繡”的圖片。圍繞它的任何內容,比如我們找到它的部落格內容,對於更廣泛的任務解決通常是無用的。
為了解決這個問題,使用多Agent步驟是有意義的!例如,我們可以建立一個管理者Agent和一個網路搜尋Agent。管理者Agent應解決更高層次的任務,並向網路搜尋Agent分配特定的網路搜尋任務。網路搜尋Agent應僅返回其搜尋的有用輸出,這樣管理者就不會被無用資訊淹沒。
我們正是在我們的工作流程中建立了這種多Agent編排
- 頂層Agent是一個ReactCodeAgent。它天生支援程式碼,因為其動作以Python形式編寫和執行。它可以使用以下工具:
- `file_inspector` 用於讀取文字檔案,可選的 `question` 引數用於不返回檔案的全部內容,而只返回其對特定問題的基於內容的答案。
- `visualizer`專門用於回答影像相關問題。
- `search_agent` 用於瀏覽網頁。更具體地說,這個工具只是一個Web搜尋Agent的封裝,Web搜尋Agent是一個JSON Agent(JSON對於嚴格順序的任務仍然很好用,比如網頁瀏覽中你向下滾動,然後導航到新頁面等等)。這個Agent反過來又可以使用網頁瀏覽工具。
資訊網路搜尋
向下翻頁
在頁面中查詢
- …(完整列表在此行)
這種將Agent嵌入為工具是一種幼稚的多Agent編排方式,但我們想看看它能走多遠——事實證明,它能走得相當遠!
規劃元件 🗺️
現在有各種各樣的規劃策略,我們選擇了一個相對簡單的預先規劃工作流。每N步我們生成兩樣東西:
- 我們已知的事實總結,或者我們可以從上下文和需要發現的事實中推斷出來
- 基於新的觀察和上述事實摘要,解決任務的分步計劃
引數N可以針對目標用例進行調整,以獲得更好的效能:我們為管理器Agent選擇了N=2,為網路搜尋Agent選擇了N=5。
一個有趣的發現是,如果我們不提供計劃的先前版本作為輸入,分數反而會上升。一個直觀的解釋是,大型語言模型(LLM)通常會強烈偏向於上下文中可用的任何相關資訊。如果計劃的先前版本存在於提示中,LLM很可能會大量重用它,而不是在需要時重新評估方法並重新生成計劃。
事實摘要和計劃都被用作生成下一步行動的額外上下文。規劃鼓勵LLM透過將所有達到目標的步驟和當前事務狀態呈現在其面前,從而選擇更好的執行路徑。
結果 🏅
我們在驗證集上取得了44.2%的成績:這意味著Transformers Agent的ReactCodeAgent現在總體排名第一,比第二名高出4個百分點!**在測試集上,我們取得了33.3%的成績,排名第二,領先於微軟Autogen的提交,並且在難度最高的Level 3問題上獲得了最佳平均分數。**

這是一個數據點,支援程式碼操作效果更好的觀點。考慮到它們的效率,我們認為程式碼操作很快就會取代JSON/OAI格式,成為Agent編寫其操作的標準。
據我們所知,LangChain和LlamaIndex目前不支援開箱即用的程式碼操作。微軟的Autogen對程式碼操作有一些支援(在Docker容器中執行程式碼),但這似乎是JSON操作的輔助功能。因此,Transformers Agents是唯一將此格式作為核心的庫!
下一步
希望您喜歡閱讀這篇部落格文章!工作才剛剛開始,我們將從以下幾個方面繼續改進Transformers Agents:
- LLM引擎:我們的提交是用GPT-4o(可惜)完成的,**沒有經過任何微調**。我們的假設是,使用微調的開源模型可以消除解析錯誤,並提高一些分數!
- 多Agent編排:我們目前的編排方式比較簡單,如果能實現更無縫的編排,我們可能會走得更遠!
- 網路瀏覽器工具:使用`selenium`包,我們可以擁有一個能夠透過cookie橫幅並載入javascript的網頁瀏覽器,從而使我們能夠訪問許多目前無法訪問的頁面。
- 進一步改進規劃:我們正在對文獻中的其他選項進行消融測試,以檢視哪種方法效果最好。我們計劃嘗試現有元件的其他實現以及一些新元件。當我們有更多見解時,我們將釋出更新!
在接下來的幾個月裡,請密切關注Transformers Agents!🚀
如果您有任何用例,請隨時與我們聯絡。現在我們已經建立了Agent方面的內部專業知識,我們將很樂意提供幫助!🤝