LangGraph入門指南

LangGraph入門指南

使用大型語言模型(LLM)構建應用程式是一件令人興奮的事情,因為它能讓我們建立智慧的互動式系統。然而,讓這些應用程式變得更加複雜也帶來了挑戰,尤其是當多個 LLM 一起工作時。那麼,我們該如何管理它們之間的資訊流?如何確保它們順利工作並理解任務?LangGraph 就是所有這些問題的答案。本免費教程是初學者瞭解 LangGraph 如何解決這些問題的好方法。本指南將透過實際操作示例和完整程式碼,教你如何有效管理多個 LLM,讓你的應用程式更強大、更高效。

瞭解LangGraph

LangGraph 是一個功能強大的庫,是 LangChain 工具的一部分。它有助於簡化 LLM 的整合,確保它們無縫協作,以理解和執行任務。它提供了一種簡便的方法來構建和處理具有許多代理的 LLM 應用程式。

LangGraph 允許開發人員設定多個 LLM 代理如何相互對話。它將這些工作流程顯示為迴圈圖。這有助於保持通訊順暢並很好地執行復雜任務。在使用有向無環圖(DAG)執行直線任務時,LangGraph 的效果最佳。但由於它是迴圈圖,並增加了迴環能力,因此可以實現更復雜、更靈活的系統。這就好比一個智慧代理可能會重新思考問題,並利用新資訊更新響應或改變選擇。

多個 LLM 代理

LangGraph的關鍵概念

以下是您需要了解的 LangGraph 的一些關鍵概念:

1. 圖形結構

LangGraph 的核心理念是為應用程式的工作流程使用圖形。該圖有兩個主要部分–節點和邊。

  • 節點:節點是基本的構建模組,代表工作流中工作或計算的離散單元。每個節點都是一個 Python 函式,用於處理當前狀態並返回更新後的狀態。節點可以執行的任務包括呼叫 LLM 和與工具或 API 互動以運算元據。
  • 邊:邊連線節點並定義執行流程。它們可以是
    • 簡單邊:從一個節點到另一個節點的直接、無條件轉換。
    • 條件邊:根據節點輸出引導流程的分支邏輯,類似於 if-else 語句。這樣就可以在工作流程中進行動態決策。

2. 狀態管理

在有許多代理的情況下,跟蹤正在發生的事情至關重要。所有代理都需要知道任務的當前狀態。LangGraph 透過自動管理狀態來解決這個問題。該庫跟蹤並更新一個主狀態物件。當代理執行任務時,它就會這樣做。狀態物件包含重要資訊。它可以在工作流的不同階段使用。這可能包括聊天記錄。

在聊天機器人中,狀態可以儲存對話。這有助於機器人使用之前的對話內容做出回應。它還可以儲存上下文資料,如使用者喜好、過去的操作等或外部資料。代理可以利用這些資料做出選擇。內部變數也可以儲存在這裡。代理可以使用狀態跟蹤標誌、計數或其他值。這些有助於指導它們的行動和決策。

3. 多代理系統

多代理系統由多個獨立的代理組成,它們透過合作或競爭來實現共同的目標。這些代理使用 LLM 做出決策並控制應用程式的流程。隨著代理和任務的增加,系統的複雜性也會隨之增加。這可能會導致決策失誤、上下文管理和專業化需求等挑戰。多代理系統透過將系統分解成較小的代理來解決這些問題,每個代理都專注於特定的任務,如規劃或研究。

使用多代理系統的主要好處是模組化、專業化和控制。模組化便於開發、測試和維護,而專業化則能確保專家代理提高整體效能。控制可確保您清楚地知道代理應如何交流。

多代理系統中的架構

以下是多代理系統中遵循的各類架構。

多代理系統中的架構

Source: LangChain

