使用 LangGraph 构建真实的**多智能体 AI 系统** | 多智能体 AI + 记忆 + API
这份 YouTube 洞见笔记由 LilysAI 生成。免费注册,从视频中以 10× 速度更深入地获取洞见。
Q: 本内容将介绍如何使用LangGraph构建一个真实世界的多代理AI系统?
本内容将介绍如何使用LangGraph构建一个AI旅行预订系统,该系统包含四个代理(航班代理、酒店代理、行程代理和最终代理),并使用Llama 3 LLM、PostgreSQL进行内存管理以及Tavily Search和Aviation Stack API进行数据获取。
如何使用 LangGraph 建立多代理 AI 系統?透過 LangGraph 框架,結合多個 AI 代理、記憶體和 API,可以建立一個能處理複雜任務的真實世界 AI 系統。
1. 建立多代理 AI 旅遊預訂系統
本教學旨在展示如何使用 LangGraph 框架,結合多個 AI 代理、記憶體和 API,建立一個能處理複雜任務的真實世界 AI 旅遊預訂系統。1.1. 系統概述與技術堆疊
- AI 旅遊預訂系統將包含四個主要代理
- 航班代理 (Flight Agent):負責處理航班相關資訊
- 飯店代理 (Hotel Agent):負責處理飯店相關資訊
- 行程代理 (Itinerary Agent):負責規劃行程
- 最終代理 (Final Agent):負責整合所有資訊並提供最終輸出
- 每個代理將執行其特定任務,並將輸出傳遞給下一個代理,最終生成完整的旅遊計畫
- 系統將利用以下技術和工具:
- LangGraph:作為代理式 AI 框架
- LLaMA 3 (70 億參數模型):透過 Groq 提供的語言模型
- PostgreSQL:作為資料庫,用於儲存應用程式的記憶體,以記住使用者先前的對話,從而提供更好的結果
- Tavily Search API:用於連接 AI 代理到網際網路,以搜尋即時資訊,例如航班和飯店的最新資料
- AviationStack API:提供免費的即時航班資料
- 所有使用的工具和 API 均為免費資源,無需付費帳戶
1.2. 系統運作示範
- 系統將接收使用者輸入的提示,例如:「規劃一個包含航班、飯店和觀光的日本七日遊,預算在 20 萬以下」
- 系統會依序啟動代理管道並顯示輸出
- 航班代理:提供完整的航空公司詳細資訊
- 飯店代理:提供完整的飯店列表資訊
- 行程代理:建立完整的七日行程計畫和預算明細
- 最終代理:整合所有代理的資料,生成最終的詳細行程計畫
- 系統還會顯示 LLM 呼叫次數、使用的代理數量和狀態
- 使用者可以選擇下載最終的旅遊計畫
2. 環境設定與 API 金鑰管理
本節詳細說明如何設定開發環境、安裝必要的 Python 套件,以及獲取和配置所需的 API 金鑰。
2.1. Python 環境設定
- 在 VS Code 中建立一個名為
MultiAgentSystemDemo的資料夾 - 開啟終端機,建立一個 Python 虛擬環境,例如
LangGraph_ENV3- 輸入指令:
python -m venv LangGraph_ENV3
- 輸入指令:
- 啟用虛擬環境
- Linux/Mac 系統:
source LangGraph_ENV3/bin/activate - Windows 系統:
.\LangGraph_ENV3\Scripts\activate
- Linux/Mac 系統:
- 安裝專案所需的所有 Python 套件
2.2. 獲取 Groq API 金鑰
- Groq 提供了多種語言模型,本專案將使用 LLaMA 3 (70 億參數模型)
- 開啟瀏覽器,前往
console.cloud.google.com - 點擊「API 金鑰」並選擇「建立 API 金鑰」
- 為金鑰命名(例如:ASD),勾選同意條款,然後點擊「提交」
- 複製生成的 API 金鑰
- 在 VS Code 的專案資料夾中,建立一個
.env檔案 - 將複製的 API 金鑰儲存為一個變數,例如
GOC_API_KEY="你的API金鑰"
2.3. 獲取 AviationStack API 金鑰
- AviationStack API 用於獲取即時航班資料
- 開啟瀏覽器,前往
aviationstack.com - 如果是首次使用,請先註冊並登入(可使用電子郵件或 Google 帳戶)
- 登入後,點擊「Get Free API」進入儀表板
- 儀表板上會自動顯示一個 API 金鑰,複製該金鑰
- 在
.env檔案中,將其儲存為變數,例如AVIATION_STACK_API_KEY="你的API金鑰"
2.4. 獲取 Tavily Search API 金鑰
- Tavily Search API 允許 AI 代理從網際網路搜尋資料
- 開啟瀏覽器,前往
tavily.com - 如果是首次使用,請先註冊並登入(可使用電子郵件或 Google 帳戶)
- 登入後,儀表板上會自動顯示一個 API 金鑰,複製該金鑰
- 在
.env檔案中,將其儲存為變數,例如TAVILY_API_KEY="你的API金鑰" - 儲存
.env檔案
2.5. 安裝 PostgreSQL 資料庫
- PostgreSQL 用於儲存應用程式的長期記憶體,即使用者對話歷史
- 如果已安裝,可跳過此步驟
- 開啟瀏覽器,搜尋「PostgreSQL 下載」,並點擊官方網站連結
- 選擇您的作業系統(例如 Windows),然後點擊「下載安裝程式」
- 選擇最新的版本進行下載
- 執行下載的
.exe檔案,並按照螢幕上的指示進行安裝- 重要提示:在安裝過程中,會要求設定一個密碼,請務必記住此密碼,因為它將用於連接 LangGraph 應用程式與資料庫
- 預設使用者名稱通常為
PostgreSQL,建議將密碼也設定為PostgreSQL以便記憶 - 記住連接埠號碼,通常是
5432或5433
- 安裝完成後,搜尋並開啟
PGAdmin4 - 如果成功開啟 PGAdmin 4,表示 PostgreSQL 資料庫已成功安裝
- 在 PGAdmin 4 中,點擊伺服器旁的箭頭,輸入您在安裝時設定的密碼以登入
3. 程式碼實作:核心模組與資料庫連接
本節將逐步介紹如何建立專案的核心程式碼,包括匯入必要的套件、設定資料庫連接,以及建立用於資料搜尋的工具函數。
3.1. 建立 main.py 檔案並匯入套件
- 在
MultiAgentSystemDemo資料夾中,建立一個名為main.py的檔案 - 匯入以下必要的 Python 套件:
os模組:用於處理環境變數TypedDict和Annotated:用於建立 LangGraph 的共享記憶體狀態operator模組:用於更新共享記憶體中的訊息列表StateGraph,START,END:用於建立 LangGraph 的圖形結構PostgresSaver:用於將 LangGraph 應用程式連接到 PostgreSQL 資料庫,以實現長期記憶體功能AnyMessage,HumanMessage,AIMessage,SystemMessage:用於表示不同類型的訊息- SystemMessage:代表提供給系統的初始提示
- AIMessage:代表 AI 代理的回覆
- HumanMessage:代表使用者輸入的訊息
- AnyMessage:可以儲存任何類型的訊息
ChatGroq:用於連接 Groq 上的 LLaMA 3 模型
3.2. 建立 tools 資料夾及工具函數
- 在
MultiAgentSystemDemo資料夾中,建立一個名為tools的子資料夾 - 在
tools資料夾中,建立兩個 Python 檔案:tavily_tool.py和flight_tools.py flight_tools.py檔案:- 匯入
requests模組和load_dotenv函數 - 使用
load_dotenv()載入.env檔案中的 API 金鑰 - 定義
search_flights函數:- 接收
query作為參數(使用者查詢) - 設定 AviationStack API 的 URL 和參數,包括
AVIATION_STACK_API_KEY和limit=5(獲取五個結果) - 使用
requests.get()發送請求並獲取航班資料 - 將回應儲存為 JSON 格式到
data變數中 - 建立一個空列表
flights,用於儲存整理後的航班資料 - 遍歷
data中的每個航班,提取airline、departure、arrival和status等資訊 - 將這些資訊以字典形式添加到
flights列表中 - 返回
flights列表
- 接收
- 匯入
tavily_tool.py檔案:- 匯入
TavilyClient模組和load_dotenv函數 - 使用
load_dotenv()載入.env檔案中的 API 金鑰 - 建立
TavilyClient實例,並將TAVILY_API_KEY儲存到client變數中 - 定義
tavily_search函數:- 接收
query作為參數(使用者查詢) - 使用
client.search()執行網際網路搜尋,設定max_results=5(獲取五個結果) - 將搜尋結果儲存到
response變數中 - 建立一個空列表
results,用於儲存整理後的搜尋結果 - 遍歷
response中的每個結果,提取title、url和snippet(內容) - 將這些資訊以字典形式添加到
results列表中 - 返回
results列表
- 接收
- 匯入
3.3. 設定 Groq LLM 和 PostgreSQL 資料庫連接
- 在
main.py中,初始化ChatGroq模型,指定使用llama3-8b-8192模型 - 建立 PostgreSQL 資料庫:
- 在 PGAdmin 4 中,右鍵點擊「資料庫」,選擇「建立」->「資料庫」
- 輸入資料庫名稱,例如
LangGraph_Memory_Demo,然後點擊「儲存」 - 記住這個資料庫名稱,因為它將用於連接 LangGraph 應用程式
- 設定資料庫 URL:
- 在
main.py中,定義DATABASE_URL變數,格式如下:postgresql://使用者名稱:密碼@localhost:連接埠號碼/資料庫名稱 - 範例:
postgresql://PostgreSQL:PostgreSQL@localhost:5432/LangGraph_Memory_Demo - 這裡的「使用者名稱」和「密碼」是您在安裝 PostgreSQL 時設定的,「連接埠號碼」是 PostgreSQL 的預設連接埠(通常是 5432 或 5433),「資料庫名稱」是您剛才建立的資料庫名稱
- 在
- 從
.env檔案中獲取DATABASE_URL
4. 建立 LangGraph 狀態與代理
本節將詳細說明如何定義 LangGraph 的共享狀態(Shared Memory),以及如何建立和配置四個 AI 代理(節點),每個代理負責特定的任務。
4.1. 定義共享狀態 (TravelState)
- 在 LangGraph 中,狀態 (State) 是所有節點(代理)共享的記憶體
- 建立一個名為
TravelState的類別,繼承自TypedDict,用於定義共享狀態的結構 TravelState包含以下鍵值對:messages:Annotated[List[AnyMessage], operator.add]- 儲存所有類型的訊息(使用者、AI、系統),以列表形式存在
operator.add表示當有新訊息時,會將其添加到現有訊息列表的末尾,而不是覆蓋,從而保留對話上下文
user_query:str- 儲存使用者輸入的原始查詢
- 作為後續代理的輸入
flight_result:str- 儲存航班代理的輸出結果
hotel_result:str- 儲存飯店代理的輸出結果
itinerary:str- 儲存行程代理生成的行程計畫
llm_calls:int- 追蹤 LLM 被呼叫的次數,用於成本監控
- 這種共享狀態確保了所有代理都能存取和更新必要的資訊,並維持對話的上下文
4.2. 建立航班代理 (Flight Agent)
- 建立一個名為
flight_agent的函數,接收TravelState作為輸入 - 從
TravelState中提取user_query - 呼叫
search_flights函數(來自flight_tools.py),並將user_query作為參數傳入,獲取航班資料 - 更新
TravelState:- 將獲取的航班資料儲存到
flight_result鍵中 - 將「航班結果已獲取」訊息添加到
messages列表中 - 如果有使用 LLM,則將
llm_calls增加 1(在此代理中未直接使用 LLM,可註解此行)
- 將獲取的航班資料儲存到
- 返回更新後的
TravelState
4.3. 建立飯店代理 (Hotel Agent)
- 建立一個名為
hotel_agent的函數,接收TravelState作為輸入 - 從
TravelState中提取user_query - 將
user_query與「最佳飯店」字串結合,形成新的查詢 - 呼叫
tavily_search函數(來自tavily_tool.py),並將新的查詢作為參數傳入,獲取飯店資料 - 更新
TravelState:- 將獲取的飯店資料儲存到
hotel_result鍵中 - 將「飯店資訊已獲取」訊息添加到
messages列表中 - 如果有使用 LLM,則將
llm_calls增加 1(在此代理中未直接使用 LLM,可註解此行)
- 將獲取的飯店資料儲存到
- 返回更新後的
TravelState
4.4. 建立行程代理 (Itinerary Agent)
- 建立一個名為
itinerary_agent的函數,接收TravelState作為輸入 - 從
TravelState中提取user_query、flight_result和hotel_result - 建立一個提示 (prompt),將這些資訊整合起來,指示 LLM 建立旅遊行程
- 使用
LLM.invoke()呼叫 LLM (LLaMA 3),並提供系統訊息(「您是一位專業的旅遊規劃師」)和整合後的提示 - LLM 將根據這些資訊生成行程計畫,並將回應儲存到
response變數中 - 更新
TravelState:- 將 LLM 生成的行程內容(
response.content)儲存到itinerary鍵中 - 將 LLM 的回應訊息添加到
messages列表中 - 將
llm_calls增加 1,因為此代理確實使用了 LLM
- 將 LLM 生成的行程內容(
- 返回更新後的
TravelState
4.5. 建立最終代理 (Final Agent)
- 建立一個名為
final_agent的函數,接收TravelState作為輸入 - 從
TravelState中提取flight_result、hotel_result和itinerary - 建立一個最終提示,指示 LLM 整合所有資訊,生成最終的旅遊回應
- 使用
LLM.invoke()呼叫 LLM (LLaMA 3),並提供最終提示 - LLM 將生成最終的旅遊計畫回應
- 更新
TravelState:- 將 LLM 的回應訊息添加到
messages列表中 - 將
llm_calls增加 1,因為此代理也使用了 LLM
- 將 LLM 的回應訊息添加到
- 返回更新後的
TravelState
5. LangGraph 圖形建構與執行
本節將說明如何使用 LangGraph 建立圖形結構、定義代理之間的連接,以及如何編譯和執行多代理應用程式,並展示其在終端機中的運作。
5.1. 建立 LangGraph 圖形
- 初始化
StateGraph,並將之前定義的TravelState作為其狀態graph = StateGraph(TravelState)
- 添加節點 (Nodes):將每個代理函數作為節點添加到圖形中
graph.add_node("flight_agent", flight_agent)graph.add_node("hotel_agent", hotel_agent)graph.add_node("itinerary_agent", itinerary_agent)graph.add_node("final_agent", final_agent)
- 定義邊緣 (Edges):建立代理之間的連接,定義工作流程
graph.add_edge(START, "flight_agent"):從START節點開始,連接到flight_agentgraph.add_edge("flight_agent", "hotel_agent"):flight_agent完成後,連接到hotel_agentgraph.add_edge("hotel_agent", "itinerary_agent"):hotel_agent完成後,連接到itinerary_agentgraph.add_edge("itinerary_agent", "final_agent"):itinerary_agent完成後,連接到final_agentgraph.add_edge("final_agent", END):final_agent完成後,連接到END節點,表示工作流程結束
5.2. 設定記憶體 (PostgreSQL)
- 在編譯圖形之前,需要設定記憶體功能,以便將對話歷史儲存到 PostgreSQL 資料庫
- 建立
PostgresSaver實例,並傳入之前設定的DATABASE_URLmemory = PostgresSaver(connection_string=DATABASE_URL)
- 這將 LangGraph 應用程式與 PostgreSQL 資料庫連接起來,允許儲存和檢索對話
5.3. 編譯圖形與執行應用程式
- 編譯圖形:使用
graph.compile()方法編譯圖形,並傳入memory實例作為檢查點 (checkpoint)app = graph.compile(checkpointer=memory)- 編譯後的圖形儲存在
app變數中,現在可以執行
- 執行應用程式 (終端機):
- 在
main.py檔案中,使用if __name__ == "__main__":區塊來執行應用程式 - 設定
config字典,包含configurable鍵和thread_id,例如{"configurable": {"thread_id": "user_aarohi"}}thread_id是每個使用者的唯一識別碼,用於從資料庫中檢索該使用者的對話歷史,實現長期記憶體功能
- 提示使用者輸入旅行請求:
user_input = input("Enter your travel request: ") - 呼叫編譯後的
app,傳入使用者輸入和configresponse = app.invoke({"messages": [HumanMessage(content=user_input)], "user_query": user_input}, config=config)- 這裡將使用者輸入作為
HumanMessage儲存到messages列表中,並將原始查詢儲存到user_query鍵中
- 列印最終回應到終端機
- 在
- 測試執行:
- 在終端機中執行
python main.py - 輸入旅行請求,例如:「規劃一個七日遊」
- 系統將輸出完整的七日行程計畫,包括航班和飯店資訊
- 在終端機中執行
6. 建立 Streamlit 前端介面
本節將介紹如何使用 Streamlit 框架為多代理 AI 旅遊預訂系統建立一個互動式的前端介面,以提供更友善的使用者體驗。
6.1. 建立 frontend.py 檔案並匯入模組
- 在專案資料夾中,建立一個名為
frontend.py的檔案 - 匯入
streamlit模組,以及main.py檔案中編譯好的app實例from main import app- 這樣可以重複使用
main.py中定義的所有代理邏輯和圖形結構
- 匯入其他必要的 Streamlit 模組,例如
st
6.2. 設定 Streamlit 頁面
- 使用
st.set_page_config()設定頁面配置- 設定頁面標題,例如:「AI 旅遊預訂系統」
- 設定頁面圖示
- 設定頁面佈局
- 使用
st.markdown()嵌入自訂 CSS 樣式,用於控制頁面的背景顏色、邊框、字體等視覺效果- 這些樣式定義了按鈕、文字框和圖片的顯示方式,例如圓角邊框、懸停效果等
6.3. 設計側邊欄 (Sidebar)
- 使用 Streamlit 的側邊欄功能 (
st.sidebar) 建立左側導航欄 - 在側邊欄中添加圖片和文字,例如「AI Travel Planner」
- 側邊欄還會顯示其他相關資訊,例如代理列表等
6.4. 設計主內容區域
- 在主內容區域中,顯示多張背景圖片,營造視覺效果
- 顯示系統的標題和簡介文字
- 建立輸入文字框,讓使用者輸入旅行請求
st.text_input("Enter your travel request", key="user_input")
- 建立一個按鈕,例如「生成我的旅行計畫」 (
st.button("Generate My Travel Plan")) - 當使用者點擊按鈕後,系統將執行以下操作:
- 從文字框中獲取使用者輸入
- 呼叫從
main.py匯入的app實例,傳入使用者輸入和thread_id配置 - 顯示代理管道的執行過程和每個代理的輸出(航班、飯店、行程、最終回應)
- 提供一個下載按鈕,讓使用者可以下載完整的旅行計畫
6.5. 執行 Streamlit 應用程式
- 在終端機中,導航到專案資料夾
- 執行指令:
streamlit run frontend.py - Streamlit 應用程式將在瀏覽器中開啟,使用者可以透過圖形介面與 AI 旅遊預訂系統互動
像天才一样理解海量资料——与 LilysAI 一起
超过 1,000,000 名知识探索者正在使用 Lilys AI。
