设置
安装langgraph:
定义和更新状态
在此我们展示如何在 LangGraph 中定义和更新 状态。我们将演示:定义状态
LangGraph 中的 状态 是使用StateSchema 类定义的。这提供了一个统一的 API,接受 标准模式(如 Zod)作为各个字段,以及特殊值类型如 ReducedValue、MessagesValue 和 UntrackedValue。
默认情况下,图将具有相同的输入和输出模式,状态决定了该模式。有关如何定义不同的输入和输出模式,请参阅 定义输入和输出模式。
让我们考虑一个使用 消息 的简单示例。这代表了适用于许多 LLM 应用的通用状态表述。有关更多详细信息,请参阅我们的 概念页面。
更新状态
让我们构建一个包含单个节点的示例图。我们的 节点 只是一个读取图的 state 并对其进行更新的 TypeScript 函数。此函数的第一个参数始终是 state:StateGraph 来定义一个在此状态下操作的图。然后我们使用 addNode 来填充我们的图。
- 我们通过更新状态的单个键来启动调用。
- 我们在调用结果中接收整个状态。
使用归约器处理状态更新
状态中的每个键都可以有自己的独立 归约器 函数,它控制如何应用来自节点的更新。如果没有显式指定归约器函数,则假设对该键的所有更新都应覆盖它。 在之前的示例中,我们使用了已经内置归约器的MessagesValue。对于自定义字段,您可以使用 ReducedValue 来定义如何应用更新。
在之前的示例中,我们的节点通过在消息列表中追加一条消息来更新状态中的 "messages" 键。MessagesValue 归约器会自动处理此操作:
MessagesValue
在实践中,更新消息列表还有其他注意事项: LangGraph 包含内置的MessagesValue,可处理这些注意事项:
MessagesValue 以供方便使用,因此我们可以拥有:
定义输入和输出模式
默认情况下,StateGraph 使用单一模式运行,所有节点都预期使用该模式进行通信。但是,也可以为图定义不同的输入和输出模式。
当指定不同的模式时,内部仍将使用模式用于节点之间的通信。输入模式确保提供的输入符合预期的结构,而输出模式过滤内部数据,仅根据定义的模式返回相关信息。
下面,我们将看到如何定义不同的输入和输出模式。
在节点之间传递私有状态
在某些情况下,您可能希望节点交换对中间逻辑至关重要但不需要成为图主模式一部分的信息。这种私有数据与图的整体输入/输出无关,应仅在特定节点之间共享。 下面,我们将创建一个由三个节点(node_1、node_2 和 node_3)组成的示例顺序图,其中私有数据在前两个步骤(node_1 和 node_2)之间传递,而第三个步骤(node_3)只能访问公共整体状态。替代状态定义
虽然StateSchema 是定义状态的推荐方法,但 LangGraph 支持几种其他方法。本节涵盖所有可用选项。
通道 API
通道 API 提供对状态管理的低级控制。LangGraph 提供几种内置通道类型:
使用对象简写:
当您传递具有
reducer 和 default 的对象时,它会创建 BinaryOperatorAggregate 通道。传递 null 会创建 LastValue 通道:
Annotation.Root
Annotation.Root 提供了一种声明式方式来定义带有归约器的状态。它与 StateSchema 类似,但使用不同的语法:
带 Zod v3 的对象
当使用 Zod v3 时,您可以使用普通z.object() 模式定义状态。LangGraph 扩展了 Zod v3,提供了 .reducer() 和 .metadata() 方法的 .langgraph 插件:
带 Zod v4 的对象
Zod v4 使用基于注册表的方法。使用 LangGraph 注册表将元数据附加到模式字段:比较表
添加运行时配置
有时您希望在调用图时能够配置它。例如,您可能希望在运行时指定要使用什么 LLM 或系统提示,而 无需将这些参数污染到图状态中。 要添加运行时配置:- 指定配置的 schema
- 将配置添加到节点或条件边的函数签名中
- 将配置传递给图。
扩展示例:在运行时指定 LLM
扩展示例:在运行时指定 LLM
下面我们演示一个实际示例,在其中配置在运行时使用什么 LLM。我们将同时使用 OpenAI 和 Anthropic 模型。
扩展示例:在运行时指定模型和系统消息
扩展示例:在运行时指定模型和系统消息
下面我们演示一个实际示例,在其中配置两个参数:在运行时使用的 LLM 和系统消息。
添加重试策略
有许多用例可能需要您的节点具有自定义重试策略,例如如果您正在调用 API、查询数据库或调用 LLM 等。LangGraph 允许您将重试策略添加到节点。 要配置重试策略,请将retryPolicy 参数传递给 addNode。retryPolicy 参数接受 RetryPolicy 对象。下面我们使用默认参数实例化 RetryPolicy 对象并将其与节点关联:
TypeErrorSyntaxErrorReferenceError
扩展示例:自定义重试策略
扩展示例:自定义重试策略
考虑一个我们从 SQL 数据库读取的示例。下面我们将两个不同的重试策略传递给节点:
创建步骤序列
先决条件
本指南假设您熟悉上面关于 状态 的部分。
- 如何构建顺序图
- 构建类似图的内置简写。
.addNode 和 .addEdge 方法:
为什么使用 LangGraph 将应用程序步骤拆分为序列?
为什么使用 LangGraph 将应用程序步骤拆分为序列?
LangGraph 使为您的应用程序添加底层持久层变得容易。
这允许在节点执行之间对状态进行检查点,因此您的 LangGraph 节点管理:它们还决定执行步骤如何 流式传输,以及如何使用 Studio 可视化和调试您的应用程序。让我们演示一个端到端示例。我们将创建三个步骤的序列:我们的 节点 只是读取图的 state 并对其进行更新的 TypeScript 函数。此函数的第一个参数始终是 state:最后,我们定义图。我们使用 StateGraph 来定义一个在此状态下操作的图。然后我们将使用 addNode 和 addEdge 来填充我们的图并定义其控制流。请注意:让我们继续进行简单的调用:请注意:
- 在状态的键中填充值
- 更新相同的值
- 填充不同的值
请注意,在向状态发出更新时,每个节点只需指定其希望更新的键的值。默认情况下,这将 覆盖 相应键的值。您还可以使用 归约器 来控制如何处理更新——例如,您可以将连续更新附加到键。有关更多详细信息,请参阅 使用归约器处理状态更新。
.addEdge接受节点的名称,对于函数默认为node.name。- 我们必须指定图的入口点。为此,我们添加一条带有 START 节点 的边。
- 当没有更多节点可执行时,图停止。
- 我们通过为单个状态键提供值来启动调用。我们必须始终至少提供一个键的值。
- 我们传入的值被第一个节点覆盖。
- 第二个节点更新了该值。
- 第三个节点填充了不同的值。
创建分支
节点的并行执行对于加快整体图操作至关重要。LangGraph 原生支持节点的并行执行,可以显著提高基于图的工作流的性能。这种并行化是通过扇出和扇入机制实现的,利用标准边和 条件边。以下是一些示例,展示如何添加适合您的分支数据流。并行运行图节点
在此示例中,我们从Node A 扇出到 B 和 C,然后扇入到 D。使用我们的状态,我们指定归约器 add 操作。这将组合或累积特定键的值,而不是简单地覆盖现有值。对于列表,这意味着将新列表与现有列表连接。有关使用归约器更新状态的更多详细信息,请参阅上面的 状态归约器 部分。
在上述示例中,节点
"b" 和 "c" 在同一个 超级步骤 中并发执行。因为它们在同一步骤中,所以节点 "d" 在 "b" 和 "c" 完成后执行。重要的是,来自并行超级步骤的更新可能不会按一致的顺序排列。如果您需要来自并行超级步骤的一致、预定顺序的更新,您应该将输出写入状态中的单独字段,并附带用于排序的值。异常处理?
异常处理?
LangGraph 在 超级步骤 内执行节点,这意味着虽然并行分支并行执行,但整个超级步骤是 事务性 的。如果这些分支中的任何一个抛出异常,没有任何 更新应用于状态(整个超级步骤出错)。重要的是,当使用 检查点器 时,超级步骤内成功节点的結果会被保存,并且在恢复时不会重复。如果您有容易出错的(也许想处理不稳定的 API 调用)节点,LangGraph 提供两种解决方法:
- 您可以在节点内编写常规 Python 代码来捕获和处理异常。
- 您可以设置 retry_policy 以指导图重试抛出某些类型异常的节点。只有失败的分支会被重试,因此您无需担心执行冗余工作。
条件分支
如果您的扇出应根据状态在运行时变化,您可以使用addConditionalEdges 使用图状态选择一个或多个路径。见下方示例,其中节点 a 生成确定下一个节点的状态更新。
Map-Reduce 和 Send API
LangGraph 支持使用 Send API 进行 map-reduce 和其他高级分支模式。以下是如何使用它的示例:创建和控制循环
在创建带有循环的图时,我们需要一种终止执行的机制。这通常是通过添加 条件边 来实现的,一旦达到某些终止条件,该边就会路由到 END 节点。 您也可以在调用或流式传输图时设置图递归限制。递归限制设置图在抛出错误之前允许执行的 超级步骤 数量。有关 递归限制概念 的更多信息。 让我们考虑一个简单的带有循环的图,以更好地了解这些机制如何工作。 创建循环时,您可以包含指定终止条件的条件边:"recursionLimit"。这将抛出 GraphRecursionError,您可以捕获并处理:
"a" 是调用工具的模型,节点 "b" 代表工具。
在我们的 route 条件边中,我们指定在状态中的 "aggregate" 列表超过阈值长度后我们应该结束。
调用图时,我们看到我们在达到终止条件之前在节点 "a" 和 "b" 之间交替。
施加递归限制
在某些应用中,我们无法保证将达到给定的终止条件。在这些情况下,我们可以设置图的 递归限制。这将在给定数量的 超级步骤 后抛出GraphRecursionError。然后我们可以捕获并处理此异常:
使用 Command 结合控制流和状态更新
结合控制流(边)和状态更新(节点)可能很有用。例如,您可能希望 同时 执行状态更新 并 决定下一个节点去哪里。LangGraph 提供了一种方法,即从节点函数返回 Command 对象:
StateGraph。请注意,图没有 条件边 用于路由!这是因为控制流是在 nodeA 中使用 Command 定义的。
导航到父图中的节点
如果您正在使用 子图,您可能希望从子图中的节点导航到不同的子图(即父图中的不同节点)。为此,您可以在Command 中指定 graph=Command.PARENT:
nodeA 更改为我们将其作为子图添加到父图中的单节点图。
在工具中使用
一个常见的用例是从工具内部更新图状态。例如,在客户支持应用中,您可能希望在对话开始时根据账户号或 ID 查找客户信息。要从工具更新图状态,您可以从工具返回Command(update={"my_custom_key": "foo", "messages": [...]}):
Command 更新状态的工具,我们建议使用预构建的 ToolNode,它自动处理工具返回 Command 对象并将它们传播到图状态。如果您正在编写调用工具的自定义节点,则需要手动传播工具返回的 Command 对象作为节点的更新。
可视化您的图
在此我们演示如何可视化您创建的图。 您可以可视化任何任意 Graph,包括 StateGraph。 让我们创建一个简单的示例图来演示可视化。Mermaid
我们还可以将图类转换为 Mermaid 语法。PNG
如果更喜欢,我们可以将图渲染为.png。这使用 Mermaid.ink API 生成图表。
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

