一文帶你瞭解大模型——智能體(Agent)
作者:lucasgftang
大語言模型 vs 人類
大語言模型很強大,就像人類的大腦一樣擁有思考的能力。如果人類只有大腦,沒有四肢,沒有工具,是沒辦法與世界互動的。如果我們能給大模型配備上四肢和工具呢?大模型是不是就會打破次元壁,從數字世界走向現實世界,與現實世界實現夢幻聯動呢?
大語言模型(後文將用 LLM 指代)可以接受輸入,可以分析 & 推理、可以輸出文字 \ 代碼 \ 媒體。然而,其無法像人類一樣,擁有規劃思考能力、運用各種工具與物理世界互動,以及擁有人類的記憶能力。
-
LLM:接受輸入、思考、輸出
-
人類:LLM(接受輸入、思考、輸出)+ 記憶 + 工具 + 規劃
如果我們給 LLM 配備上:與物理世界互動的工具、記憶能力、規劃思考能力。LLM 是否就可以像人類一樣,能夠自主思考並規劃完成任務的過程,能檢索記憶,能使用各種工具提高效率,最終完成某個任務。
智能體是什麼
智能體的英文是 Agent,AI 業界對智能體提出了各種定義。個人理解,智能體是一種通用問題解決器。從軟件工程的角度看來,智能體是一種基於大語言模型的,具備規劃思考能力、記憶能力、使用工具函數的能力,能自主完成給定任務的計算機程序。
圖 1. 由 LLM 驅動的智能體系統
如圖 1 所示,在基於 LLM 的智能體中,LLM 的充當着智能體的 “大腦” 的角色,同時還有 3 個關鍵部分:
-
規劃(Planning) : 智能體會把大型任務分解爲子任務,並規劃執行任務的流程;智能體會對任務執行的過程進行思考和反思,從而決定是繼續執行任務,或判斷任務完結並終止運行。
-
記憶(Memory): 短期記憶,是指在執行任務的過程中的上下文,會在子任務的執行過程產生和暫存,在任務完結後被清空。長期記憶是長時間保留的信息,一般是指外部知識庫,通常用向量數據庫來存儲和檢索。
-
工具使用(Tool use) 爲智能體配備工具 API,比如:計算器、搜索工具、代碼執行器、數據庫查詢工具等。有了這些工具 API,智能體就可以是物理世界交互,解決實際的問題。
智能體能做什麼
相信看到這裏,我們已經對智能體有了基本的認知。如果你還覺得智能體這個概念有點抽象,沒關係,現在我們來點好玩的,一起來看看智能體能玩出什麼花樣?
智能體之調研員
調研員智能體,可以根據用戶的調研問題,從搜索引擎上搜索資料並總結,然後生成調研報告。這裏使用 MetaGPT 框架中的調研員 示例來展示一個智能體的實際作用及其構成。
運行一下試試
-
輸入調研課題:調研特斯拉 FSD 和華爲 ADS 這兩個自動駕駛系統
~ python3 -m metagpt.roles.researcher "特斯拉FSD vs 華爲ADS"
- 智能體執行調研
(圖左爲馮 · 諾依曼;右爲奧本海默;背後是世界上第一臺馮 · 諾依曼架構的 “現代” 計算機)
- 輸出調研報告 metaGPT 生成並保存了調研報告
特斯拉FSD vs 華爲ADS.md
拆解調研員
調研員智能體構成
回到前文所說的,如果僅有 LLM 這個大腦,是無法完成整個調研流程的。在調研員智能體中,爲 LLM 大腦配備了規劃、工具、記憶的能力,使得他能獨立完成調研任務,下面列出其基本構成,構成分三部分:角色、工具、記憶。在角色中,會註冊各種工具,定義思考規劃的方式,以及本身具備的短期記憶能力。
圖解調研員智能體
智能體的關鍵構成
智能體 如上圖所示,在基於 LLM 的智能體中,LLM 的充當着智能體的 “大腦” 的角色,同時還有 3 個關鍵部分:規劃(Planning)、記憶(Memory)、工具使用(Tool use)
規劃(Planing)
規劃,可以爲理解觀察和思考。如果用人類來類比,當我們接到一個任務,我們的思維模式可能會像下面這樣:
-
我們首先會思考怎麼完成這個任務。
-
然後我們會審視手頭上所擁有的工具,以及如何使用這些工具高效地達成目的。
-
我們會把任務拆分成子任務(就像我們會使用 TAPD 做任務拆分)。
-
在執行任務的時候,我們會對執行過程進行反思和完善,吸取教訓以完善未來的步驟
-
執行過程中思考任務何時可以終止
這是人類的規劃能力,我們希望智能體也擁有這樣的思維模式,因此可以通過 LLM 提示工程,爲智能體賦予這樣的思維模式。在智能體中,最重要的是讓 LLM 具備這以下兩個能力:
子任務分解
通過 LLM 使得智能體可以把大型任務分解爲更小的、更可控的子任務,從而能夠有效完成複雜的任務。
思維鏈(Chain of Thoughts, CoT)
思維鏈已經是一種比較標準的提示技術,能顯著提升 LLM 完成複雜任務的效果。當我們對 LLM 這樣要求「think step by step」,會發現 LLM 會把問題分解成多個步驟,一步一步思考和解決,能使得輸出的結果更加準確。這是一種線性的思維方式。
思維鏈的 prompt 可以像是如下這樣(這裏只是一個極簡的 prompt,實際會按需進行 prompt 調優):
template="Answer the question: Q: {question}? Let's think step by step:"
思維樹(Tree-of-thought, ToT)
對 CoT 的進一步擴展,在思維鏈的每一步,推理出多個分支,拓撲展開成一棵思維樹。使用啓發式方法評估每個推理分支對問題解決的貢獻。選擇搜索算法,使用廣度優先搜索(BFS)或深度優先搜索(DFS)等算法來探索思維樹,並進行前瞻和回溯。
反思和完善
智能體在執行任務過程中,通過 LLM 對完成的子任務進行反思,從錯誤中吸取教訓,並完善未來的步驟,提高任務完成的質量。同時反思任務是否已經完成,並終止任務。
ReAct
(剛接觸到這個單詞時,腦子裏冒出來的是 「React 是由 Facebook 開源的一個進行創建用戶界面的一款 JavaScript 庫....」,打住,我們好像走錯片場了,此 React 非彼 ReAct •﹏• )
ReAct(Yao et al. 2023) ,《ReAct: Synergizing Reasoning and Acting in Language Models》 這篇論文提出一種用於增強大型語言模型的方法,它通過結合推理(Reasoning)和行動(Acting)來增強推理和決策的效果。
-
推理(Reasoning): LLM 基於「已有的知識」或「行動(Acting)後獲取的知識」,推導出結論的過程。
-
行動(Acting): LLM 根據實際情況,使用工具獲取知識,或完成子任務得到階段性的信息。
爲什麼結合推理和行動,就會有效增強 LLM 完成任務的能力?這個問題其實很好回答,我們用上面的「調研員智能體」舉例,我提出了問題:「特斯拉 FSD 對比華爲 ADS」,下面列出幾種不同規劃模式的推演:
-
僅推理(Reasoning Only):LLM 僅僅基於已有的知識進行推理,生成答案回答這個問題。很顯然,如果 LLM 本身不具備這些知識,可能會出現幻覺,胡亂回答一通。
-
僅行動(Acting Only):大模型不加以推理,僅使用工具(比如搜索引擎)搜索這個問題,得出來的將會是海量的資料,不能直接回到這個問題。
-
推理 + 行動(Reasoning and Acting):LLM 首先會基於已有的知識,並審視擁有的工具。當發現已有的知識不足以回答這個問題,則會調用工具,比如:搜索工具、生成報告等,然後得到新的信息,基於新的信息重複進行推理和行動,直到完成這個任務。其推理和行動的步驟會是如下這樣:
推理1:當前知識不足以回答這個問題,要回答該問題,需要知道什麼是「特斯拉FSD 」和「華爲ADS」
行動1:使用搜索工具搜索「特斯拉FSD 」和「華爲ADS」的資料
觀察1:總結行動1的內容
推理2:基於行動1和觀察1的信息,得知這是關於兩個自動駕駛提供商的方案對比,基於已有的信息,現在需要生成報告
行動2:使用生成報告的工具,生成調研報告
觀察2:任務完成
通過巧妙的 promt 提示設計,使得 LLM 重複地執行推理和行動,最終完成任務。ReAct 的 prompt 模版的大致思路爲:
Thought(思考): ...
Action(行動): ...
Observation(觀察): ...
Thought(思考): ...
Action(行動): ...
Observation(觀察): ...
...(Repeated many times(重複多次))
記憶(Memory)
記憶是什麼?當我們在思考這個問題,其實人類的大腦已經在使用記憶。記憶是大腦存儲、保留和回憶信息的能力。記憶可以分爲不同的類型:
-
短期記憶(或工作記憶):這是一種持續時間較短的記憶,能夠暫時存儲和處理有限數量的信息。例如,記住一個電話號碼直到撥打完畢。
-
長期記憶:這是一種持續時間較長的記憶,可以存儲大量信息,從幾分鐘到一生。長期記憶可以進一步分爲顯性記憶和隱性記憶。顯性記憶,可以有意識地回憶和表達的信息,顯性記憶又可以分爲情景記憶(個人經歷的具體事件)和語義記憶(一般知識和概念)。隱性記憶,這種記憶通常是無意識的,涉及技能和習慣,如騎自行車或打字。
仿照人類的記憶機制,智能體實現了兩種記憶機制:
-
短期記憶:在當前任務執行過程中所產生的信息,比如某個工具或某個子任務執行的結果,會寫入短期記憶中。記憶在當前任務過程中產生和暫存,在任務完結後被清空。
-
長期記憶:長期記憶是長時間保留的信息。一般是指外部知識庫,通常用向量數據庫來存儲和檢索。
工具使用(Tool use)
LLM 是數字世界中的程序,想要與現實世界互動、獲取未知的知識,或是計算某個複雜的公式等,都離不開不工具。所以我們需要爲智能體配備各種工具以及賦予它使用工具的能力。
工具是什麼?它可以是錘子、螺絲刀,也可以是函數(function)、軟件開發工具包(sdk)。工具是人類智慧的具象化,擴展我們的能力,提升工作效率。在智能體中,工具就是函數(Function),工具使用就是調用函數(Call Function)。
在 LLM 中實現函數調用,使用到 LLM 的這個能力:
Function Calling
Function Calling 是一種實現大型語言模型連接外部工具的機制。通過 API 調用 LLM 時,調用方可以描述函數,包括函數的功能描述、請求參數說明、響應參數說明,讓 LLM 根據用戶的輸入,合適地選擇調用哪個函數,同時理解用戶的自然語言,並轉換爲調用函數的請求參數(通過 JSON 格式返回)。調用方使用 LLM 返回的函數名稱和參數,調用函數並得到響應。最後,如果需求,把函數的響應傳給 LLM,讓 LLM 組織成自然語言回覆用戶。
function calling 具體工作流程如下圖所示:
不同 LLM 的 API 接口協議會有所不同,下文將以 OpenAI 的 API 協議爲例,說明如何實現 Function Calling
函數描述
我們可以按照智能體的需要來實現函數,比如前文的「調研員」智能體,爲其實現了這些函數:WebBrowseAndSummarize:瀏覽網頁並總結網頁內容;ConductResearch:生成調研報告等。如果是一個智能家居的智能體,可能會需要這些函數:開關燈、開光空調、獲取環境信息等。函數的實現在這裏不展開贅述,一個函數可以自行編碼實現,也可以通過調用外部 API 實現。
假設你的函數已經被實現,我們需要向 LLM 描述這個函數,函數描述的必備要素:
-
函數名
-
函數的功能描述
-
函數的請求參數說明
-
函數的響應參數說明(可選)
「查詢最近天氣」的函數描述:
tools = [
{
"type": "function",
"function": {
"name": "get_n_day_weather_forecast",
"description": "獲取最近n天的天氣預報",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市或鎮區 如:深圳市南山區",
},
"format": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "要使用的溫度單位,攝氏度 or 華氏度",
},
"num_days": {
"type": "integer",
"description": "預測天數",
}
},
"required": ["location", "format", "num_days"]
},
}
}
]
調用 LLM 獲得函數的請求參數
Function Calling 是通過請求 LLM 的 chat API 實現的,在支持 Function Calling 模型的 chat API 參數中,會有一個 functions 參數 (或 tools,不同 LLM 的參數會有所不同) ,通過傳入這個參數,大模型則會知道擁有哪些參數可供使用。並且會根據用戶的輸入,推理出應該調用哪些函數,並將自然語言轉成函數的請求參數,返回給請求方。下面以 OpenAI 的 SDK 舉例:
from openai import OpenAI
def chat_completion_request(messages, tools=None, tool_choice=None, model="gpt-3.5-turbo"):
try:
response = client.chat.completions.create(
model=model,
messages=messages,
tools=tools,
tool_choice=tool_choice,
)
return response
except Exception as e:
print("Unable to generate ChatCompletion response")
print(f"Exception: {e}")
return e
if __name__ == "__main__":
messages = []
messages.append({"role": "system", "content": "不要假設將哪些值輸入到函數中。如果用戶請求不明確,請要求澄清"})
messages.append({"role": "user", "content": "未來5天深圳南山區的天氣怎麼樣"})
chat_response = chat_completion_request(
messages, tools=tools
)
tool_calls = chat_response.choices[0].message.tool_calls
print("===回覆===")
print(tool_calls)
LLM 將會返回get_n_day_weather_forecast
函數的調用參數:
===回覆===
[ChatCompletionMessageToolCall(id='call_7qGdyUEWp34ihubinIUCTXyH', function=Function(arguments='{"location":"深圳市南山區","format":"celsius","num_days":5}', name='get_n_day_weather_forecast'), type='function')]
// 格式化看看:chat_response.choices[0].message.tool_calls:
[
{
"id": "call_7qGdyUEWp34ihubinIUCTXyH",
"function": {
"arguments": {
"location": "深圳市南山區",
"format": "celsius",
"num_days": 5
},
"name": "get_n_day_weather_forecast"
},
"type": "function"
}
]
調用函數
調用方獲得 LLM 返回的函數調用信息(函數名稱和調用參數)後,自行調用函數,並得到函數執行的響應。如果有需要,還可以把函數執行的響應追加到 chat API 的對話中傳給 LLM,讓 LLM 組織成自然語言回覆用戶。
# 執行函數
for tool_call in tool_calls:
function = tool_call.function.name
arguments_list = json.loads(tool_call.function.arguments)
function_to_call = globals().get(function)
result = function_to_call(**arguments_list)
print("===" + function + "===")
print(result)
# 把函數調用結果加入到對話歷史中
messages.append(
{
"tool_call_id": tool_call.id, # 用於標識函數調用的 ID
"role": "user",
"name": function,
"content": "函數執行結果爲:" + str(result)
}
)
# 函數執行結果傳給LLM,組織成自然語言回覆用戶
chat_response = chat_completion_request(
messages, tools=tools
)
print("===回覆===")
print(chat_response.choices[0].message.content)
執行結果:
===get_n_day_weather_forecast===
[{'date': '2023-04-01', 'location': '深圳市南山區', 'temperature': '20°C', 'description': '晴朗'}, {'date': '2023-04-02', 'location': '深圳市南山區', 'temperature': '21°C', 'description': '多雲'}, {'date': '2023-04-03', 'location': '深圳市南山區', 'temperature': '22°C', 'description': '晴朗'}, {'date': '2023-04-04', 'location': '深圳市南山區', 'temperature': '23°C', 'description': '多雲'}, {'date': '2023-04-05', 'location': '深圳市南山區', 'temperature': '24°C', 'description': '晴朗'}]
===回覆===
未來5天深圳南山區的天氣情況如下:
- 4月1日:晴朗,溫度20°C
- 4月2日:多雲,溫度21°C
- 4月3日:晴朗,溫度22°C
- 4月4日:多雲,溫度23°C
- 4月5日:晴朗,溫度24°C
請注意天氣預報僅供參考,實際情況可能會有所變化。
智能體的開發框架
現在(2024 年 5 月)如果你想要開發一個 AI 智能體,已經比大模型爆發的初期方便太多了,隨着 AI 應用需求的持續火熱,智能體框架層出不窮。智能體開發框架,會抽象和封裝那些被高頻使用的模塊,如記憶能力、規劃能力、RAG 能力、大模型調用等。使用智能體框架,可讓幫助你快速搭建智能體。
根據 awesome-ai-agents 的整理,無論是開源的還是閉源的,智能體應用框架在各個領域,比如自定義智能體、編碼、研究、數據分析、多智能體等等,都有比較有代表性的產品可供選擇。
上文曾使用到 MetaGPT ,MetaGPT 是一個多智能體框架,多智能體框架可以幫你開發一個由多個不同職責的智能體組合起來的多智能體。舉個例子,如果我們想開發一個多智能體軟件團隊,該軟件團隊可以根據用戶需求交付代碼,其內部會通過測試代碼、評審代碼來提升代碼質量。該多智能體將包含:開發(coder)、測試(tester)、評審人(reviewer)這三個不同職責的智能體,他們各司其職,互相協作完成任務。下圖的左側是多智能體的協作流程,右側是單智能體的工作流程。
展望
隨着大模型的百花齊放,LLM 會支持更長的上下文、更大的參數規模,其推理能力也會愈發強大。因此,基於大模型搭建的智能體(AI Agent)的能力邊界也在不斷突破。通過智能體技術,我們可以創建各種各樣的 AI 應用,比如:Copilot、DB-GPT 等等,一些 AI 應用已經成爲工作生活中不可缺少的存在。相信 AI 應用的將會快速全面地重構我們曾經習以爲常的軟件形態和交互方式,以及提升人類的生產效率。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/oMIPPgHjvJDyf98K9yNQbQ