第 1 章:LangGraph 框架概览
第 1 章:LangGraph 框架概览
本笔记面向 AI 开发工程师、架构师及对 AI 智能体感兴趣的技术爱好者阅读。
在构建复杂的智能体应用时,我们经常面临多轮对话、状态管理、工作流程控制等挑战。传统的线性处理方式往往难以胜任这些复杂场景。
LangGraph 是基于 LangChain 生态的智能体框架,采用图架构设计,将智能体的工作流程抽象为由节点和边构成的有向循环图。这种架构为构建状态化、可循环的智能体系统提供了强大的支持。
本章将通过手工构建 ReAct 智能体的完整示例,帮助您理解 LangGraph 的核心概念和实际应用。
LangGraph 简介
LangGraph 的核心创新在于其采用了图架构来设计智能体的工作流程。这种架构与传统的线性流程或树状结构截然不同,LangGraph 将智能体执行任务的过程,抽象为一个由节点(Node)和边(Edge)构成的有向循环图(Directed Cyclic Graph)。
🔧 核心组件
节点(Node)类型
-
• LLM 调用节点: 负责与大型语言模型进行交互,执行推理任务
-
• 工具调用节点: 允许智能体调用外部工具或 API,扩展能力边界
-
• 自定义函数节点: 封装业务逻辑或数据处理逻辑
-
• 子图节点: 提高代码模块化和可维护性
边(Edge)类型
-
• 普通边: 定义节点间的直接顺序执行关系
-
• 条件边: 根据状态动态决定工作流程走向
-
• 入口点: 定义工作流程的起始位置
-
• 条件入口点: 根据初始状态动态选择起始节点
状态(State)
状态是 LangGraph 的核心概念,扮演着多重角色:
-
• 上下文信息存储: 记录对话历史、任务进度等
-
• 节点间数据传递: 作为共享的数据容器
-
• 状态持久化: 支持记忆能力和容错恢复
-
• 多智能体共享: 实现智能体间协作
现在让我们通过实际代码来理解这些概念的应用。
🚀 环境准备
首先加载必要的环境变量配置:
from dotenv import load_dotenv
load_dotenv()
LangGraph 与 LangChain 的关系
在深入实践之前,让我们理解 LangGraph 与 LangChain 的关系。
核心架构差异
|
特性 |
LangChain (LCEL) |
LangGraph |
|---|---|---|
| 核心架构 |
链式,有向无环图 (DAG) |
图架构,有向循环图 (DCG) |
| 设计理念 |
简化 LLM 应用开发,线性流程 |
构建复杂、状态化的智能体系统 |
| 状态管理 |
相对简单,短期记忆 |
强大的状态管理和持久化机制 |
| 工作流程 |
线性或分支流程,相对固定 |
循环流程,支持迭代和动态分支 |
| 适用场景 |
简单应用,快速原型开发 |
复杂智能体,多智能体系统 |
协同使用策略
最佳实践是将 LangChain 作为 LangGraph 的“组件库”:
-
• 利用 LangChain 的模型、提示、工具等组件
-
• 在 LangGraph 中组织和编排这些组件
-
• 构建更复杂的工作流程和智能体系统
现在让我们实际构建一个展示这些概念的 ReAct 智能体。
基于 LangGraph 实现 ReAct 模式

