1. 项目概述
如果你正在寻找一个能帮你从零开始,真正搞懂 LangGraph 1.0 并动手构建智能体的实战教程,那么你找对地方了。LangGraph 作为 LangChain 生态中负责工作流编排和状态管理的核心框架,在 2025 年 10 月发布 1.0 稳定版后,已经成为构建复杂、可靠智能体应用的事实标准。但官方文档往往侧重于 API 参考,而社区中的许多教程又停留在 0.x 版本,这让很多开发者,尤其是刚接触智能体开发的同行,感到无从下手。这个名为 “Dive into LangGraph” 的开源项目,正是为了解决这个问题而生。它是一本结构清晰、内容详实、完全基于 LangGraph 1.0 的实战指南,旨在帮助开发者,无论是刚入门的新手还是希望体系化进阶的资深工程师,快速掌握构建生产级智能体所需的核心技能。
这个项目最吸引我的地方在于它的“完整性”和“实战性”。它没有停留在简单的概念介绍,而是将 LangGraph 与 LangChain 的核心功能拆解成 14 个循序渐进的章节,从创建一个最简单的 ReAct 智能体开始,逐步深入到状态图、中间件、记忆系统、人机交互、MCP 集成、监督者模式、并行处理、RAG 乃至最终打包成 Gradio 应用。每一个章节都是一个独立的 Jupyter Notebook,你可以边学边跑,亲眼看到代码如何工作,状态如何流转。更值得一提的是,它现在已经进化成了一个 “Agent Skill”,这意味着你可以直接将它安装到 Claude Code 这类 AI 编程助手中,让它来辅助你写出更地道的 LangGraph 代码,这简直是把“学习”和“实践”无缝衔接了起来。接下来,我将带你深入拆解这个项目的设计思路、核心内容以及如何最高效地利用它来提升你的智能体开发能力。
1.1 核心价值与目标读者
这个教程的核心价值在于它提供了一个“最小可行知识体系”。智能体开发涉及面广,从提示工程、工具调用到工作流编排、状态持久化,知识点非常分散。该项目作者敏锐地抓住了 LangGraph 1.0 稳定发布这个时间窗口,将两个核心库(LangChain 和 LangGraph)中最常用、最关键的功能提炼出来,形成了一条平滑的学习路径。它避免了让你在浩瀚的官方文档中迷失,直接指向了构建一个可用、可扩展智能体所必须掌握的技能。
它主要适合以下几类开发者:
- 智能体开发新手:如果你对 LLM 应用开发有基本了解,但不知道如何将想法组织成可维护、有状态的工作流,这个教程是你的绝佳起点。它会手把手教你搭建第一个智能体。
- 从 LangGraph 旧版本迁移的开发者:1.0 版本在接口和设计理念上相比 0.x 有显著优化。本教程承诺“不含任何 v0.6 的历史残留”,是进行版本迁移和知识更新的可靠参考。
- 寻求最佳实践的进阶开发者:即使你已经用过 LangGraph,教程中关于中间件(预算控制、敏感信息过滤)、记忆系统(短期/长期记忆)、上下文管理(State, Store, Runtime)以及监督者模式的深入讲解,也能帮你优化现有项目结构,提升应用的健壮性和可观测性。
- 希望将智能体产品化的工程师:最后的 Gradio 应用实战章节,展示了如何将一个 LangGraph 工作流封装成带有流式响应的 Web 应用,这对于构建演示原型或最终产品至关重要。
项目的目标非常明确:让你不仅能“看懂” LangGraph,更能“用好” LangGraph,最终具备独立设计和实现复杂智能体工作流的能力。
2. 教程内容深度解析与学习路径
“Dive into LangGraph” 的目录结构设计体现了作者对学习曲线的深刻理解。它不是简单的功能罗列,而是遵循了“由浅入深、从核心到外围”的认知规律。我们可以将 14 个章节划分为四个主要阶段,这构成了一个高效的学习路径。
2.1 第一阶段:核心概念与基础构建(第1-3章)
这一阶段的目标是建立对 LangGraph 最核心抽象——状态图(StateGraph)——的直观理解,并跑通第一个智能体。
- 第1章:快速入门:这一章通常会带你创建一个经典的ReAct(Reasoning + Acting)智能体。ReAct 模式是智能体基础的推理-行动循环。在这里,你会首次接触到如何定义工具(Tool)、如何构建提示模板(PromptTemplate)、如何创建执行器(Graph)。关键是理解
State的定义,它通常是一个 Pydantic 模型,包含了智能体运行过程中所有需要传递和修改的数据,比如对话历史、中间思考过程、工具调用结果等。通过这一章,你能立刻获得一个能运行、能调用简单工具(比如计算器、搜索引擎)的智能体,建立初步的信心。 - 第2章:状态图:这是 LangGraph 的灵魂。本章会深入讲解
StateGraph的构建。你会学习如何定义节点(Node)——即工作流中的具体步骤函数,以及边(Edge)——决定工作流走向的条件逻辑。重点是理解“状态”如何在节点间流动和更新。例如,一个节点处理用户问题,下一个节点决定调用哪个工具,再下一个节点解析工具返回结果。你会接触到add_node,add_edge,add_conditional_edges等核心方法,并理解如何通过compile()方法将图编译成可执行的对象。 - 第3章:中间件:在掌握了基础工作流后,本章引入中间件(Middleware)的概念,这是实现生产级应用的关键。中间件允许你在工作流执行的生命周期(如节点执行前、后,或整个流程开始、结束时)注入自定义逻辑。教程实战了四个非常实用的功能:
- 预算控制:限制智能体单次对话的最大 Token 消耗或 API 调用次数,防止成本失控。
- 消息截断:当对话历史过长时,自动截断或总结,确保不超出模型上下文窗口。
- 敏感词过滤:在输入或输出层过滤不当内容,满足合规要求。
- PII(个人身份信息)检测:自动检测并脱敏用户输入中的电话号码、邮箱等信息,保护隐私。
注意:中间件的学习是区分“玩具项目”和“严肃项目”的重要一步。在早期就养成使用中间件处理通用横切关注点(如日志、监控、鉴权)的习惯,能让你的代码更清晰、更健壮。
2.2 第二阶段:高级功能与状态管理(第4-8章)
在打好基础后,这一阶段开始探索如何让智能体更智能、更可控、更易集成。
- 第4章:人机交互:智能体不是全自动的,有时需要人类介入做出关键决策。本章介绍如何使用内置的HITL(Human-In-The-Loop)中间件。例如,当智能体试图执行一个高风险操作(如发送邮件、修改数据库)时,工作流可以暂停,并通过一个预设的通道(如 Slack、钉钉机器人或简单的 CLI 输入)向人类操作员发送审批请求,待批准后再继续执行。这为智能体在关键业务场景中的应用提供了安全阀。
- 第5章:记忆:没有记忆的智能体,每次对话都是全新的开始。本章深入讲解 LangGraph 如何管理短期记忆和长期记忆。
- 短期记忆:通常指单次对话轮次中的上下文,由
State对象管理。 - 长期记忆:涉及持久化存储,教程会介绍如何使用
langgraph-checkpoint系列库(如 SQLite, Redis)来保存和加载对话状态。这使得智能体能在多次会话中记住用户偏好、历史任务上下文,实现真正的持续性对话。
- 短期记忆:通常指单次对话轮次中的上下文,由
- 第6章:上下文工程:这是对状态管理的进阶探讨。除了基础的
State,LangGraph 还提供了Store(用于存储全局、共享的只读数据)和Runtime上下文(提供执行环境信息)。合理使用这三者,可以优雅地管理配置、工具集、数据库连接等资源,避免在State中传递一切导致的臃肿和混乱。 - 第7章:MCP Server:MCP(Model Context Protocol)是 LangChain 生态中一个重要的开放协议,用于标准化工具、知识库等资源的接入。本章教你如何创建一个自定义的 MCP Server(例如,一个连接公司内部知识库的服务器),并将其无缝接入 LangGraph 智能体。这极大地扩展了智能体的能力边界,使其能够安全、规范地使用任何通过 MCP 暴露的资源。
- 第8章:监督者模式:当任务复杂时,单一智能体可能力不从心。监督者模式采用“管理者-工作者”的架构。本章介绍两种实现方式:
- 基于 Tool Calling 的监督者:一个主智能体(监督者)将子任务分解,并通过调用“工具”的方式,将任务分配给专门化的子智能体(工作者)去执行。
- 使用
langgraph-supervisor库:这是更官方、更强大的方式。它提供了专门的Supervisor节点类型,可以更方便地管理多个子工作流(Sub-graph)的创建、执行和结果汇总,非常适合实现复杂的多智能体协作系统。
2.3 第三阶段:性能优化与核心应用(第9-11章)
这一阶段关注如何提升智能体的性能和解决两类核心应用场景:知识问答和实时信息获取。
- 第9章:并行:为了提高效率,需要让智能体并行工作。本章讲解四种并发模式:
- 节点并发:在定义图时,让多个无依赖关系的节点同时执行。
@task装饰器:将一个普通的 Python 函数标记为可异步执行的任务。- Map-reduce:经典的大任务分解模式。将一个大型查询映射(Map)到多个并行处理的子任务上,然后将所有子结果归约(Reduce)成一个最终答案。
- 子图:将复杂的图分解成多个可复用的子图,子图内部可以有自己的并发逻辑,主图通过调用子图来组织更宏观的并行流程。
- 第10章:RAG:检索增强生成是当前 LLM 应用的核心范式。本章不满足于一种方法,而是展示了三种检索策略的实现:
- 向量检索:最主流的方式,使用嵌入模型将文档和查询转换为向量,通过相似度计算找到最相关的片段。会涉及文档加载、切分、向量化存储(如使用 Chroma, Pinecone)和查询的全流程。
- 关键词检索:传统但快速有效的方法,例如使用 TF-IDF 或 BM25 算法。在文档结构清晰或需要精确匹配时非常有用。
- 混合检索:结合向量检索和关键词检索的优点,先通过关键词快速筛选出一个候选集,再用向量检索进行精排,在精度和速度间取得平衡。
- 第11章:网络搜索:让智能体“联网”获取最新信息。本章介绍了集成三个搜索工具的方法:
- DashScope:阿里云的通义千问模型服务平台提供的搜索能力。
- Tavily:一个专为 AI 优化的搜索 API,返回的结果已经过针对 LLM 的优化和总结。
- DDGS:DuckDuckGo 搜索的 Python 库,提供免费、匿名的搜索服务。 每种方式都会讲解如何将其封装成 LangChain Tool,并集成到 LangGraph 工作流中,让智能体能够回答关于实时事件的问题。
2.4 第四阶段:应用落地与生态拓展(第12-14章)
最后阶段着眼于如何将所学投入实际应用,并了解更前沿的生态。
- 第12章:Deep Agents:这是一个对 LangChain 旗下更高级框架Deep Agents的简要介绍。Deep Agents 在 LangGraph 基础上,进一步抽象,旨在让智能体具备更复杂的规划、反思和从失败中学习的能力。本章为你打开一扇窗,指明更深入的学习方向。
- 第13章:Gradio APP:这是从代码到产品的关键一步。本章完整演示了如何将一个训练好的 LangGraph 智能体工作流,封装成一个带有 Web 界面的、支持流式输出(打字机效果)的应用程序。你会学习到如何使用 Gradio 的
ChatInterface,如何将 LangGraph 的流式响应适配到 Gradio 的事件循环中。这个实战章节提供的代码可以直接运行和二次开发,是你构建演示原型或轻量级产品的绝佳模板。 - 第14章:附录:调试页面:工欲善其事,必先利其器。
langgraph-cli提供的开发服务器和调试页面是一个强大的可视化工具。本章教你如何使用langgraph dev命令启动本地调试环境。在这个页面里,你可以清晰地看到工作流的执行图谱、每一步的状态变化、输入输出,甚至可以直接编辑状态并重新执行某个节点,这对于开发和排查复杂工作流中的问题至关重要。
3. 从学习到实践:如何高效使用本教程
拥有了一份优秀的地图,还需要正确的行走方法。下面我结合自己的学习经验,分享如何最高效地利用这个项目,并将其转化为你自己的开发能力。
3.1 环境准备与工具链搭建
教程的requirements.txt文件已经列出了所有依赖。我建议的实践环境如下:
Python 环境:使用 Python 3.10 或以上版本。强烈推荐使用Conda或venv创建独立的虚拟环境,避免包冲突。
# 使用 conda conda create -n langgraph-tutorial python=3.10 conda activate langgraph-tutorial # 或使用 venv python -m venv venv # Windows: .\venv\Scripts\activate # Linux/Mac: source venv/bin/activate安装依赖:克隆项目后,直接安装。
git clone https://github.com/luochang212/dive-into-langgraph.git cd dive-into-langgraph pip install -r requirements.txt实操心得:如果安装缓慢或遇到网络问题,可以临时使用国内镜像源,如
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple。另外,langchain[openai]这个 extras 声明会安装 OpenAI 相关的依赖,如果你计划使用其他模型(如通义千问、智谱GLM),可以先安装基础版langchain-core,langchain,再单独安装对应的社区集成包。开发工具:
- Jupyter Lab / VS Code:教程本身是
.ipynb文件,用 Jupyter Lab 打开学习是最直观的。VS Code 配合 Jupyter 插件也有很好的体验,方便做笔记和调试。 - LangGraph CLI:确保
langgraph-cli安装成功,后续的调试页面依赖它。 - API 密钥:准备你需要的 API 密钥(如 OpenAI, DashScope, Tavily),并在项目根目录创建
.env文件进行配置,例如:OPENAI_API_KEY=sk-... DASHSCOPE_API_KEY=sk-... TAVILY_API_KEY=tvly-...
- Jupyter Lab / VS Code:教程本身是
3.2 学习方法论:动手、修改、调试
不要仅仅阅读代码,一定要动手运行。
- 顺序推进,逐章运行:严格按照 1 到 14 章的顺序学习。每一章都是一个完整的、可运行的例子。确保你理解了前一章的核心概念(尤其是
State和StateGraph)再进入下一章。 - 修改参数,观察变化:在成功运行示例后,尝试修改代码。例如:
- 修改
State模型,增加或减少一个字段,看看图如何运行。 - 在中间件章节,调整预算控制的阈值,触发限制看看效果。
- 在 RAG 章节,换用自己的文档,体验不同的检索效果。
- 在 Gradio 章节,修改 UI 布局或添加新的功能按钮。
- 修改
- 善用调试页面:从第 2 章开始,就可以在代码中启动调试页面。在关键节点设置检查点,然后在浏览器中打开
http://localhost:2024,可视化地跟踪状态流转。这是理解复杂工作流不可替代的工具。 - 结合 Agent Skill 学习:这是本教程的一大特色。按照说明,使用
npx skills add ...命令将这个教程安装为 Claude Code 的 Skill。之后,当你在编写 LangGraph 相关代码时,可以直接向 Claude Code 提问,比如“如何为我的智能体添加一个记忆功能?”或“这个中间件怎么写?”,它会参考本教程的内容给出更精准、更地道的代码建议,实现“学以致用,用以促学”的闭环。
3.3 构建你自己的第一个项目
在完成前 6 章的学习后,你就可以尝试脱离教程,构建一个自己的小项目了。我建议从一个具体的、有明确目标的场景开始:
项目构思:一个“旅行规划助手”智能体。
- 定义 State:包含
destination(目的地)、dates(日期)、interests(兴趣列表)、conversation_history(对话历史)、research_results(网络搜索的结果)、itinerary(最终生成的行程草案)。 - 设计工作流:
- 节点1:信息收集:与用户对话,澄清目的地、日期、兴趣偏好。
- 条件边:如果信息不完整,循环回节点1;如果完整,进入节点2。
- 节点2:网络研究:调用 Tavily 或 DDGS 工具,搜索目的地的景点、美食、天气、注意事项。
- 节点3:行程生成:将收集到的信息和研究结果,发送给 LLM,生成一份初步的每日行程安排。
- 节点4:人机确认(可选,使用 HITL):将生成的行程发送给用户确认或修改。
- 节点5:最终输出:格式化输出最终行程。
- 添加增强功能:
- 中间件:为节点2(网络搜索)添加预算控制,防止搜索过于昂贵。
- 记忆:使用 SQLite Checkpoint,让用户下次可以接着说“帮我修改一下上次的行程”。
- RAG(进阶):如果你有自己的旅行攻略文档库,可以增加一个 RAG 节点,在生成行程前先检索内部知识。
通过这样一个完整的项目实践,你会把分散的知识点串联起来,深刻理解 LangGraph 各个模块是如何协同工作的。
4. 常见问题与避坑指南实录
在实际学习和开发中,你肯定会遇到各种问题。下面我整理了一些常见坑点及其解决方案,这些在官方文档里不一定找得到。
4.1 状态(State)设计不当
这是新手最容易出错的地方。
- 问题:
State模型设计得过于庞大或混乱,所有数据都往里塞,导致节点函数参数冗长,且难以维护。 - 解决方案:遵循“最小化”和“结构化”原则。
- 只将需要在节点间流动和改变的数据放入
State。 - 对于全局配置、工具实例、数据库连接等,使用
Store或通过图的构造参数传入。 - 使用嵌套的 Pydantic 模型来组织复杂状态。例如,可以将所有和用户相关的字段放在一个
UserContext子模型里,所有和任务相关的放在TaskContext里。
from pydantic import BaseModel, Field from typing import List, Optional class UserContext(BaseModel): user_id: str preferences: dict = Field(default_factory=dict) class TaskContext(BaseModel): query: str research_materials: List[str] = Field(default_factory=list) answer: Optional[str] = None class AgentState(BaseModel): user: UserContext task: TaskContext conversation: List[dict] = Field(default_factory=list) # 在节点中,可以清晰地访问 state.user.user_id 或 state.task.query - 只将需要在节点间流动和改变的数据放入
4.2 图编译与执行错误
- 问题:在调用
graph.compile()或graph.invoke()时,出现ValidationError或键错误。 - 排查思路:
- 检查 State 模型默认值:确保
State中所有字段都有合理的默认值(使用Field(default_factory=...))或标记为Optional。因为工作流初始调用时,传入的是一个空字典,Pydantic 会用它来初始化State对象。 - 检查节点函数的输入输出:每个节点函数接收的第一个参数是当前的
State对象,它必须返回一个字典,用于更新(update)状态,而不是替换状态。常见的错误是返回了整个新的 State 对象。# 正确:返回要更新的字段字典 def research_node(state: AgentState): result = do_search(state.task.query) return {"task": {"research_materials": result}} # 更新嵌套字段 # 错误:返回了新的State实例或错误的键 def research_node_wrong(state: AgentState): result = do_search(state.task.query) state.task.research_materials = result return state # 错误!应该返回字典。 # 或者 return {"research_materials": result} # 错误!键与State结构不匹配。 - 使用调试页面:在
langgraph dev模式下,错误信息通常会更有帮助,并且你可以看到执行到哪一步失败了。
- 检查 State 模型默认值:确保
4.3 流式输出与 Gradio 集成问题
- 问题:在 Gradio 应用中,无法正常显示 LangGraph 的流式输出(即一个字一个字出现的效果)。
- 解决方案:关键在于正确处理 LangGraph 的异步迭代器。LangGraph 的
graph.astream()或graph.astream_events()返回的是异步生成器。import gradio as gr from langgraph.graph import StateGraph async def predict(message, history): # history 是 Gradio 的格式,需要转换成你的 State 格式 inputs = {"conversation": history, "query": message} full_response = "" async for event in graph.astream(inputs, stream_mode="values"): # 假设我们只关心名为“final_node”的输出 if "final_node" in event and "answer" in event["final_node"]: token = event["final_node"]["answer"] full_response += token yield full_response # 这是实现流式的关键:持续 yield 部分结果注意:确保你的 Gradio
ChatInterface的fn是一个异步函数,并且使用了yield。同时,检查 LangGraph 图中对应最终输出的节点,其返回的字典是否包含了逐步生成的 token。
4.4 记忆(Checkpoint)不生效
- 问题:配置了 SQLite 或 Redis Checkpoint,但智能体似乎并没有记住上次的对话。
- 排查步骤:
- 线程/进程标识:Checkpoint 通过
configurable参数中的thread_id来区分不同的对话会话。确保在每次属于同一会话的graph.invoke()调用中,传入了相同的thread_id。config = {"configurable": {"thread_id": "user_123_session_1"}} result1 = graph.invoke(inputs, config=config) # 下一次调用,使用相同的 thread_id 才能加载上次的状态 result2 = graph.invoke(new_inputs, config=config) - 检查点配置:确保在创建图时正确配置了检查点。
from langgraph.checkpoint.sqlite import SqliteSaver memory = SqliteSaver.from_conn_string(":memory:") # 或文件路径 graph = StateGraph(AgentState) # ... 添加节点和边 ... app = graph.compile(checkpointer=memory) # 关键:传入 checkpointer - 状态序列化:确保你的
State模型中所有字段都是可 JSON 序列化的。自定义类或复杂的 Python 对象可能导致保存失败。
- 线程/进程标识:Checkpoint 通过
4.5 工具调用(Tool Calling)失败
- 问题:智能体决定调用工具,但工具执行失败或返回意外结果。
- 调试方法:
- 启用详细日志:在代码开头设置
import logging; logging.basicConfig(level=logging.DEBUG),查看 LangChain 和 OpenAI 的详细通信日志。 - 检查工具 Schema:确保你传递给 LLM 的工具描述(
name,description,args_schema)是清晰、准确的。模糊的描述会导致模型错误理解工具用途。 - 验证工具函数:单独测试你的工具函数,确保其能处理各种边界情况,并返回结构化的、字符串化的结果。LLM 需要解析这个结果。
- 使用
langgraph-cli调试页面:在调试页面中,你可以清晰地看到模型决定调用哪个工具、传递了什么参数、工具返回了什么,这是定位问题最直观的方式。
- 启用详细日志:在代码开头设置
遵循这个教程的路径,避开这些常见的坑,你就能相对平滑地掌握 LangGraph 1.0。记住,智能体开发是一个迭代和实践的过程,多动手、多思考、多参考这个项目提供的范例,你会逐渐建立起构建复杂 AI 应用的自信和能力。这个项目最大的贡献,就是为你铺平了从理论到实践的那段最难走的路。