目录
- 什么是 LangGraph
- 为什么需要 LangGraph
- LangGraph vs LangChain
- 核心概念
- 环境搭建
- 单智能体:带记忆的 ReAct Agent
- 多智能体:Supervisor 模式
- 多智能体:Swarm 模式
- 实战:多智能体文档问答系统
- 常见问题
- 总结
一、什么是 LangGraph
LangGraph 是 LangChain 生态中用于构建有状态、多步骤智能体的低层编排框架。它由 LangChain 官方开发,专为生产级智能体应用设计。
官方定位:"LangGraph is a low-level orchestration framework for building, managing, and deploying long-running, stateful agents."
1.1 核心特点
特性 说明
图结构编排 用有向图(StateGraph)定义智能体的执行流程
状态管理 通过共享状态在节点间传递数据
循环支持 支持条件分支和循环,实现 ReAct 模式
持久化记忆 内置检查点机制,支持跨会话记忆
人机协作 支持 Human-in-the-Loop,可在执行中中断和恢复
1.2 应用场景
场景 说明
复杂问答系统 需要多步推理和工具调用
多智能体协作 多个专业 Agent 协同完成任务
自动化工作流 需要条件判断和循环的业务流程
长期运行任务 需要持久化状态和断点续传的 Agent
二、为什么需要 LangGraph
2.1 LangChain 的局限
用 LangChain 写 Agent 时,常见的困境是:
· 线性执行:链(Chain)只能线性执行,如果模型发现"工具返回的结果不够,还需要再查一次",线性链路就断了
· 状态管理难:多轮对话的历史存在哪里?需要写大量胶水代码来管理消息列表
· 无法循环:ReAct 模式(思考 → 行动 → 观察)需要循环,但 Chain 不支持循环
2.2 LangGraph 的解决方案
LangGraph 的核心思路是状态图:
· 把整个 Agent 的运行抽象成一张图
· 图上有节点(Node)、有边(Edge)
· 还有一块在所有节点之间流转的公共黑板------状态(State)
三、LangGraph vs LangChain
对比维度 LangChain LangGraph
执行模式 线性链(Chain) 图结构(Graph)
循环支持 ❌ 不支持 ✅ 支持条件循环
状态管理 手动管理 内置 StateGraph
多智能体 需要手写逻辑 内置 Supervisor/Swarm 模式
持久化 基础支持 内置检查点机制
适用场景 简单工作流 复杂、多步骤、有状态 Agent
一句话总结:
"LangChain 负责单次调用,LangGraph 负责把调用串成可循环、可记忆的工作流。"
四、核心概念
4.1 StateGraph(状态图)
StateGraph 是 LangGraph 的图构建器,所有节点共享一个状态对象。
python
from langgraph.graph import StateGraph, MessagesState
from typing import TypedDict, Annotated
from operator import add
# 自定义状态
class CustomState(TypedDict):
messages: Annotated[list, add] # 追加模式
user_name: str # 自定义字段
current_step: str
4.2 节点(Node)
节点是图中的一个执行单元,可以是:
· 模型调用
· 工具执行
· 普通 Python 函数
python
def call_model(state: CustomState) -> dict:
"""Agent 节点:调用大模型"""
response = llm.invoke(state["messages"])
return {"messages": [response]}
4.3 边(Edge)
边定义节点之间的连接:
类型 说明 示例
普通边 固定流向 graph.add_edge("tools", "agent")
条件边 动态选择去向 graph.add_conditional_edges("agent", should_continue)
起始边 设置入口 graph.add_edge(START, "agent")
4.4 检查点(Checkpoint)
检查点机制让 Agent 拥有跨轮次记忆:
python
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
app = workflow.compile(checkpointer=checkpointer)
# 使用 thread_id 隔离不同会话的记忆
config = {"configurable": {"thread_id": "user_123"}}
result = app.invoke({"messages": [HumanMessage("你好")]}, config)
五、环境搭建
5.1 安装依赖
bash
pip install langgraph langchain langchain-openai python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple
5.2 配置 API Key
创建 .env 文件:
bash
DASHSCOPE_API_KEY="你的阿里云百炼API Key"
DASHSCOPE_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
5.3 引入阿里云百炼模型
python
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
load_dotenv()
# 使用阿里云百炼的通义千问模型
llm = ChatOpenAI(
model="qwen3-max",
temperature=0,
openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)
六、单智能体:带记忆的 ReAct Agent
6.1 完整代码
python
"""
LangGraph 入门:带记忆的 ReAct Agent(阿里云百炼版)
功能:根据用户问题,自动判断是否需要调用工具
"""
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.tools import tool
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import InMemorySaver
from langchain_core.messages import HumanMessage
load_dotenv()
# ========== 1. 初始化阿里云百炼模型 ==========
llm = ChatOpenAI(
model="qwen3-max",
temperature=0,
openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)
# ========== 2. 定义工具 ==========
@tool
def search(query: str) -> str:
"""模拟搜索工具,返回搜索结果"""
if "上海" in query or "Shanghai" in query:
return "上海今天天气:晴,25°C,空气质量良好"
elif "北京" in query or "Beijing" in query:
return "北京今天天气:多云,18°C,空气质量轻度污染"
else:
return f"未找到关于 '{query}' 的信息"
@tool
def calculator(expression: str) -> str:
"""计算数学表达式"""
try:
# 安全的 eval,只允许基本运算
result = eval(expression, {"__builtins__": {}})
return f"计算结果:{result}"
except Exception:
return "计算错误,请检查表达式"
tools = [search, calculator]
tool_node = ToolNode(tools)
# 将工具绑定到模型
llm_with_tools = llm.bind_tools(tools)
# ========== 3. 定义节点函数 ==========
def call_model(state: MessagesState):
"""Agent 节点:调用模型"""
messages = state["messages"]
response = llm_with_tools.invoke(messages)
return {"messages": [response]}
def should_continue(state: MessagesState):
"""条件判断:是否需要调用工具"""
messages = state["messages"]
last_message = messages[-1]
# 如果模型调用了工具,则进入 tools 节点
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
# 否则结束
return END
# ========== 4. 构建状态图 ==========
workflow = StateGraph(MessagesState)
# 添加节点
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)
# 添加边
workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")
# ========== 5. 编译并添加记忆 ==========
checkpointer = InMemorySaver()
app = workflow.compile(checkpointer=checkpointer)
# ========== 6. 运行测试 ==========
if __name__ == "__main__":
config = {"configurable": {"thread_id": "test_user"}}
print("=" * 50)
print("单智能体 ReAct Agent 测试(阿里云百炼)")
print("=" * 50)
# 第一轮:天气查询
print("\n第1轮对话")
print("用户:上海的天气怎么样?")
result = app.invoke(
{"messages": [HumanMessage(content="上海的天气怎么样?")]},
config=config
)
print(f"AI:{result['messages'][-1].content}")
# 第二轮:测试记忆
print("\n第2轮对话(测试记忆)")
print("用户:我问的是哪个城市?")
result = app.invoke(
{"messages": [HumanMessage(content="我问的是哪个城市?")]},
config=config
)
print(f"AI:{result['messages'][-1].content}")
# 第三轮:数学计算
print("\n第3轮对话")
print("用户:计算 123 * 456")
result = app.invoke(
{"messages": [HumanMessage(content="计算 123 * 456")]},
config=config
)
print(f"AI:{result['messages'][-1].content}")
6.2 代码解析
组件 作用 说明
ChatOpenAI 模型调用 配置阿里云百炼 API
@tool 定义工具 装饰普通函数为可调用工具
bind_tools 绑定工具 将工具绑定到模型
ToolNode 工具节点 LangGraph 内置,自动执行工具调用
MessagesState 状态模式 内置状态,包含 messages 字段
StateGraph 图构建器 创建状态图
InMemorySaver 检查点 保存状态,实现记忆
七、多智能体:Supervisor 模式
Supervisor 模式是层级式多智能体架构,由一个中央监督者协调多个专业智能体。
7.1 架构图
┌─────────────────────────────────────────────────────────┐
│ Supervisor Agent │
│ (中央调度者) │
│ │
│ 接收用户任务 → 判断任务类型 → 分配给对应智能体 │
└─────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Research │ │ Math │ │ Writing │
│ Agent │ │ Agent │ │ Agent │
│ (研究专家) │ │ (数学专家) │ │ (写作专家) │
└────────────┘ └────────────┘ └────────────┘
7.2 完整代码
python
"""
LangGraph 多智能体:Supervisor 模式(阿里云百炼版)
功能:一个监督者协调多个专业智能体
"""
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END, START
from typing import TypedDict, Literal, Annotated
from langchain_core.messages import AnyMessage, HumanMessage, AIMessage
from operator import add
load_dotenv()
# ========== 1. 初始化阿里云百炼模型 ==========
llm = ChatOpenAI(
model="qwen3-max",
temperature=0,
openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)
# ========== 2. 定义专业智能体 ==========
def research_agent(state: dict) -> dict:
"""研究专家:负责信息检索和知识整理"""
messages = state["messages"]
last_message = messages[-1].content if messages else ""
response = llm.invoke(f"作为研究专家,请回答:{last_message}")
return {"messages": [AIMessage(content=response.content)]}
def math_agent(state: dict) -> dict:
"""数学专家:负责计算和数学推理"""
messages = state["messages"]
last_message = messages[-1].content if messages else ""
response = llm.invoke(f"作为数学专家,请解决数学问题:{last_message}")
return {"messages": [AIMessage(content=response.content)]}
def writing_agent(state: dict) -> dict:
"""写作专家:负责润色、总结和创作"""
messages = state["messages"]
last_message = messages[-1].content if messages else ""
response = llm.invoke(f"作为写作专家,请优化或总结以下内容:{last_message}")
return {"messages": [AIMessage(content=response.content)]}
# ========== 3. 定义监督者 ==========
def supervisor(state: dict) -> dict:
"""监督者:分析任务并决定使用哪个智能体"""
messages = state["messages"]
last_message = messages[-1].content if messages else ""
# 智能体选择提示词
prompt = f"""
分析用户的问题,选择最合适的专业智能体来处理。
用户问题:{last_message}
可选智能体:
- research:研究专家,负责信息检索、查找资料、回答问题
- math:数学专家,负责计算、数学推理
- writing:写作专家,负责润色、总结、创作
只输出智能体名称,不要输出其他内容。
"""
response = llm.invoke(prompt)
next_agent = response.content.strip().lower()
# 验证返回的智能体名称是否有效
if next_agent not in ["research", "math", "writing"]:
next_agent = "writing" # 默认使用写作专家
return {"next": next_agent, "messages": messages}
def router(state: dict) -> Literal["research", "math", "writing", "finish"]:
"""路由函数:根据监督者决策跳转"""
next_agent = state.get("next", "finish")
if next_agent in ["research", "math", "writing"]:
return next_agent
return "finish"
def finish_agent(state: dict) -> dict:
"""结束节点:汇总最终结果"""
messages = state["messages"]
return {"messages": messages}
# ========== 4. 构建多智能体图 ==========
class MultiAgentState(TypedDict):
messages: Annotated[list[AnyMessage], add]
next: str
workflow = StateGraph(MultiAgentState)
# 添加节点
workflow.add_node("supervisor", supervisor)
workflow.add_node("research", research_agent)
workflow.add_node("math", math_agent)
workflow.add_node("writing", writing_agent)
workflow.add_node("finish", finish_agent)
# 添加边
workflow.add_edge(START, "supervisor")
workflow.add_conditional_edges("supervisor", router)
workflow.add_edge("research", END)
workflow.add_edge("math", END)
workflow.add_edge("writing", END)
app = workflow.compile()
# ========== 5. 运行测试 ==========
if __name__ == "__main__":
print("=" * 50)
print("多智能体 Supervisor 模式测试(阿里云百炼)")
print("=" * 50)
test_questions = [
"帮我搜索关于人工智能的最新发展",
"计算 25 + 17 等于多少?",
"请润色这句话:今天天气很好,我很开心"
]
for q in test_questions:
print(f"\n用户:{q}")
result = app.invoke({"messages": [HumanMessage(content=q)]})
print(f"AI:{result['messages'][-1].content}")
八、实战:多智能体文档问答系统(RAG + Agent)
8.1 系统架构
用户输入问题
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 监督者(Supervisor) │
│ 判断问题类型,分配任务 │
└─────────────────────────────────────────────────────────────┘
│
├──────────┬──────────┬──────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 检索专家 │ │ 推理专家 │ │ 代码专家 │ │ 总结专家 │
│ 查找文档 │ │ 逻辑推理 │ │ 代码生成 │ │ 结果整理 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
8.2 完整代码
python
"""
多智能体文档问答系统(阿里云百炼版 + RAG)
功能:检索 + 推理 + 代码 + 总结 多智能体协作
"""
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langgraph.graph import StateGraph, END, START
from typing import TypedDict, List
from langchain_core.messages import HumanMessage
load_dotenv()
# ========== 1. 初始化阿里云百炼模型 ==========
llm = ChatOpenAI(
model="qwen3-max",
temperature=0,
openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
openai_api_base=os.getenv("DASHSCOPE_BASE_URL"),
)
# ========== 2. 初始化 RAG 向量数据库 ==========
def init_rag():
"""初始化 RAG 检索系统"""
# 创建示例文档
sample_docs = [
"LangGraph 是 LangChain 团队开发的用于构建有状态多智能体应用的框架。",
"LangGraph 基于图结构,支持循环和条件分支,适合构建 ReAct Agent。",
"LangGraph 内置检查点机制,可以实现跨会话的对话记忆。",
"Supervisor 模式是多智能体架构的一种,由一个中央监督者协调多个专业智能体。",
]
with open("temp_docs.txt", "w", encoding="utf-8") as f:
f.write("\n".join(sample_docs))
loader = TextLoader("temp_docs.txt", encoding="utf-8")
docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
chunks = text_splitter.split_documents(docs)
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)
vectorstore = Chroma.from_documents(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
os.remove("temp_docs.txt")
return retriever
retriever = init_rag()
# ========== 3. 定义系统状态 ==========
class RAGState(TypedDict):
question: str
retrieved_context: str
reasoning_result: str
code_result: str
final_answer: str
next_agent: str
# ========== 4. 定义专业智能体 ==========
def retrieval_agent(state: RAGState) -> dict:
"""检索专家:根据问题检索相关文档"""
question = state["question"]
print(f"\n📚 检索专家:正在搜索相关信息...")
docs = retriever.invoke(question)
context = "\n".join([doc.page_content for doc in docs])
return {"retrieved_context": context, "next_agent": "reasoning"}
def reasoning_agent(state: RAGState) -> dict:
"""推理专家:基于检索结果进行逻辑推理"""
question = state["question"]
context = state.get("retrieved_context", "")
prompt = f"""
基于以下文档内容,回答问题。
文档内容:
{context}
问题:{question}
请给出准确、简洁的回答。
"""
response = llm.invoke(prompt)
return {"reasoning_result": response.content, "next_agent": "code"}
def code_agent(state: RAGState) -> dict:
"""代码专家:生成相关代码示例(如果需要)"""
question = state["question"]
reasoning = state.get("reasoning_result", "")
# 判断是否需要代码
if "代码" in question or "实现" in question or "写一个" in question:
prompt = f"""
根据问题和推理结果,生成相关的代码示例。
问题:{question}
推理:{reasoning}
只输出代码,不要解释。
"""
response = llm.invoke(prompt)
return {"code_result": response.content, "next_agent": "summary"}
else:
return {"code_result": "", "next_agent": "summary"}
def summary_agent(state: RAGState) -> dict:
"""总结专家:整合所有结果,输出最终答案"""
reasoning = state.get("reasoning_result", "")
code = state.get("code_result", "")
if code:
final = f"{reasoning}\n\n代码示例:\n{code}"
else:
final = reasoning
return {"final_answer": final, "next_agent": "end"}
def end_agent(state: RAGState) -> dict:
"""结束节点"""
return {}
# ========== 5. 构建多智能体图 ==========
def router(state: RAGState) -> str:
"""路由函数"""
return state.get("next_agent", "end")
workflow = StateGraph(RAGState)
# 添加节点
workflow.add_node("retrieval", retrieval_agent)
workflow.add_node("reasoning", reasoning_agent)
workflow.add_node("code", code_agent)
workflow.add_node("summary", summary_agent)
workflow.add_node("end", end_agent)
# 添加边
workflow.add_edge(START, "retrieval")
workflow.add_edge("retrieval", "reasoning")
workflow.add_edge("reasoning", "code")
workflow.add_edge("code", "summary")
workflow.add_conditional_edges("summary", router)
workflow.add_edge("end", END)
app = workflow.compile()
# ========== 6. 运行测试 ==========
if __name__ == "__main__":
print("=" * 50)
print("多智能体文档问答系统测试(阿里云百炼 + RAG)")
print("=" * 50)
test_questions = [
"LangGraph 是什么?",
"LangGraph 支持哪些特性?",
"我想了解 Supervisor 模式,请给出代码示例"
]
for q in test_questions:
print(f"\n用户:{q}")
result = app.invoke({"question": q})
print(f"AI:{result['final_answer']}")
九、常见问题
Q1:LangGraph 和 LangChain 的关系?
LangGraph 是 LangChain 生态的一部分,专门用于构建复杂的多步骤智能体。LangChain 负责单次调用,LangGraph 负责编排调用流程。
Q2:阿里云百炼支持哪些模型用于 LangGraph?
所有支持 Function Calling 的模型都可以:
· qwen3-max:能力最强,推荐用于复杂场景
· qwen3-plus:平衡之选
· qwen3-turbo:速度快,适合简单任务
Q3:如何调试 LangGraph 应用?
python
# 开启调试模式
from langchain.globals import set_debug
set_debug(True)
# 或使用可视化
from IPython.display import Image, display
display(Image(app.get_graph().draw_png()))
Q4:多智能体和单智能体的性能差异?
对比项 单智能体 多智能体
响应速度 快 较慢(多次调用)
复杂任务 效果一般 效果好
调试难度 简单 复杂
适用场景 简单任务 复杂工作流
十、与已有技能的联系
你学过的技能 在 LangGraph 中的应用
LangChain 基础 模型调用、工具定义与之前相同
RAG 可集成到检索智能体节点中
Agent LangGraph 是 Agent 的底层实现框架
阿里云百炼 API 直接用 qwen 系列模型
记忆管理 LangGraph 内置检查点机制
十一、总结
本文完成了 LangGraph 的完整入门:
内容 状态
环境搭建(阿里云百炼) ✅
单智能体 ReAct Agent ✅
多智能体 Supervisor 模式 ✅
多智能体 RAG 问答系统 ✅
核心概念总结:
StateGraph(状态图)
├── Node(节点):执行单元
├── Edge(边):连接方式
├── State(状态):共享数据
└── Checkpoint(检查点):持久化记忆
执行流程:
START → Node1 → Conditional Edge → Node2 → END
↓
(条件判断)
快速开始模板:
python
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import InMemorySaver
# 1. 构建图
workflow = StateGraph(MessagesState)
# 2. 添加节点
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)
# 3. 添加边
workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")
# 4. 编译
app = workflow.compile(checkpointer=InMemorySaver())
# 5. 调用
result = app.invoke({"messages": [HumanMessage("你好")]})