1. 網路架構:在這種架構中,每個代理都與其他代理進行通訊,然後每個代理都可以決定下一步應該呼叫哪個代理。當沒有明確的操作順序時,這種架構非常有用。下面是一個使用狀態圖(StateGraph)的簡單示例。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langchain_openai import ChatOpenAI
from langgraph.types import Command
from langgraph.graph import StateGraph
model = ChatOpenAI()
def agent_1(state) -> Command:
response = model.invoke(...)
return Command(goto=response["next_agent"], update={"messages": [response["content"]]})
builder = StateGraph()
builder.add_node(agent_1)
builder.compile()
from langchain_openai import ChatOpenAI from langgraph.types import Command from langgraph.graph import StateGraph model = ChatOpenAI() def agent_1(state) -> Command: response = model.invoke(...) return Command(goto=response["next_agent"], update={"messages": [response["content"]]}) builder = StateGraph() builder.add_node(agent_1) builder.compile()
from langchain_openai import ChatOpenAI
from langgraph.types import Command
from langgraph.graph import StateGraph
model = ChatOpenAI()
def agent_1(state) -> Command:
response = model.invoke(...)
return Command(goto=response["next_agent"], update={"messages": [response["content"]]})
builder = StateGraph()
builder.add_node(agent_1)
builder.compile()

2. 主管架構:監管代理控制決策過程,並將任務分配給相應的代理。下面是一個示例:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def supervisor(state) -> Command:
response = model.invoke(...)
return Command(goto=response["next_agent"])
builder = StateGraph()
builder.add_node(supervisor)
builder.compile()
def supervisor(state) -> Command: response = model.invoke(...) return Command(goto=response["next_agent"]) builder = StateGraph() builder.add_node(supervisor) builder.compile()
def supervisor(state) -> Command:
response = model.invoke(...)
return Command(goto=response["next_agent"])
builder = StateGraph()
builder.add_node(supervisor)
builder.compile()

3. 帶有工具呼叫功能的監督員:在這種架構中,監管代理使用工具呼叫代理來決定使用哪種工具(或代理)。工具執行任務並返回結果,為下一步控制流決策提供指導。一種常見的模式是使用工具包裝功能:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def agent_1(state):
response = model.invoke(...)
return response.content
def agent_1(state): response = model.invoke(...) return response.content
def agent_1(state):
response = model.invoke(...)
return response.content

4. 分層架構:這種方法透過將代理組織成團隊來解決多代理系統的複雜性問題,每個團隊都有自己的主管。頂層主管負責指揮哪個團隊。例如:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def top_level_supervisor(state):
response = model.invoke(...)
return Command(goto=response["next_team"])
builder = StateGraph()
builder.add_node(top_level_supervisor)
builder.compile()
def top_level_supervisor(state): response = model.invoke(...) return Command(goto=response["next_team"]) builder = StateGraph() builder.add_node(top_level_supervisor) builder.compile()
def top_level_supervisor(state):
response = model.invoke(...)
return Command(goto=response["next_team"])
builder = StateGraph()
builder.add_node(top_level_supervisor)
builder.compile()

5. 多代理系統中的切換:切換允許一個代理將控制權傳遞給另一個代理,從而促進從一個代理到下一個代理的流程。每個代理都會返回一個“命令”(Command)物件,指定下一個要呼叫和傳送狀態更新的代理。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def agent(state) -> Command:
goto = get_next_agent(...)
return Command(goto=goto, update={"my_state_key": "my_state_value"})
def agent(state) -> Command: goto = get_next_agent(...) return Command(goto=goto, update={"my_state_key": "my_state_value"})
def agent(state) -> Command:
goto = get_next_agent(...)
return Command(goto=goto, update={"my_state_key": "my_state_value"})

在複雜的系統中,代理可能巢狀在子圖中,子圖中的節點可以將控制權指向其圖外的另一個代理:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def some_node_inside_alice(state):
return Command(goto="bob", graph=Command.PARENT)
def some_node_inside_alice(state): return Command(goto="bob", graph=Command.PARENT)
def some_node_inside_alice(state):
return Command(goto="bob", graph=Command.PARENT)

多代理系統採用模組化和專業化設計,代理可獨立處理任務並進行交流,從而高效地解決問題。網路系統、監督系統和分層系統等架構都能滿足特定需求,而交接則能確保代理之間的平穩過渡,保持靈活性和控制性。

4. 永續性

永續性指的是儲存程序的進度,這樣即使在中斷之後,您也可以稍後再返回。每個步驟的狀態都會被儲存,這有助於錯誤恢復。它支援執行過程中的人為反饋。您還可以重放步驟來除錯或嘗試新的路徑。

