LangGraph 核心概念全解笔记

一、LangGraph 是什么?

LangGraph 是 LangChain 团队官方推出的基于状态机的智能体 (Agent) 开发框架 ,它基于 LangChain 生态构建,专门解决了 LangChain 原生 LCEL 链式调用的核心短板,用来构建有状态、可循环、可持久化、支持复杂分支逻辑的 Agent 工作流。

它的核心设计思想是:以「状态」为核心,用「节点 + 边」的图结构编排工作流,天然支持 Agent 所需的「思考 - 行动 - 反思」循环逻辑,是目前 LangChain 生态中构建生产级 Agent 的官方标准方案。

关键补充:LangGraph 不是替代 LangChain,而是 LangChain 生态的补充。LangChain 提供 LLM、工具、向量库、文档加载器等原子组件,LangGraph 负责这些组件的复杂流程编排、状态管理和持久化,两者通常配合使用。

二、LangGraph 核心概念(逐点详解 + 实战示例)

1. State(状态:LangGraph 的灵魂)

State 是 LangGraph 最核心的概念,它是贯穿整个工作流的全局数据容器,工作流中所有节点的输入都来自 State,节点的输出都会更新 State,整个工作流的执行过程就是 State 不断更新的过程。

核心特性
  • 强类型定义 :通常用 TypedDict 或 Pydantic BaseModel 定义,保证类型安全
  • Reducer 机制 :通过 Annotated 绑定 reducer 函数,定义 State 字段的更新规则,避免手动处理数据合并
  • 全链路共享:所有节点都可以读取 / 更新 State,是节点间通信的唯一载体
实战示例(你正在使用的写法)
复制代码
from typing import TypedDict, Sequence, Annotated
from langchain_core.messages import BaseMessage
from langgraph.graph import add_messages

# 定义State结构
class ReActState(TypedDict):
    # 消息列表:绑定add_messages reducer,自动实现消息追加,无需手动拼接列表
    messages: Annotated[Sequence[BaseMessage], add_messages]
    loop_count: int  # 防死循环计数器
    user_id: str     # 用户ID,绑定长期记忆
    error: str | None  # 错误信息,用于异常处理路由
关键知识点
  • add_messages 是 LangGraph 内置的最常用 reducer,专门处理消息列表的追加,自动去重、合并消息,是多轮对话的核心
  • 节点的返回值只需要包含 State 的子集,不需要返回完整的 State,LangGraph 会自动根据 reducer 规则合并到全局 State 中
  • 你之前踩过的「HumanMessage 没有 tool_calls」的坑,本质就是 State 中 messages 列表的最后一条消息类型判断错误,属于 State 数据的处理问题

2. Node(节点:工作流的执行单元)

Node 是工作流中的具体执行逻辑单元,对应 Agent 中的一个动作(比如 LLM 思考、工具调用、文档检索、反思校验),本质是一个接收 State、返回 State 更新的纯函数。

节点的 3 种核心类型
节点类型 作用 示例
普通自定义节点 实现自定义业务逻辑 LLM 思考节点、文档检索节点、反思校验节点
内置工具节点 ToolNode LangGraph 内置封装,专门处理 LLM 的工具调用 你代码中的 ToolNode(tools),自动解析 AIMessage 中的 tool_calls 并执行工具
子图节点 把一个完整的 LangGraph 图作为节点嵌入到另一个图中 多智能体场景中,把单个 Agent 的工作流封装为子图
实战示例(你正在使用的写法)
复制代码
from langchain_core.messages import AIMessage

# 自定义节点:LLM思考节点
def llm_think(state: ReActState):
    """核心思考节点:加载记忆、调用LLM生成回答/工具调用"""
    messages = state["messages"]
    user_id = state["user_id"]
    error = None

    try:
        # 加载长期记忆
        user_preference = store.get(("user_memory", user_id), "preference")
        if user_preference:
            messages = [HumanMessage(content=f'用户偏好:{user_preference.value}')] + messages
        # 调用LLM
        response = llm.invoke(messages)
    except Exception as e:
        response = AIMessage(content=f"请求失败:{str(e)}")
        error = str(e)

    # 返回State的更新,LangGraph自动合并
    return {
        "messages": [response],
        "loop_count": state["loop_count"] + 1,
        "user_id": user_id,
        "error": error
    }

# 内置工具节点
tool_executor = ToolNode(tools, handle_tool_errors=True)

3. Edge(边:工作流的流程控制器)

