1. 什么是 LangGraph
LangGraph 是 LangChain 团队开发的状态化(Stateful)智能体编排框架。如果说传统 LangChain 的 Chain/Agent 是线性的,那么 LangGraph 用图结构来表达复杂的工作流。
1.1 为什么选择 LangGraph?
| 特性 | LangChain Agent | LangGraph |
|---|---|---|
| 流程控制 | 简单循环 | DAG + 条件分支 |
| 状态管理 | 有限 | 基于 TypedDict 的显式状态 |
| 多智能体 | 困难 | 原生支持 |
| 人工介入 | 自定义实现 | 内置 interrupt() |
| 流式传输 | 基础 | Token/事件/状态流式传输 |
| 调试 | 困难 | LangGraph Studio |
2. 基本概念
2.1 StateGraph
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
# 1) 定义状态
class AgentState(TypedDict):
messages: Annotated[list, "add_messages"] # 累积消息
next_action: str
result: str
# 2) 定义节点函数
def classify_intent(state: AgentState) -> dict:
"""分类用户意图"""
last_msg = state["messages"][-1].content
# 用 LLM 分类意图
intent = llm.invoke(f"Classify intent: {last_msg}")
return {"next_action": intent.content}
def handle_question(state: AgentState) -> dict:
"""处理问题"""
answer = llm.invoke(state["messages"])
return {"result": answer.content}
def handle_task(state: AgentState) -> dict:
"""执行任务"""
result = agent_executor.invoke(state["messages"])
return {"result": result}
# 3) 构建图
graph = StateGraph(AgentState)
graph.add_node("classify", classify_intent)
graph.add_node("question", handle_question)
graph.add_node("task", handle_task)
# 4) 连接边
graph.add_edge(START, "classify")
graph.add_conditional_edges(
"classify",
lambda state: state["next_action"],
{
"question": "question",
"task": "task",
}
)
graph.add_edge("question", END)
graph.add_edge("task", END)
# 5) 编译并执行
app = graph.compile()
result = app.invoke({"messages": [HumanMessage("What is Kubernetes?")]})
2.2 使用工具的智能体
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
@tool
def search_docs(query: str) -> str:
"""Search internal documentation."""
# 向量数据库检索
results = vectorstore.similarity_search(query, k=3)
return "\n".join([r.page_content for r in results])
@tool
def run_query(sql: str) -> str:
"""Execute a read-only SQL query."""
return db.execute(sql).fetchall()
@tool
def create_ticket(title: str, description: str) -> str:
"""Create a Jira ticket."""
return jira.create_issue(title=title, description=description)
llm = ChatOpenAI(model="gpt-4o")
# 自动创建 ReAct 智能体
agent = create_react_agent(
llm,
tools=[search_docs, run_query, create_ticket],
state_modifier="You are a helpful DevOps assistant."
)
# 执行
result = agent.invoke({
"messages": [HumanMessage("Check if order-service has errors and create a ticket")]
})
3. 高级模式
3.1 多智能体编排
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import create_react_agent
class SupervisorState(TypedDict):
messages: Annotated[list, "add_messages"]
next_agent: str
final_answer: str
# 专业智能体
researcher = create_react_agent(llm, tools=[search_web, search_docs])
coder = create_react_agent(llm, tools=[run_code, read_file])
reviewer = create_react_agent(llm, tools=[analyze_code, lint_code])
def supervisor(state: SupervisorState) -> dict:
"""决定委派给哪个智能体"""
response = llm.invoke([
SystemMessage("You are a supervisor. Route to: researcher, coder, reviewer, or FINISH"),
*state["messages"]
])
return {"next_agent": response.content.strip()}
def run_researcher(state):
result = researcher.invoke({"messages": state["messages"]})
return {"messages": result["messages"]}
def run_coder(state):
result = coder.invoke({"messages": state["messages"]})
return {"messages": result["messages"]}
def run_reviewer(state):
result = reviewer.invoke({"messages": state["messages"]})
return {"messages": result["messages"]}
# 构建图
workflow = StateGraph(SupervisorState)
workflow.add_node("supervisor", supervisor)
workflow.add_node("researcher", run_researcher)
workflow.add_node("coder", run_coder)
workflow.add_node("reviewer", run_reviewer)
workflow.add_edge(START, "supervisor")
workflow.add_conditional_edges(
"supervisor",
lambda s: s["next_agent"],
{
"researcher": "researcher",
"coder": "coder",
"reviewer": "reviewer",
"FINISH": END,
}
)
# 每个智能体执行后返回 supervisor
for agent_name in ["researcher", "coder", "reviewer"]:
workflow.add_edge(agent_name, "supervisor")
app = workflow.compile()
3.2 Human-in-the-Loop
from langgraph.types import interrupt, Command
def sensitive_action(state):
"""在敏感操作前请求人工批准"""
action = state["pending_action"]
# 暂停执行,等待人工批准
approval = interrupt({
"question": f"Approve this action?\n{action}",
"options": ["approve", "reject", "modify"]
})
if approval == "approve":
return execute_action(action)
elif approval == "reject":
return {"result": "Action cancelled by user"}
else:
return {"result": f"Action modified: {approval}"}
# 与检查点一起编译
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()
app = workflow.compile(checkpointer=checkpointer)
# 执行(在 interrupt 处停止)
config = {"configurable": {"thread_id": "user-123"}}
result = app.invoke({"messages": [...]}, config)
# result = {"__interrupt__": {...}}
# 人工批准后恢复
app.invoke(Command(resume="approve"), config)
3.3 并行执行
from langgraph.graph import StateGraph
class ParallelState(TypedDict):
query: str
web_results: str
db_results: str
combined: str
def search_web_node(state):
return {"web_results": search_web(state["query"])}
def search_db_node(state):
return {"db_results": search_db(state["query"])}
def combine_results(state):
combined = f"Web: {state['web_results']}\nDB: {state['db_results']}"
return {"combined": combined}
graph = StateGraph(ParallelState)
graph.add_node("web", search_web_node)
graph.add_node("db", search_db_node)
graph.add_node("combine", combine_results)
# 并行执行: START → [web, db] → combine
graph.add_edge(START, "web")
graph.add_edge(START, "db")
graph.add_edge("web", "combine")
graph.add_edge("db", "combine")
graph.add_edge("combine", END)
app = graph.compile()
4. 流式传输
# 按 token 流式输出
async for event in app.astream_events(
{"messages": [HumanMessage("Explain CQRS")]},
version="v2"
):
if event["event"] == "on_chat_model_stream":
print(event["data"]["chunk"].content, end="", flush=True)
# 按节点流式输出
for chunk in app.stream({"messages": [HumanMessage("...")]}):
for node_name, output in chunk.items():
print(f"[{node_name}]: {output}")
5. 内存与检查点
from langgraph.checkpoint.postgres import PostgresSaver
# PostgreSQL 检查点(生产环境)
checkpointer = PostgresSaver.from_conn_string(
"postgresql://user:pass@localhost/langgraph"
)
app = workflow.compile(checkpointer=checkpointer)
# 会话持久化(通过 thread_id 区分)
config = {"configurable": {"thread_id": "user-456"}}
# 第一条消息
app.invoke({"messages": [HumanMessage("Hi")]}, config)
# 第二条消息(保留之前的对话上下文)
app.invoke({"messages": [HumanMessage("What did I just say?")]}, config)
6. LangGraph Platform 部署
6.1 langgraph.json
{
"dependencies": ["."],
"graphs": {
"agent": "./agent.py:app"
},
"env": ".env"
}
6.2 部署
# 安装 LangGraph CLI
pip install langgraph-cli
# 本地测试
langgraph dev
# 构建 Docker 镜像
langgraph build -t my-agent:latest
# 部署到 LangGraph Cloud
langgraph deploy --app my-agent
7. 测验
Q1. LangGraph 的 StateGraph 中,状态(State)扮演什么角色?
节点之间共享的数据容器。用 TypedDict 定义,每个节点读取并更新状态。可以用 Annotated reducer 定义列表累积等合并策略。
Q2. add_conditional_edges 的用途是什么?
条件分支。根据当前状态动态决定下一个节点。路由函数接收状态,返回下一个节点的名称。
Q3. interrupt() 的作用是什么?
实现 Human-in-the-Loop。中断工作流的执行,等待人工输入(批准/拒绝/修改),然后用 Command(resume=...) 恢复。
Q4. 多智能体中 Supervisor 模式的优点是什么?
由中央 Supervisor 控制整体流程,从而能够(1)发挥每个智能体的专长(2)动态决定任务顺序(3)在执行后判断下一步。
Q5. 为什么要使用检查点(Checkpointer)?
(1)会话持久化 — 按 thread_id 保存状态(2)故障恢复 — 从中断点恢复(3)Human-in-the-Loop — interrupt 后保留状态。
Q6. LangGraph 中并行执行是如何实现的?
从同一个源节点(如 START)连接边到多个节点,即可自动实现并行执行。汇总结果的节点会等待所有前置节点都执行完成。
Q7. create_react_agent 与直接构建 StateGraph 有什么区别?
create_react_agent 是 ReAct(Reasoning + Acting)模式的预构建实现,适合简单的工具使用型智能体。如果需要复杂的分支、多智能体或自定义状态,则要直接构建 StateGraph。
测验
Q1:《LangGraph 智能体工作流实战指南:从多智能体编排到生产部署》主要涵盖哪些内容?
用 LangGraph 构建状态化的 AI 智能体工作流。涵盖 StateGraph、条件路由、多智能体编排、Human-in-the-Loop,以及 LangGraph Platform 部署,全程附带实战代码。
Q2:什么是 LangGraph?
LangGraph 是 LangChain 团队开发的状态化(Stateful)智能体编排框架。如果说传统 LangChain 的 Chain/Agent
是线性的,那么 LangGraph 用图结构来表达复杂的工作流。1.1 为什么选择 LangGraph?
Q3:请说明基本概念的核心内容。
2.1 StateGraph 2.2 使用工具的智能体
Q4:高级模式的要点是什么?
3.1 多智能体编排 3.2 Human-in-the-Loop 3.3 并行执行
Q5:LangGraph Platform 部署是如何运作的?
6.1 langgraph.json 6.2 部署
현재 단락 (1/200)
**LangGraph** 是 LangChain 团队开发的**状态化(Stateful)智能体编排框架**。如果说传统 LangChain 的 Chain/Agent 是线性的,那么 LangGr...