永續性

Source: LangChain

在 LangGraph 中,永續性是透過檢查點來實現的。在這裡,圖的狀態會在每個主要步驟後儲存,每個儲存的狀態都稱為一個檢查點。所有檢查點都集中在一個執行緒(特定執行的對話歷史)中。

檢查點是自動完成的,不需要總是手動配置。檢查點就像是圖表狀態的快照,其中包括

  • config:該步驟中使用的配置資訊
  • metadata:步驟詳細資訊(例如,哪個節點正在執行)
  • values:此時的實際狀態值
  • next:將執行的下一個(多個)節點
  • tasks:任務資訊或錯誤資訊

每個圖形在執行時都需要一個執行緒 ID 來對其檢查點進行分組。可以透過配置提供執行緒 ID: 下面是一個示例:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
config = {"configurable": {"thread_id": "1"}}
config = {"configurable": {"thread_id": "1"}}
config = {"configurable": {"thread_id": "1"}}

要獲取執行緒內的最新狀態,請使用下面的程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph.get_state({"configurable": {"thread_id": "1"}})
graph.get_state({"configurable": {"thread_id": "1"}})
graph.get_state({"configurable": {"thread_id": "1"}})

下面的程式碼顯示瞭如何獲取特定的檢查點:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph.get_state({
"configurable": {
"thread_id": "1",
"checkpoint_id": "your_checkpoint_id"
}
})
graph.get_state({ "configurable": { "thread_id": "1", "checkpoint_id": "your_checkpoint_id" } })
graph.get_state({
"configurable": {
"thread_id": "1", 
"checkpoint_id": "your_checkpoint_id"
}
})

要獲取狀態歷史記錄或以前的所有狀態,請使用此程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
history = graph.get_state_history({"configurable": {"thread_id": "1"}})
history = graph.get_state_history({"configurable": {"thread_id": "1"}})
history = graph.get_state_history({"configurable": {"thread_id": "1"}})

您也可以隨時手動更新或編輯狀態:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph.update_state(
config={"configurable": {"thread_id": "1"}},
values={"foo": "new_value"}
)
graph.update_state( config={"configurable": {"thread_id": "1"}}, values={"foo": "new_value"} )
graph.update_state(
config={"configurable": {"thread_id": "1"}},
values={"foo": "new_value"}
)

5. Human-in-the-Loop整合

在自動 LangGraph 工作流程的關鍵步驟中,您可以新增人的反饋。這在某些任務中至關重要,因為 LLM 可能會產生不確定或有風險的輸出,例如在工具呼叫、內容生成或決策過程中。LangGraph 的 interrupt() 函式可以暫停圖形,將資料顯示給人類,然後使用 Command(resume=value) 方法根據人類的輸入恢復圖形。這樣就可以進行審查、修正或資料輸入。

Human-in-the-Loop 支援批准/拒絕、編輯狀態、提供輸入或多輪對話等模式。要使用它,請定義一個檢查指標,並在節點內新增 interrupt()。在人工輸入後,您可以使用 Command 恢復圖形。

Human-in-the-Loop整合

來源:LangChain

下面是如何在 LangGraph 中使用“Human-in-the-loop”的示例。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langgraph.types import interrupt, Command
def human_node(state):
value = interrupt({"text_to_revise": state["some_text"]})
return {"some_text": value}
graph = graph_builder.compile(checkpointer=checkpointer)
graph.invoke(some_input, config={"configurable": {"thread_id": "some_id"}})
graph.invoke(Command(resume="Edited text"), config={"configurable": {"thread_id": "some_id"}})
from langgraph.types import interrupt, Command def human_node(state): value = interrupt({"text_to_revise": state["some_text"]}) return {"some_text": value} graph = graph_builder.compile(checkpointer=checkpointer) graph.invoke(some_input, config={"configurable": {"thread_id": "some_id"}}) graph.invoke(Command(resume="Edited text"), config={"configurable": {"thread_id": "some_id"}})
from langgraph.types import interrupt, Command
def human_node(state):
value = interrupt({"text_to_revise": state["some_text"]})
return {"some_text": value}
graph = graph_builder.compile(checkpointer=checkpointer)
graph.invoke(some_input, config={"configurable": {"thread_id": "some_id"}})
graph.invoke(Command(resume="Edited text"), config={"configurable": {"thread_id": "some_id"}})

