一句話理解
LangGraph 用有向圖(狀態機)描述 AI 工作流,支援條件分支、迴圈、多 Agent 協作,比普通 Chain 更適合複雜任務。
什麼時候用 LangGraph?
安裝
pip install langgraph
核心概念
State(狀態) ← 整個流程共享的資料結構
Node(節點) ← 每個步驟的函式
Edge(邊) ← 節點之間的連接
Conditional Edge ← 根據 State 決定走哪條路
基本範例:客服分流
from langgraph.graph import StateGraph, END
from typing import TypedDict, Literal
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# 1. 定義 State
class SupportState(TypedDict):
question: str
category: str # "technical" | "billing" | "general"
answer: str
# 2. 定義 Node 函式(每個接收 state,回傳更新)
def classify(state: SupportState) -> SupportState:
"""判斷問題類型"""
response = llm.invoke([
HumanMessage(content=f"""
判斷以下問題屬於哪個類別,只回答一個詞:technical / billing / general
問題:{state['question']}
""")
])
return {"category": response.content.strip()}
def handle_technical(state: SupportState) -> SupportState:
response = llm.invoke([HumanMessage(content=f"作為技術支援,回答:{state['question']}")])
return {"answer": response.content}
def handle_billing(state: SupportState) -> SupportState:
response = llm.invoke([HumanMessage(content=f"作為帳務部門,回答:{state['question']}")])
return {"answer": response.content}
def handle_general(state: SupportState) -> SupportState:
response = llm.invoke([HumanMessage(content=f"作為客服,回答:{state['question']}")])
return {"answer": response.content}
# 3. 條件函式(決定走哪個分支)
def route(state: SupportState) -> Literal["technical", "billing", "general"]:
return state["category"]
# 4. 建立圖
graph = StateGraph(SupportState)
graph.add_node("classify", classify)
graph.add_node("technical", handle_technical)
graph.add_node("billing", handle_billing)
graph.add_node("general", handle_general)
# 5. 加邊
graph.set_entry_point("classify")
graph.add_conditional_edges("classify", route, {
"technical": "technical",
"billing": "billing",
"general": "general"
})
graph.add_edge("technical", END)
graph.add_edge("billing", END)
graph.add_edge("general", END)
# 6. 編譯並執行
app = graph.compile()
result = app.invoke({"question": "我的帳單怎麼算的?", "category": "", "answer": ""})
print(result["answer"])
ReAct Agent 用 LangGraph 實作
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(
model=llm,
tools=[search_tool, calculator_tool],
)
result = agent.invoke({"messages": [HumanMessage(content="台北今天天氣如何?")]})
print(result["messages"][-1].content)
Human-in-the-Loop(中途讓人類審核)
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()
app = graph.compile(
checkpointer=checkpointer,
interrupt_before=["execute_action"] # 執行前暫停等人確認
)
config = {"configurable": {"thread_id": "task_001"}}
# 執行到 interrupt_before 的節點就暫停
result = app.invoke(initial_state, config=config)
# 人類審核後繼續
app.invoke(None, config=config)
圖的視覺化
# 印出 ASCII 圖
print(app.get_graph().draw_ascii())
# 產生 PNG(需安裝 graphviz)
from IPython.display import Image
Image(app.get_graph().draw_mermaid_png())
LangGraph vs Agent 比較
| 面向 | LangGraph | 一般 Agent |
|---|
| 流程控制 | 明確定義圖結構 | LLM 自主決定 |
| 除錯難度 | 容易(每個 node 獨立) | 難(LLM 決策不透明) |
| 條件分支 | ✅ 原生支援 | ❌ 需技巧實作 |
| 迴圈 | ✅ 原生支援 | ❌ 靠 max_iterations |
| 多 Agent | ✅ 原生支援 | ❌ 需自己管 |
| 學習曲線 | 較高 | 較低 |
相關筆記