LangGraph 是 LangChain 团队推出的有状态、多 Actor 应用框架,专为构建循环、有记忆的 LLM Agent 而设计。本文带你从核心概念出发,手把手搭建一个会思考、能工具调用的 AI 助手。
目录
- 为什么需要 LangGraph?
- 核心概念:图、节点、边、状态
- 环境安装与准备
- Hello World:最简单的 Graph
- 状态管理:让 Agent 有记忆
- 条件路由:让 Agent 做决策
- 实战:带工具调用的 ReAct Agent
- 人工介入(Human-in-the-loop)
- 总结与进阶方向
1. 为什么需要 LangGraph?
普通的 LangChain 链是单向的——输入进去,输出出来,一气呵成。但真实世界的 AI Agent 需要:
| 能力 | 说明 |
|---|---|
| 🔄 循环执行 | Agent 需要反复调用工具,直到任务完成,而不是一次性输出 |
| 🧠 持久状态 | 跨多步骤甚至跨多轮对话记住上下文信息 |
| 🔀 条件分支 | 根据 LLM 输出动态决定下一步走哪条路径 |
| 👁️ 人工介入 | 在关键节点暂停,让人类确认或修改,再继续执行 |
LangGraph 用 有向图(Directed Graph) 的思路解决了这些问题。每个节点是一个处理步骤,边决定控制流,整个图维护一份共享状态,支持循环,天然适合 Agent 场景。
| 能力 | LangChain Chain | LangGraph |
|---|---|---|
| 循环 / 重试 | ✗ 不支持 | ✓ 原生支持 |
| 条件分支 | 有限支持 | ✓ 完整路由系统 |
| 持久化状态 | ✗ | ✓ Checkpoint 机制 |
| 人工介入 | ✗ | ✓ interrupt_before/after |
| 流式输出 | 部分 | ✓ 原生 streaming |
2. 核心概念:图、节点、边、状态
LangGraph 的世界由四个要素构成,理解它们是一切的基础:
- Graph(图) :整个 Agent 的控制流骨架,由节点和边组成,类似状态机。
- Node(节点) :一个普通 Python 函数,接收 State 返回 State 的更新,是实际的计算单元。
- Edge(边) :连接节点的路径。普通边固定跳转,条件边根据状态动态选择下一节点。
- State(状态) :贯穿整个图执行的共享数据结构,每个节点读取并更新它的一部分。
START → [节点 A] → (条件路由) → [节点 B: 工具调用] → END
↘ [节点 C: 生成回复] → END
↑__________ 共享 State 贯穿整个执行过程 __________↑
3. 环境安装与准备
ℹ️ 需要 Python 3.9+,建议使用虚拟环境(venv 或 conda)隔离依赖。
# 安装核心依赖
pip install langgraph langchain-openai langchain-core
# 可选:可视化依赖
pip install grandalf
配置 API Key:
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
# 国内用户可以配置代理或使用兼容模型
# 例如 DeepSeek、Qwen 等 OpenAI 兼容接口均可
4. Hello World:最简单的 Graph
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
# 1️⃣ 定义状态结构
class MyState(TypedDict):
message: str
result: str
# 2️⃣ 定义节点函数(输入 State,返回更新字典)
def greet(state: MyState) -> dict:
name = state["message"]
return {"result": f"你好,{name}!欢迎使用 LangGraph 🎉"}
# 3️⃣ 构建图
builder = StateGraph(MyState)
builder.add_node("greet", greet) # 注册节点
builder.add_edge(START, "greet") # 起始边
builder.add_edge("greet", END) # 终止边
# 4️⃣ 编译图(生成可执行 Runnable)
graph = builder.compile()
# 5️⃣ 运行!
result = graph.invoke({"message": "世界"})
print(result)
输出:
{'message': '世界', 'result': '你好,世界!欢迎使用 LangGraph 🎉'}
💡 关键点:节点函数只返回需要更新的字段,LangGraph 会自动合并到现有 State 中,不会覆盖未修改的字段。
5. 状态管理:让 Agent 有记忆
真实 Agent 需要维护对话历史。LangGraph 通过 Annotated + operator.add 实现消息的追加语义:
from typing import Annotated
import operator
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
class ChatState(TypedDict):
# Annotated + operator.add 表示"列表追加"而非"覆盖"
messages: Annotated[list[BaseMessage], operator.add]
def chat_node(state: ChatState) -> dict:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
response = llm.invoke(state["messages"])
return {"messages": [response]} # 返回列表,自动追加
builder = StateGraph(ChatState)
builder.add_node("chat", chat_node)
builder.add_edge(START, "chat")
builder.add_edge("chat", END)
graph = builder.compile()
# 多轮对话
state = {"messages": [HumanMessage("你好!")]}
state = graph.invoke(state)
state["messages"].append(HumanMessage("刚才我说了什么?"))
state = graph.invoke(state) # 携带完整历史重新调用
⚠️ 注意 reducer 语义:
operator.add对列表执行追加操作。如果你的节点返回{"messages": [new_msg]},新消息会被追加到历史中,而不是替换整个列表——这是 LangGraph 状态更新的核心机制。
6. 条件路由:让 Agent 做决策
条件边是 LangGraph 最强大的功能之一,它让图可以根据当前状态动态选择执行路径:
# 路由函数:返回下一个节点的名称
def should_use_tool(state: ChatState) -> str:
last_msg = state["messages"][-1]
# 如果 LLM 请求调用工具,跳到 tools 节点
if hasattr(last_msg, "tool_calls") and last_msg.tool_calls:
return "tools"
# 否则直接结束
return END
builder.add_conditional_edges(
"agent", # 源节点
should_use_tool, # 路由函数
{ # 路由映射(可选,增加可读性)
"tools": "tools",
END: END
}
)
执行流程:
START → [agent: 调用LLM] → 路由判断
├─ 有工具调用 → [tools: 执行工具] → 循环回 agent
└─ 无工具调用 → END
7. 实战:带工具调用的 ReAct Agent
ReAct(Reason + Act)是目前最流行的 Agent 模式。下面完整实现一个会调用工具的 Agent:
Step 1:定义工具
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
@tool
def search_web(query: str) -> str:
"""在网络上搜索最新信息"""
# 实际使用 Tavily / SerpAPI 等搜索服务
return f"搜索结果:关于 '{query}' 的最新资讯..."
@tool
def calculator(expression: str) -> str:
"""计算数学表达式"""
try:
return str(eval(expression))
except:
return "计算错误"
tools = [search_web, calculator]
llm = ChatOpenAI(model="gpt-4o-mini").bind_tools(tools)
Step 2:定义 Agent 节点和 Tool 节点
from langgraph.prebuilt import ToolNode
def agent_node(state: ChatState) -> dict:
"""LLM 思考并决定是否调用工具"""
response = llm.invoke(state["messages"])
return {"messages": [response]}
# ToolNode 会自动执行所有工具调用并返回 ToolMessage
tool_node = ToolNode(tools)
Step 3:组装图并运行
from langgraph.graph import StateGraph, START, END
def should_continue(state: ChatState) -> str:
last = state["messages"][-1]
if hasattr(last, "tool_calls") and last.tool_calls:
return "tools"
return END
builder = StateGraph(ChatState)
builder.add_node("agent", agent_node)
builder.add_node("tools", tool_node)
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", should_continue)
builder.add_edge("tools", "agent") # 工具结果返回 agent 继续思考
react_agent = builder.compile()
# 运行 Agent
result = react_agent.invoke({
"messages": [HumanMessage("今天 1234 * 5678 等于多少?")]
})
for msg in result["messages"]:
print(f"[{type(msg).__name__}]", msg.content[:100])
运行轨迹:
[HumanMessage] 今天 1234 * 5678 等于多少?
[AIMessage] (调用工具: calculator)
[ToolMessage] 7006652
[AIMessage] 1234 × 5678 = 7,006,652 🎯
8. 人工介入(Human-in-the-loop)
生产级 Agent 通常需要在执行敏感操作前让人类确认。LangGraph 通过 Checkpointer + interrupt 实现:
from langgraph.checkpoint.memory import MemorySaver
# 1️⃣ 添加 checkpointer(内存版,生产用 PostgresSaver / RedisSaver)
memory = MemorySaver()
agent_with_hitl = builder.compile(
checkpointer=memory,
interrupt_before=["tools"] # 在执行工具前暂停!
)
config = {"configurable": {"thread_id": "user-42"}}
# 2️⃣ 第一次 invoke:执行到 tools 节点前暂停
snapshot = agent_with_hitl.invoke(
{"messages": [HumanMessage("搜索最新 AI 新闻")]},
config
)
# 此时 Agent 已暂停,等待人类确认
print("Agent 准备调用工具,请确认...")
print(snapshot["messages"][-1].tool_calls)
# 3️⃣ 人类审核后,传入 None 继续执行
final = agent_with_hitl.invoke(None, config) # 从断点恢复
print(final["messages"][-1].content)
💡 Checkpoint 原理:每次执行前后,LangGraph 都会将完整 State 序列化保存到 Checkpointer 中。
thread_id是会话标识符,允许同一个 Agent 服务多个独立用户,实现真正的多会话持久化。
9. 总结与进阶方向
本文从零开始走了一遍 LangGraph 的核心路径:
已掌握:
- ✅ StateGraph 基本用法
- ✅ 节点 / 边定义
- ✅ 条件路由
- ✅ 多轮对话状态管理
- ✅ 工具调用(ReAct 模式)
- ✅ 人工介入(Human-in-the-loop)
进阶方向:
- 🚀 多 Agent 协作(Supervisor 模式)
- 🚀 子图(Subgraph)拆分复杂逻辑
- 🚀 流式输出(stream / astream)
- 🚀 持久化 Checkpointer(PostgreSQL / Redis)
- 🚀 LangGraph Platform 生产部署
LangGraph 的设计哲学是把复杂性还给开发者:它不替你决定 Agent 应该怎么跑,而是给你一套清晰的原语来精确控制每一个执行步骤。这正是它在生产级 Agent 中越来越受欢迎的原因。
📚 推荐资源:
- 官方文档:langchain-ai.github.io/langgraph
- LangGraph Academy 课程
- GitHub 示例:github.com/langchain-a…