這可以保持工作流程的互動性、可審計性和準確性,是高風險或協作式人工智慧用例的完美選擇。

6. 流

LangGraph 可在建立輸出時將其串流起來,讓使用者更快地看到結果。這改善了使用者使用 LLM 的體驗。資料流可向您顯示即時進度,從而幫助您構建響應式應用程式。有 3 種主要資料型別可用於流式傳輸:工作流進度、LLM 標記和自定義更新。

使用 .stream() (sync) 或 .astream() (async) 來實現流式輸出。您可以設定 stream_mode 來控制輸出內容:

  • “values”:每個圖形步驟後的完整狀態
  • “updates”:僅在每個節點後發生變化
  • “custom”:在節點中記錄的任何自定義資料
  • “messages”:帶有後設資料的 LLM 標記流
  • “debug”:整個執行過程中的所有資訊

您可以像這樣傳遞多種模式:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for stream_type, data in graph.stream(inputs, stream_mode=["updates", "messages"]):
if stream_type == "messages":
print(data[0].content) # AIMessageChunk
elif stream_type == "updates":
print(data) # State update
for stream_type, data in graph.stream(inputs, stream_mode=["updates", "messages"]): if stream_type == "messages": print(data[0].content) # AIMessageChunk elif stream_type == "updates": print(data) # State update
for stream_type, data in graph.stream(inputs, stream_mode=["updates", "messages"]):
if stream_type == "messages":
print(data[0].content)  # AIMessageChunk
elif stream_type == "updates":
print(data)  # State update

如果需要完整的事件流,請使用 .astream_events() 。這在遷移大型應用程式時非常適合。

專業建議:對於即時 UI 反饋,可使用“messages”進行令牌流,使用“updates”進行後臺狀態。

為什麼使用LangGraph?

LangGraph 是開發人員構建智慧、靈活的人工智慧代理的理想選擇。原因如下

  • 可靠、可控:新增節制檢查和人工審批。它能讓長期任務的上下文保持活力。
  • 自定義和可擴充套件:使用底層工具按自己的方式構建代理。設計系統時,每個代理都能發揮特定的作用。
  • 流式傳輸:即時檢視每個標記和步驟,跟蹤代理的思考過程。

您還可以學習 Langchain 學院的這門課程 ,瞭解更多資訊。

構建最簡單的圖表

既然我們已經看到了 LangGraph 的關鍵元件,那麼讓我們嘗試用三個節點和一條條件邊構建一個基本圖。這個簡單的示例展示瞭如何呼叫涉及狀態、節點和邊等關鍵概念的圖形。

節點

Step 1:定義圖狀態

狀態定義了節點之間共享的資料結構。它就像一個在圖中流動的共享記憶體。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from typing_extensions import TypedDict
class State(TypedDict):
graph_state: str
from typing_extensions import TypedDict class State(TypedDict): graph_state: str
from typing_extensions import TypedDict
class State(TypedDict):
graph_state: str

在這裡,我們使用了 python 的 TypeDict 來宣告我們的狀態將有一個名為 graph_state 的單鍵,其中儲存了一個字串。

Step 2:建立節點

節點只是簡單的 Python 函式。每個節點都接收當前狀態,對其進行修改,然後返回更新後的狀態。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def node_1(state):
print("---Node 1---")
return {"graph_state": state['graph_state'] + " I am"}
def node_1(state): print("---Node 1---") return {"graph_state": state['graph_state'] + " I am"}
def node_1(state):
print("---Node 1---")
return {"graph_state": state['graph_state'] + " I am"}

此函式將“I am”新增到 graph_state 中的任何字串中。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def node_2(state):
print("---Node 2---")
return {"graph_state": state['graph_state'] + " extremely happy!"}
def node_3(state):
print("---Node 3---")
return {"graph_state": state['graph_state'] + " extremely sad!"}
def node_2(state): print("---Node 2---") return {"graph_state": state['graph_state'] + " extremely happy!"} def node_3(state): print("---Node 3---") return {"graph_state": state['graph_state'] + " extremely sad!"}
def node_2(state):
print("---Node 2---")
return {"graph_state": state['graph_state'] + " extremely happy!"}
def node_3(state):
print("---Node 3---")
return {"graph_state": state['graph_state'] + " extremely sad!"}