Edge 是连接节点的「桥梁」,定义了工作流的执行顺序和分支逻辑,是 LangGraph 实现循环、条件判断、异常降级的核心。

边的 3 种核心类型
边类型 作用 语法
普通边 固定的执行顺序,上一个节点执行完,固定执行下一个节点 builder.add_edge(START, "llm_think")builder.add_edge("tool_executor", "llm_think")
条件边 核心分支逻辑,根据当前 State 的数据,动态决定下一个执行的节点 builder.add_conditional_edges("llm_think", should_continue, 路由映射)
起止边 特殊的固定边,START 代表工作流入口,END 代表工作流结束 builder.add_edge("llm_think", END)
实战示例(你正在使用的写法)
复制代码
from typing import Literal
from langgraph.constants import START, END

# 条件路由函数:接收State,返回下一个节点的名称
def should_continue(state: ReActState) -> Literal["llm_think", "backup_llm_think", "tool_executor", "end"]:
    # 优先处理异常:有错误则走备用LLM节点
    if state.get("error"):
        if state["loop_count"] < 2:
            return "backup_llm_think"
        else:
            return "end"
    
    # 过滤出AI消息,避免HumanMessage没有tool_calls的报错
    ai_messages = [msg for msg in state["messages"] if isinstance(msg, AIMessage)]
    if not ai_messages:
        return "llm_think"
    last_message = ai_messages[-1]
    
    # 正常流程判断:有工具调用则执行工具,否则结束
    if not last_message.tool_calls or state["loop_count"] >= 5:
        return "end"
    return "tool_executor"

# 构建图时绑定条件边
builder = StateGraph(ReActState)
builder.add_node("llm_think", llm_think)
builder.add_node("tool_executor", tool_executor)

# 入口边
builder.add_edge(START, "llm_think")
# 条件边:llm_think执行完后,根据should_continue的返回值路由
builder.add_conditional_edges(
    "llm_think",
    should_continue,
    # 路由映射:函数返回值 → 目标节点
    {
        "backup_llm_think": "backup_llm_think",
        "tool_executor": "tool_executor",
        "end": END
    }
)
# 普通边:工具执行完后,回到llm_think,实现ReAct循环
builder.add_edge("tool_executor", "llm_think")

4. Checkpointer(检查点:持久化与会话恢复)

Checkpointer 是 LangGraph 内置的状态持久化组件,它会在工作流的每一步执行完成后,自动保存 State 的完整快照(Checkpoint),实现会话恢复、断点续跑、历史回溯。

核心能力
  • 会话持久化 :服务重启后,通过 thread_id 恢复之前的对话状态,实现多轮对话不丢失
  • 断点续跑:工作流执行中断后,从断点继续执行,无需从头开始
  • 历史回溯:可以查看工作流每一步的 State 变化,方便调试和问题排查
  • 时间旅行:支持回滚到历史任意一个检查点,重新执行工作流
常用实现
实现类 适用场景 特点
MemorySaver 开发学习、本地测试 内存存储,零配置,重启数据丢失
RedisSaver 生产环境、分布式部署 Redis 持久化,重启不丢数据,支持多实例共享
PostgresSaver 生产环境、企业级部署 数据库持久化,支持事务、数据备份
实战示例(你正在使用的写法)
复制代码
from langgraph.checkpoint.redis import RedisSaver
from langgraph.checkpoint.memory import MemorySaver

# 1. 初始化持久化组件
checkpointer = RedisSaver("redis://localhost:6379/0")
# 开发环境用MemorySaver零配置
# checkpointer = MemorySaver()

# 2. 编译图时绑定checkpointer
react_agent = builder.compile(checkpointer=checkpointer)

# 3. 调用时通过thread_id绑定会话,实现持久化
config = {"configurable": {"thread_id": "session_001", "user_id": "user_001"}}
# 同一个thread_id的调用,会自动恢复之前的State
result = react_agent.invoke({"messages": [HumanMessage(content="你好")]}, config=config)

5. Store(存储:跨会话长期记忆)

Store 是 LangGraph 内置的跨会话全局存储组件,和 Checkpointer 互补:

  • Checkpointer:存储单会话内的工作流状态,生命周期和会话绑定
  • Store:存储跨会话的全局数据,比如用户长期偏好、知识库元数据、全局配置,生命周期和用户 / 业务绑定
核心能力
  • 键值对存储,支持命名空间(namespace),实现数据隔离
  • 原生集成到 LangGraph 工作流中,节点内可以直接读写
  • 支持 Redis、Postgres 等持久化实现