为了帮助大家深入理解 LangGraph 框架的图构建过程,并掌握如何从零开始搭建智能体工作流程,我们将通过手工构建图的方式来实现一个工具调用型的 ReAct 模式智能体。
我们将使用 OpenAI 兼容的模型作为示例,构建一个能够使用搜索工具查询天气信息的智能体。与预制 API 不同,这次我们从最基础的 LangGraph 组件开始,一步步构建 ReAct 智能体的工作流程图。
示例 1:定义工具和工具节点
首先导入必要的 LangGraph 和 LangChain 组件,并定义智能体可以使用的工具。
from langchain_openai import ChatOpenAI # 导入 ChatOpenAI,用于使用 OpenAI 的模型
from langchain_core.tools import tool # 导入 tool 装饰器,用于定义工具
from langgraph.graph import END, StateGraph, MessagesState # 导入 LangGraph 图构建核心组件:END, StateGraph, MessagesState
from langgraph.prebuilt import ToolNode # 导入 ToolNode,用于封装工具节点
# 定义工具:search,用于模拟网页搜索,查询天气信息 (与之前的示例相同)
@tool
def search(query: str):
"""Call to surf the web."""
# 这是一个占位符工具,实际应用中需要替换为真正的搜索功能
if "sf" in query.lower() or "san francisco" in query.lower():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tools = [search] # 将 search 工具放入工具列表
tool_node = ToolNode(tools) # 创建 ToolNode 实例,将工具列表封装成 LangGraph 节点
💡 核心概念解析:
在这段代码中,我们定义了 search 工具,并使用 ToolNode 将工具列表封装成一个 LangGraph 节点。
-
•
@tool装饰器:将普通 Python 函数转换为 LangChain 工具 -
•
ToolNode:LangGraph 预置的节点类型,专门用于执行工具调用 -
• 工具的 docstring 作为工具描述提供给 LLM,帮助模型理解何时使用工具
示例 2:初始化模型并绑定工具
初始化语言模型,并将其配置为能够调用工具。
# 初始化语言模型,使用 Qwen/Qwen3-8B 模型,并绑定工具
model = ChatOpenAI(model="Qwen/Qwen3-8B", temperature=0).bind_tools(tools)
💡 关键概念:
bind_tools(tools) 方法至关重要。它将我们定义的工具列表绑定到 ChatOpenAI 模型上,使得模型知道它有哪些工具可以使用,以及如何调用这些工具。只有绑定了工具的模型,才能在后续的推理过程中生成工具调用指令。
示例 3:创建状态结构体
创建 StateGraph 实例,指定状态类型。
# 定义状态类型为 MessageState,用于处理消息列表
workflow = StateGraph(MessagesState)
💡 StateGraph 核心概念:
-
•
StateGraph:LangGraph 中用于构建和管理图的核心类 -
•
MessagesState:LangGraph 预置的状态类型,专门用于处理消息列表,非常适合构建对话型智能体 -
• 状态作为"记忆库",用于存储和传递信息,在不同节点间共享数据
示例 4 & 5:添加节点
向图中添加两个核心节点:
-
1. "agent" 节点:负责调用语言模型进行推理
-
2. "tools" 节点:负责执行工具调用
# 定义 agent 节点的执行函数:call_model
def call_model(state):
messages = state['messages'] # 从状态中获取消息列表
response = model.invoke(messages) # 调用语言模型 model 进行推理,输入为消息列表
return {"messages": [response]} # 将模型响应消息封装成字典返回,键为 "messages",值为包含响应消息的列表
# 将 call_model 函数添加到图中,并命名为 "agent" 节点
workflow.add_node("agent", call_model)
# 将之前创建的 tool_node 实例添加到图中,并命名为 "tools" 节点
workflow.add_node("tools", tool_node)
💡 节点设计原理:
-
•
call_model函数:节点的执行函数,接收状态作为输入,返回状态更新 -
• 返回格式:必须是字典形式
{"messages": [response]},用于更新 LangGraph 状态 -
• 双节点架构:Agent 负责推理决策,Tools 负责行动执行,形成 ReAct 循环的基础
示例 6:设置图的入口点
定义工作流程的起始节点。
# 设置图的入口点为 "agent" 节点,表示工作流程从 agent 节点开始执行
workflow.set_entry_point("agent")
示例 7:定义条件判断函数
定义条件判断逻辑,这是 ReAct 模式的核心:根据模型输出决定下一步行动。
# 定义条件判断函数:should_continue,决定下一步执行哪个节点
def should_continue(state):
messages = state['messages'] # 从状态中获取消息列表
last_message = messages[-1] # 获取最后一条消息,即 agent 节点的输出消息
# 如果 agent 节点的输出消息中包含工具调用指令,则流向 "tools" 节点
if last_message.tool_calls:
return "tools"
# 否则,工作流程结束,流向 END
return END
💡 条件路由机制:
should_continue 函数实现了 ReAct 的核心决策逻辑:
-
• 检查最后一条消息是否包含
tool_calls -
• 如果有工具调用,返回 "tools"(继续行动)
-
• 否则返回
END(推理完成,结束流程) -
•
END是 LangGraph 预定义的特殊值,表示工作流程终点
示例 8:添加条件边
添加从 agent 节点出发的条件边,根据条件函数的返回值决定流向。
# 添加条件边:从 "agent" 节点出发,根据 should_continue 函数的返回值,决定流向 "tools" 节点或 END
workflow.add_conditional_edges(
"agent", # 起始节点为 "agent" 节点
should_continue # 条件判断函数为 should_continue
)
示例 9:添加普通边
添加固定的返回路径,从 tools 节点总是返回到 agent 节点。
# 添加普通边:从 "tools" 节点到 "agent" 节点,表示工具调用完成后,总是返回 agent 节点继续推理
workflow.add_edge("tools", 'agent')
💡 边的类型和 ReAct 循环:
-
• 条件边:
add_conditional_edges()实现动态路由,根据运行时状态选择路径 -
• 普通边:
add_edge()创建固定连接,工具执行后总是返回 agent -
• ReAct 循环:这种设计形成了"推理 → 行动 → 推理 → ..."的循环模式
-
• 有向循环图:与传统 DAG 不同,支持循环结构,实现迭代推理
示例 10:编译 LangGraph 图
将构建好的图编译为可执行的 Runnable 对象。
# 编译 LangGraph 图,得到可执行的 app 对象
app = workflow.compile()
示例 11:运行 ReAct 智能体并处理用户查询
测试我们构建的 ReAct 智能体,向其发送用户查询。
# 运行智能体应用 app,处理用户查询 "What is the weather in sf" (旧金山天气)
final_state = app.invoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
# 打印智能体的最后一条回复消息的内容
print(final_state["messages"][-1].content)
🔄 LangGraph 执行流程深度解析
让我们深入分析当运行 app.invoke() 方法时,LangGraph 内部的执行机制:
完整执行步骤
-
初始化阶段:
-
• LangGraph 将输入消息添加到内部状态
-
• 状态传递给入口点节点 "agent"
-
-
Agent 节点执行:
-
•
call_model函数被调用,接收当前状态 -
• 从状态中提取消息列表,传递给语言模型
-
• 模型分析问题,识别需要获取天气信息
-
• 生成包含工具调用指令的 AIMessage
-
-
条件判断阶段:
-
•
should_continue函数检查最后一条消息 -
• 发现
tool_calls存在,返回 "tools" -
• 工作流程路由到 Tools 节点
-
-
Tools 节点执行:
-
• ToolNode 解析工具调用指令
-
• 执行
search("weather in sf")函数 -
• 返回结果:"It's 60 degrees and foggy."
-
• 工具结果被添加到状态中
-
-
循环返回 Agent:
-
• 根据普通边,流程返回 Agent 节点
-
• Agent 接收包含工具结果的完整对话历史
-
• 模型基于工具结果生成最终回答
-
-
流程结束:
-
• 最终回答不包含工具调用
-
•
should_continue返回 END -
• 工作流程完成,返回最终状态
-
ReAct 模式的核心优势
这种设计体现了 LangGraph 相比传统线性流程的关键优势:
-
• 动态决策:根据运行时状态动态选择执行路径
-
• 状态持久化:完整的对话历史在整个流程中保持可用
-
• 循环支持:支持多轮推理-行动循环,直到问题解决
-
• 灵活扩展:易于添加新的工具、节点或修改流程逻辑
📚 本章总结
通过本章的学习,我们深入了解了 LangGraph 框架的核心理念和实际应用。LangGraph 采用有向循环图架构,通过节点、边和状态三个核心组件构建智能体工作流程,相比传统线性流程具有更强的灵活性和表达能力。我们通过手工构建 ReAct 智能体的完整示例,掌握了状态管理、条件路由、循环结构等关键技术,为构建复杂的对话系统、决策型智能体和多智能体协作系统奠定了基础。
在下一章中,我们将深入探讨 LangGraph 的图驱动智能体系统,学习更高级的状态管理和复杂流程控制技巧。
参考文献和资料
-
• LangGraph文档:https://docs.langchain.com/oss/python/langgraph/overview
-
• 《LangGraph实战》
更多推荐
所有评论(0)