在這裡,這兩個節點為句子新增了“happy!”或“sad!”的情感基調。

Step 3:新增條件邏輯

有時您需要動態行為,即下一步取決於邏輯或隨機性。這就是條件邊的作用。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import random
from typing import Literal
def decide_mood(state) -> Literal["node_2", "node_3"]:
if random.random() < 0.5:
return "node_2"
return "node_3"
import random from typing import Literal def decide_mood(state) -> Literal["node_2", "node_3"]: if random.random() < 0.5: return "node_2" return "node_3"
import random
from typing import Literal
def decide_mood(state) -> Literal["node_2", "node_3"]:
if random.random() < 0.5:
return "node_2"
return "node_3"

該函式以相等的機率在節點_2 和節點_3 之間隨機選擇,模擬一個簡單的情緒選擇器。

Step 4:構建圖

讓我們使用 LangGraph 的 StateGraph 類將這一切整合在一起。我們在這裡定義完整的圖結構。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from IPython.display import Image, display
from langgraph.graph import StateGraph, START, END
# Initialize the graph with the state schema
builder = StateGraph(State)
# Add nodes to the graph
builder.add_node("node_1", node_1)
builder.add_node("node_2", node_2)
builder.add_node("node_3", node_3)
from IPython.display import Image, display from langgraph.graph import StateGraph, START, END # Initialize the graph with the state schema builder = StateGraph(State) # Add nodes to the graph builder.add_node("node_1", node_1) builder.add_node("node_2", node_2) builder.add_node("node_3", node_3)
from IPython.display import Image, display
from langgraph.graph import StateGraph, START, END
# Initialize the graph with the state schema
builder = StateGraph(State)
# Add nodes to the graph
builder.add_node("node_1", node_1)
builder.add_node("node_2", node_2)
builder.add_node("node_3", node_3)

我們從 START 節點開始,路由到節點_1。然後,我們使用 decide_mood 從節點_1 開始新增一條條件邊。之後,圖繼續延伸至節點_2 或節點_3,並在終點節點處結束。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Add edges to define flow
builder.add_edge(START, "node_1")
builder.add_conditional_edges("node_1", decide_mood)
builder.add_edge("node_2", END)
builder.add_edge("node_3", END)
# Compile and visualize the graph
graph = builder.compile()
display(Image(graph.get_graph().draw_mermaid_png()))
# Add edges to define flow builder.add_edge(START, "node_1") builder.add_conditional_edges("node_1", decide_mood) builder.add_edge("node_2", END) builder.add_edge("node_3", END) # Compile and visualize the graph graph = builder.compile() display(Image(graph.get_graph().draw_mermaid_png()))
# Add edges to define flow
builder.add_edge(START, "node_1")
builder.add_conditional_edges("node_1", decide_mood)
builder.add_edge("node_2", END)
builder.add_edge("node_3", END)
# Compile and visualize the graph
graph = builder.compile()
display(Image(graph.get_graph().draw_mermaid_png()))

定義完整的圖結構

compile() 方法可執行基本驗證,而 draw_mermaid_png() 則可將圖形視覺化為美人魚圖。

Step 5:呼叫圖表

最後,我們可以使用 invoke() 方法執行圖表。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph.invoke({"graph_state" : "Hi, this is Janvi."})
graph.invoke({"graph_state" : "Hi, this is Janvi."})
graph.invoke({"graph_state" : "Hi, this is Janvi."})

這將在 START 節點處啟動圖形,並用句子 “嗨,我是 Janvi ”初始化 graph_state。

  1. node_1 新增 “I am”→“Hi, this is Janvi.”。
  2. decide_mood 隨機選擇路徑
  3. node_2 或 node_3 應用“extremely happy!”或“extremely sad!”。

輸出:

呼叫圖表

該輸出顯示了狀態如何在圖的每個步驟中流動和更新。

使用OpenAI透過LangGraph構建支援聊天機器人