实战示例(你正在使用的写法)
复制代码
from langgraph.store.redis import RedisStore

# 初始化Store
store = RedisStore.from_url("redis://localhost:6379/1")
# 编译图时绑定store
react_agent = builder.compile(checkpointer=checkpointer, store=store)

# 节点内读写Store
def llm_think(state: ReActState):
    user_id = state["user_id"]
    # 读取用户长期记忆
    user_preference = store.get(("user_memory", user_id), "preference")
    # 写入用户长期记忆
    store.put(("user_memory", user_id), "preference", "喜欢用摄氏度,偏好简洁回答")
    ...

6. 其他核心概念

  1. Thread(会话) :通过 thread_id 唯一标识,对应一个独立的工作流执行实例,是 Checkpointer 隔离不同会话的核心标识。
  2. Compilation(编译)builder.compile() 把定义好的图结构,转换成可执行的运行时对象,同时绑定 Checkpointer、Store、中断配置等。
  3. Interrupt(中断):LangGraph 原生支持工作流执行中暂停,等待人工输入 / 审核后继续执行,适合需要人工介入的复杂 Agent 场景。
  4. Stream(流式输出) :支持多种流式模式(valuesupdatesmessages),可以实时输出工作流的每一步执行结果,提升用户体验。

三、LangGraph vs LangChain 深度对比

3.1 核心差异总表

表格

对比维度 LangChain LangGraph
核心设计范式 链式调用(LCEL),线性 DAG(有向无环图) 状态机,图结构,支持有环图
流程控制能力 仅支持线性执行、简单分支,不支持循环 原生支持任意循环、多条件分支、子图嵌套、异常降级
状态管理 无内置全局状态,需要手动传递和管理上下文 内置全局 State,自动管理状态更新、合并、持久化
持久化能力 无原生持久化,需要自己实现会话存储 原生 Checkpointer 机制,一行代码实现会话持久化、断点续跑
Agent 能力 仅支持简单的单轮工具调用,复杂 Agent 需要大量二次开发 原生适配 ReAct、Plan-Execute、多智能体等主流 Agent 范式,是 LangChain 官方 Agent 标准方案
可调试性 链式执行黑盒,难以回溯中间步骤 每一步都有 Checkpoint 快照,可完整回溯工作流的每一步状态变化
人工介入 无原生支持,需要自己实现中断逻辑 原生 Interrupt 机制,支持工作流暂停、人工介入、恢复执行
适用场景 简单线性任务、单轮对话、无状态一次性任务 复杂 Agent、多轮对话、有状态工作流、多智能体协作、需要人工介入的场景
学习曲线 低,简单链式调用上手快 中,需要理解状态机、图结构的核心概念,上限更高

3.2 关键差异详解

  1. 循环支持是核心分水岭 LangChain 的 LCEL 是无环的线性链,天生无法实现 Agent 最核心的「思考→工具调用→再思考」的循环逻辑。而 LangGraph 基于状态机,天然支持循环,这也是 LangChain 官方推出 LangGraph 的核心原因 ------LCEL 根本不适合构建 Agent。

  2. 状态管理的本质区别LangChain 中,上下文需要在链的每个步骤手动传递,多轮对话的状态管理需要自己写代码实现;而 LangGraph 中,State 是全局共享的,所有节点都可以读取和更新,内置的 reducer 机制自动处理数据合并,开发者只需要关注业务逻辑。

  3. 生态定位的互补性LangGraph 不是替代 LangChain,而是扩展了 LangChain 的能力边界。LangChain 提供了海量的组件(LLM 集成、工具、向量库、文档加载器等),LangGraph 负责把这些组件编排成复杂、健壮的 Agent 工作流,两者是「原子组件」和「流程编排框架」的关系。


四、什么时候应该使用 LangGraph?

