Build a basic chatbot¶
在本教程中,您將建立一個基本的聊天機器人。這個聊天機器人是後續系列教學的基礎,您將逐步添加更複雜的功能,並在過程中學習 LangGraph 的關鍵概念。讓我們開始吧! 🌟
Prerequisites¶
在開始本教學之前,請確保您可以存取支援工具呼叫功能的 LLM,例如 OpenAI, Anthropic 或 Google Gemini。
1. Install packages¶
安裝所需的軟體包:
2. Create a StateGraph¶
現在,您可以使用 LangGraph 建立一個基本的聊天機器人。該聊天機器人將直接回覆用戶訊息。
首先建立一個 StateGraph。 StateGraph 物件將聊天機器人的結構定義為 "state machine"。我們將新增 nodes 來表示 llm 和聊天機器人可以呼叫的函數,以及 edges 來指定機器人如何在這些函數之間轉換。
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
# 定義一個用來記錄并保存 Agent 在 node 中共同分享的 State 物件
class State(TypedDict):
# Messages have the type "list". The `add_messages` function
# in the annotation defines how this state key should be updated
# (in this case, it appends messages to the list, rather than overwriting them)
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
我們的 graph 現在可以處理兩個 key tasks:
- 每個
node可以接收目前State作為輸入,並輸出更新的State。 - 由於預先建置的
add_messages函數與Annotated語法配合使用,訊息更新將附加到現有清單(messages)中,而不是覆寫它。
Tip
Python 中的 TypedDict 是一種類型提示,用於定義具有固定字串鍵和其對應值的特定類型的字典。它為字典帶來了一定程度的結構化類型,允許像 MyPy 這樣的靜態類型檢查器在開發過程中驗證字典資料的結構和類型。
例如:
預設來說, 所有被定義在 TypedDict 的 properties 都是 "Must", 如果要設定 "Optional":
Tip
Annotated 是 Python 3.9 中引入的一種特殊類型提示,允許將任意元資料附加到類型註解。
Annotated 則允許添加可供其他庫使用或用於運行時驗證的額外詳細信息。
工作原理: - Annotated 至少接受兩個參數: - 實際類型:這是類型檢查器將識別的基底類型。 - 元資料:可以是任意數量的表示元資料的附加參數。
from typing import Annotated
# Define a type hint with metadata for validation
Age = Annotated[int, "value should be between 0 and 120"]
def process_age(age: Age):
# In a real application, a library like Pydantic or a custom validator
# would use the metadata to enforce the constraint.
print(f"Processing age: {age}")
process_age(30)
# process_age(150) # This would likely raise a validation error if a validator is in place
靜態類型檢查器會忽略這些參數,但庫或自訂程式碼可以在運行時存取它們。
3. Add a node¶
接下來,新增一個 chatbot 節點。**Nodes` 代表工作單元,通常是常規的 Python 函數。
我們先選擇一個 chat model:
import os
from langchain.chat_models import init_chat_model
os.environ["OPENAI_API_KEY"] = "sk-..."
llm = init_chat_model("openai:gpt-4.1-mini")
我們現在可以將 chat model 合併到一個簡單的 node:
# 新增一個 `chatbot` 節點
def chatbot(state: State):
return {"messages": [llm.invoke(state["messages"])]}
# 第一個參數是唯一的節點名稱
# 第二個參數是每當節點被使用時將被呼叫的函數或物件。
graph_builder.add_node("chatbot", chatbot)
Info
請注意,chatbot 節點函數如何將當前狀態作為輸入,並傳回 dict,其中包含鍵 messages 下的更新訊息清單。這是所有 LangGraph 節點函數的基本模式。
我們狀態中的 add_messages 函數會將 LLM 的回應訊息附加到狀態中已有的任何訊息之後。
4. Add an entry point¶
增加一個 entry 來告訴 graph 物件每次運行時從那個 node 開始工作:
5. Add an exit point¶
新增 exit 節點,指示 graph 物件應在何處結束執行。這對於更複雜的流程很有幫助,但即使在像這樣的簡單 graph 中,添加結束節點也能提高清晰度。
這告訴 graph 在運行 chatbot節點後就轉換到 END。
6. Compile the graph¶
在運行 graph 之前,我們需要對其進行編譯。我們可以透過在 graph 建構器上呼叫 compile() 來實現。這將建立一個 CompiledGraph,我們可以在狀態上呼叫它。
7. Visualize the graph (optional)¶
您可以使用 get_graph 方法和某個 draw 方法(例如 draw_ascii 或 draw_png)來視覺化圖表。每個 draw 方法都需要額外的依賴項。
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
# This requires some extra dependencies and is optional
pass
8. Run the chatbot¶
現在來運行聊天機器人!
Tip
您可以隨時輸入 quit, exit 或 q 退出聊天循環。
def stream_graph_updates(user_input: str):
# 執行 graph 並傳入使用者的 input
for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}):
# 串流地取回回應
for value in event.values():
# 打印最後的 message
print("Assistant:", value["messages"][-1].content)
# 構建 loop 來持績與 chatbot 進行對話
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 if input() is not available
user_input = "What do you know about LangGraph?"
print("User: " + user_input)
stream_graph_updates(user_input)
break
恭喜!您已經使用 LangGraph 建立了第一個聊天機器人。該機器人可以透過接收用戶輸入並使用 LLM 生成回應來進行基本對話。您可以檢查上述調用的 LangSmith Trace。
以下是本教學的完整程式碼:
from typing import Annotated
from langchain.chat_models import init_chat_model
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
llm = init_chat_model("openai:gpt-4.1-mini")
def chatbot(state: State):
return {"messages": [llm.invoke(state["messages"])]}
# The first argument is the unique node name
# The second argument is the function or object that will be called whenever
# the node is used.
graph_builder.add_node("chatbot", chatbot)
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
graph = graph_builder.compile()
Next steps¶
你可能已經注意到,chatbot 的知識僅限於其訓練資料。在下一部分中,我們將添加一個網頁搜尋工具,以擴展 chatbot 的知識,使其更加強大。