在上一節中,我們已經構建了最簡單的圖,在本節中,我將向您展示如何使用 LangGraph 構建支援聊天機器人,從基本功能開始,逐步新增網路搜尋、記憶和人在迴路等功能。在此過程中,我們還將瞭解 LangGraph 的核心概念。

我們的目標是建立一個聊天機器人,它可以使用網路搜尋回答問題、記住過去的對話、在需要時向人類尋求幫助、使用自定義狀態行為以及倒帶對話路徑(透過檢查點啟用)。

設定

在構建聊天機器人之前,我們先安裝必要的軟體包。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
!pip install -U langgraph langchain openai
!pip install -U langgraph langchain openai
!pip install -U langgraph langchain openai

此命令將安裝:

  • LangGraph:用於構建圖形結構。
  • LangChain:用於與 OpenAI 的語言模型互動。
  • OpenAI:用於使用 OpenAI 的模型(如GPT-4)。

我們需要安全地提供 OpenAI API 金鑰,以便應用程式可以驗證和使用 GPT 模型。如果環境中尚未設定金鑰,則此函式會提示輸入金鑰。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import getpass
import os
def _set_env(var: str):
if not os.environ.get(var):
os.environ[var] = getpass.getpass(f"{var}: ")
_set_env("OPENAI_API_KEY")
import getpass import os def _set_env(var: str): if not os.environ.get(var): os.environ[var] = getpass.getpass(f"{var}: ") _set_env("OPENAI_API_KEY")
import getpass
import os
def _set_env(var: str):
if not os.environ.get(var):
os.environ[var] = getpass.getpass(f"{var}: ")
_set_env("OPENAI_API_KEY")

第 1 部分:構建基本聊天機器人

我們將從建立最簡單的聊天機器人開始。

1. 定義狀態

狀態定義了在圖中節點之間傳遞的資料結構。在這裡,我們定義了一個帶有單鍵 messages 的狀態,它將儲存對話資訊列表。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.messae import add_messages
class State(TypedDict):
# 'messages' holds the list of chat messages.
# 'add_messages' ensures new messages are added, not replaced.
messages: Annotated[list, add_messages]
from typing import Annotated from typing_extensions import TypedDict from langgraph.graph import StateGraph, START, END from langgraph.graph.messae import add_messages class State(TypedDict): # 'messages' holds the list of chat messages. # 'add_messages' ensures new messages are added, not replaced. messages: Annotated[list, add_messages]
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.messae import add_messages
class State(TypedDict):
# 'messages' holds the list of chat messages.
# 'add_messages' ensures new messages are added, not replaced.
messages: Annotated[list, add_messages]

2. 建立圖形生成器

StateGraph 物件是定義圖形結構的入口點。它使用我們剛剛建立的狀態定義進行初始化。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph_builder = StateGraph(State)
graph_builder = StateGraph(State)
graph_builder = StateGraph(State)

3. 新增聊天機器人節點

我們定義了一個 Python 函式 chatbot,它獲取當前狀態,用狀態中的訊息呼叫 OpenAI 的 GPT 模型,並返回 LLM 的響應,作為狀態中訊息鍵的更新。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import openai
# Initialize OpenAI GPT model
openai.api_key = os.environ["OPENAI_API_KEY"]
def chatbot(state: State):
response = openai.Completion.create(
model="gpt-4", # You can also use "gpt-3.5-turbo" or any other OpenAI model
prompt=state["messages"],
max_tokens=150
)
return {"messages": [response.choices[0].text.strip()]}
graph_builder.add_node("chatbot", chatbot)
import openai # Initialize OpenAI GPT model openai.api_key = os.environ["OPENAI_API_KEY"] def chatbot(state: State): response = openai.Completion.create( model="gpt-4", # You can also use "gpt-3.5-turbo" or any other OpenAI model prompt=state["messages"], max_tokens=150 ) return {"messages": [response.choices[0].text.strip()]} graph_builder.add_node("chatbot", chatbot)
import openai
# Initialize OpenAI GPT model
openai.api_key = os.environ["OPENAI_API_KEY"]
def chatbot(state: State):
response = openai.Completion.create(
model="gpt-4",  # You can also use "gpt-3.5-turbo" or any other OpenAI model
prompt=state["messages"],
max_tokens=150
)
return {"messages": [response.choices[0].text.strip()]}
graph_builder.add_node("chatbot", chatbot)