4.1 优先使用 LangGraph 的 7 大场景

  1. **构建任何类型的智能体 (Agent)**只要你的场景需要 LLM 自主思考、调用工具、多步执行(比如 ReAct 工具调用 Agent、客服 Agent、代码执行 Agent),必须优先用 LangGraph。它原生支持 Agent 的循环逻辑,是 LangChain 官方的标准方案,比自己用 LCEL 封装要简单、健壮得多。

  2. 需要多轮对话、会话持久化的场景比如智能客服、个人知识库问答、陪伴式机器人,需要服务重启后用户的对话历史不丢失,LangGraph 的 Checkpointer 一行代码就能实现会话持久化,无需自己开发状态存储。

  3. 复杂的非线性工作流比如 RAG + 反思重写、文档审核→纠错→二次审核、多步骤分支判断、错误重试 / 降级兜底,这些场景用 LCEL 很难实现,用 LangGraph 的条件边、节点循环可以轻松搞定。

  4. 需要人工介入的场景比如合同审核 Agent 执行到关键步骤需要人工确认、代码生成 Agent 需要人工审核代码后再执行,LangGraph 的 Interrupt 原生支持工作流暂停和恢复,无需自己开发状态暂停机制。

  5. 多智能体协作场景比如产品经理 Agent + 开发 Agent + 测试 Agent 协作完成需求开发,LangGraph 的子图、多节点并行执行可以轻松实现多智能体的分工和协作。

  6. 需要高可观测性、可调试性的生产级应用生产环境中,你需要知道 Agent 每一步做了什么、为什么出错,LangGraph 的 Checkpoint 机制会保存每一步的完整状态,可以完整回溯执行过程,快速定位问题。

  7. 需要断点续跑的长任务场景比如长文档总结、批量数据处理、自动化报告生成,这些长任务如果中途中断,LangGraph 可以从断点继续执行,无需从头开始,节省时间和 Token 成本。

4.2 用 LangChain LCEL 就足够的场景

  1. 简单的线性单轮任务比如文本翻译、文案生成、单轮摘要、简单的单轮 RAG(提问→检索→生成回答),没有循环、没有多轮对话、没有分支逻辑,用 LCEL 一行代码就能实现,无需引入 LangGraph。

  2. 无状态的一次性任务执行一次就结束,不需要保存状态、不需要多轮对话,比如一次性的文档格式转换、数据清洗、单条数据的标签生成。

  3. 快速原型验证想快速验证一个想法的效果,用 LCEL 可以快速搭起一个最简原型,验证通过后,再用 LangGraph 重构为生产级的工作流。


五、LangGraph 最佳实践(结合你的踩坑经验)

  1. State 设计优先先定义好 State 结构,再开发节点和边。State 只保留工作流必须的字段,避免冗余数据;复杂字段一定要绑定 reducer,避免手动处理数据合并出错。

  2. 优先用内置组件 工具调用优先用内置的 ToolNode,消息管理优先用 add_messages reducer,持久化优先用官方的 Saver 实现,不要自己重复造轮子,避免踩坑。

  3. 条件边一定要做边界校验条件路由函数中,一定要对 State 的数据做类型校验和空值判断,比如你之前踩过的「HumanMessage 没有 tool_calls」的坑,就是没有先过滤消息类型导致的。

  4. 开发用 MemorySaver,生产用 Redis/PostgresSaver 开发阶段用 MemorySaver 零配置快速迭代,上线生产环境切换到 Redis/PostgresSaver,保证数据持久化。

  5. 节点职责单一一个节点只做一件事,比如「检索节点」只做文档检索,「生成节点」只做 LLM 调用,不要把多个逻辑写在一个节点里,方便调试和复用。

相关推荐
EAIReport1 小时前
深度拆解WorkBuddy技术实现:腾讯云全场景AI智能体的架构设计与核心逻辑
人工智能·云计算·腾讯云
m0_741481781 小时前
SQL嵌套查询逻辑重构_将复杂业务逻辑移至应用层
jvm·数据库·python
美狐美颜SDK开放平台1 小时前
什么是美颜SDK?高并发场景下的企业级美颜SDK如何开发?
android·人工智能·ios·美颜sdk·第三方美颜sdk·视频美颜sdk
2303_821287381 小时前
Golang log包如何打印日志_Golang日志输出教程【收藏】
jvm·数据库·python
m0_591364731 小时前
mysql怎么处理连接数过多的报错_调整max_connections参数
jvm·数据库·python
m0_690825821 小时前
Python Flask项目中如何管理数据库连接_使用SQLAlchemy连接池管理
jvm·数据库·python
Westward-sun.1 小时前
Claude Code 接入 DeepSeek V4 Pro:从 npm 安装到 CC Switch 配置完整记录
网络·人工智能
项目題供诗1 小时前
STM32-对射式红外传感器计次&旋转编码器计次(九)
人工智能·stm32·嵌入式硬件
灵机一物1 小时前
灵机一物AI原生电商小程序、PC端(已上线)-黄仁勋 CNBC 对话全文解析:AI 算力、芯片出口、安全开源与产业生态核心观点
人工智能