4. 設定進入點和退出點

定義圖形執行的入口點(START)和出口點(END)。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
graph_builder.add_edge(START, "chatbot") graph_builder.add_edge("chatbot", END)
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)

5. 編譯圖形

定義好所有節點和邊後,編譯圖形結構。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
graph = graph_builder.compile()
graph = graph_builder.compile()
graph = graph_builder.compile()

6. 視覺化(可選)

LangGraph 允許將編譯後的圖形結構視覺化。這有助於理解執行流程。我們可以使用 pygraphviz 或 mermaid 等工具將圖視覺化。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
pass # Optional visualization
from IPython.display import Image, display try: display(Image(graph.get_graph().draw_mermaid_png())) except Exception: pass # Optional visualization
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
pass # Optional visualization

圖形結構視覺化

7. 執行聊天機器人

設定一個與聊天機器人互動的迴圈。它接收使用者輸入,將其打包成預期的 State 格式 ({"messages": […]}),然後使用 graph.stream 執行圖表。隨著圖形的進行,stream 方法會返回事件,我們會列印助手的最終訊息。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def stream_graph_updates(user_input: str):
for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}):
for value in event.values():
print("Assistant:", value["messages"][-1].content)
# Loop to chat with the bot
while True:
try:
user_input = input("User: ")
if user_input.lower() in ["quit", "exit", "q"]:
print("Goodbye!")
break
stream_graph_updates(user_input)
except: # Fallback for environments without input()
user_input = "What do you know about LangGraph?"
print("User: " + user_input)
stream_graph_updates(user_input)
break
def stream_graph_updates(user_input: str): for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}): for value in event.values(): print("Assistant:", value["messages"][-1].content) # Loop to chat with the bot while True: try: user_input = input("User: ") if user_input.lower() in ["quit", "exit", "q"]: print("Goodbye!") break stream_graph_updates(user_input) except: # Fallback for environments without input() user_input = "What do you know about LangGraph?" print("User: " + user_input) stream_graph_updates(user_input) break
def stream_graph_updates(user_input: str):
for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}):
for value in event.values():
print("Assistant:", value["messages"][-1].content)
# Loop to chat with the bot
while True:
try:
user_input = input("User: ")
if user_input.lower() in ["quit", "exit", "q"]:
print("Goodbye!")
break
stream_graph_updates(user_input)
except: # Fallback for environments without input()
user_input = "What do you know about LangGraph?"
print("User: " + user_input)
stream_graph_updates(user_input)
break

執行聊天機器人

第 2 部分:利用工具增強聊天機器人的功能

為了讓聊天機器人掌握更多知識,尤其是最近的資訊,我們將整合網路搜尋工具(Tavily)。這需要讓 LLM 能夠請求使用工具,並新增圖元件來處理這些工具的執行。

1. 安裝工具要求

安裝 Tavily 搜尋工具所需的庫。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
%pip install -U tavily-python langchain_community
%pip install -U tavily-python langchain_community
%pip install -U tavily-python langchain_community

2. 設定工具API金鑰

配置 Tavily 服務的 API 金鑰。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
_set_env("TAVILY_API_KEY") # Uses the function defined earlier
_set_env("TAVILY_API_KEY") # Uses the function defined earlier
_set_env("TAVILY_API_KEY")  # Uses the function defined earlier

3. 定義工具

例項化 TavilySearchResults 工具,它將返回 2 個結果。LLM 和圖表都將使用該工具。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langchain_community.tools.tavily_search import TavilySearchResults
# Create a Tavily search tool instance, limiting to 2 results
tool = TavilySearchResults(max_results=2)
tools = [tool] # List of tools the bot can use
from langchain_community.tools.tavily_search import TavilySearchResults # Create a Tavily search tool instance, limiting to 2 results tool = TavilySearchResults(max_results=2) tools = [tool] # List of tools the bot can use
from langchain_community.tools.tavily_search import TavilySearchResults
# Create a Tavily search tool instance, limiting to 2 results
tool = TavilySearchResults(max_results=2)
tools = [tool]  # List of tools the bot can use

第 2 部分:為聊天機器人新增記憶功能

為了讓機器人在多輪對話中記住之前的資訊,我們引入了 LangGraph 的檢查點功能。

新增校驗指標

使用 MemorySaver 校驗指標將對話狀態儲存在記憶體中。在生產中,您可能會使用 SQLite 或 Postgres 等永續性後端。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
from langgraph.checkpoint.memory import MemorySaver memory = MemorySaver()
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()

第 4 部分:Human-in-the-loop

有時,人工智慧代理在繼續工作之前可能需要人工輸入。我們可以透過建立一個暫停圖流的工具來實現這一點。

定義人工輔助工具

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langchain_core.tools import tool
from langgraph.types import interrupt
@tool
def human_assistance(query: str) -> str:
print(f"Pausing for human assistance regarding: {query}")
# interrupt pauses graph execution and waits for input
human_response = interrupt({"query": query})
return human_response["data"]
from langchain_core.tools import tool from langgraph.types import interrupt @tool def human_assistance(query: str) -> str: print(f"Pausing for human assistance regarding: {query}") # interrupt pauses graph execution and waits for input human_response = interrupt({"query": query}) return human_response["data"]
from langchain_core.tools import tool
from langgraph.types import interrupt
@tool
def human_assistance(query: str) -> str:
print(f"Pausing for human assistance regarding: {query}")
# interrupt pauses graph execution and waits for input
human_response = interrupt({"query": query})
return human_response["data"]

該工具會暫停圖形,等待人工輸入後再繼續。

部署LangGraph應用程式

構建好 LangGraph 應用程式後,接下來需要做的就是在本地機器或雲平臺上執行應用程式,以便進一步開發和測試。LangGraph為我們提供了多種部署選項,這些選項可以有不同的工作流程和基礎架構。

在部署方面,LangGraph支援多種選項。雲 SaaS 模式可為您處理一切事務。自託管資料平面(Self-Hosted Data Plane)可讓您在自己的雲中執行應用程式,同時使用 LangChain 的控制平面。使用自託管控制平面,你可以自己管理一切。或者使用獨立容器,使用 Docker 獲得充分的靈活性。

LangGraph的使用案例

LangGraph 可用於構建互動式智慧人工智慧代理。讓我們來探索和了解它的一些用例。

1. 改善客戶服務:LangGraph 能夠為客戶支援開發高階聊天機器人。這些聊天機器人能夠回憶起過去的購買記錄和客戶偏好。透過回憶過去的記錄,它們可以回覆有關訂單的詢問,並在必要時與人類建立聯絡。這樣就能更快地解決客戶的問題。

2. 人工智慧研究助手:使用 LangGraph 也可以建立一個研究助手。它可以查詢學術文章,然後突出顯示重要資訊。然後,助理可以提取資訊,研究人員和學生可以利用這些資訊從各個領域獲得更多見解。

3. 個性化學習:利用 LangGraph,我們還可以建立個性化或定製化學習系統,根據學習者的情況調整學習內容。這將幫助學習者瞭解自己的薄弱環節,然後根據薄弱環節推薦資源。這將創造個性化的學習體驗,提高參與度和學習效果。

4. 簡化業務任務:LangGraph 還能幫助我們實現業務流程自動化。有了它,檔案審批和專案管理可以實現自動化,代理還可以用來分析資料。自動化有助於提高生產力,減少人為錯誤,讓團隊專注於更高層次的任務。

 

小結

在這篇面向初學者的 LangGraph 教程中,您學會了如何構建互動式人工智慧系統。這些系統不僅僅是簡單的問答機器人。透過 LangGraph 示例,我們瞭解了 LangGraph 如何管理狀態、整合多個代理並允許人類輸入。該指南展示瞭如何構建一個支援聊天機器人,它可以處理網路搜尋、記住過去的互動,甚至可以讓人類介入。

對於開發人員來說,LangGraph 入門教程非常有用。它有助於建立強大的人工智慧驅動應用程式。透過使用 LangGraph,我們可以構建靈活、自適應的系統,處理複雜的任務。無論您是要建立聊天機器人、研究助手還是個性化學習工具,LangGraph 都能為您提供高效開發所需的結構和工具。

評論留言