1004 字
3 分钟
LangGraphlanggraph
LangGraph 核心能力 07:Subgraphs 子图与复用

子图如何作为节点复用、如何共享 state、如何流式查看子图执行与持久化模式选择。

LangGraph能力 - Subgraphs (子图)#

子图是一种在另一张图中作为图节点使用的节点。适用于以下场景:

  • 构建多智能体系统
  • 在多张图中复用一组节点
  • 分布式开发:当需要不同团队独立负责图的不同部分时,可将各部分定义为子图。只要遵循子图接口(输入与输出模式),父图即可在无需了解子图任何细节的情况下完成构建

添加子图时,需要定义父图与子图之间的通信方式:

模式适用场景状态 schema 特点
在节点内部调用子图父图和子图的状态 schema 不同,二者没有共享键;或者你需要在父图与子图之间做状态转换需要自己写一个包装节点,把父图 state 映射成子图输入,再把子图输出映射回父图 state
将子图直接作为节点加入父图和子图共享部分状态键;子图可以直接读写父图的同一批 state channel直接把编译好的子图传给 add_node,不需要额外包装函数

1. 节点内部调用:#

当父图与子图拥有不同的状态结构(无共享键)时,需在节点函数内部调用子图。这种做法常见于多智能体系统中需要为每个智能体保留独立消息历史的场景。

节点函数会在调用子图前将父图状态转换为子图状态,并在返回前将结果转换回父图状态。

Python3 点击展开代码
36 lines 展开代码

因为父图和子图的state不一样,上例用了一个call_subgraph包装,来把父图的状态转化为子图的输入,再把子图的输出转回父图的状态。

2. 子图作为node加入#

当父图与子图共享状态键(State)时,可将编译后的子图直接传入add_node。无需包装函数 —— 子图会自动读写父图的状态通道。例如,在多智能体系统中,智能体通常通过共享的messages键进行通信。

alt text

如果子图与父图共享状态键,可按照以下步骤将其添加到你的图中:

  • 定义子图工作流(下方示例中的subgraph_builder)并对其进行编译
  • 在定义父图工作流时,将编译后的子图传入add_node方法
Python3 点击展开代码
27 lines 展开代码

只要有共享的 state key,就可以直接作为 node 加入,同时子图还可以有自己私有的 key,也就是说,子图结构可以比父图更复杂。

3. 流式看到子图内部执行#

只需要调整一个参数就可以,然后,我们就可以通过chunk["ns"] 看这个事件来自哪里,ns == ()表示是主图,如果来自某个子图可能是ns == ("node_2:<task_id>",)

Python3 代码示例
1 lines

4. 子图的持久化模式#

子图在 compile() 时,checkpointer 有 3 种模式:

checkpointer=None

  • 默认
  • 每次调用子图都从头开始
  • 但单次调用内部仍继承父图 checkpointer,支持 interrupt / durable execution

checkpointer=True

  • 子图按 thread 持续积累状态
  • 下次调用同一个子图时,会接着上次记忆继续
  • 适合"子 agent 自己也要有多轮记忆"

checkpointer=False

  • 完全无 checkpoint
  • 像普通函数调用
  • 不支持 interrupt / durable execution

对于有多个"有记忆的子图"命名时,我们要给稳定的namespace进行空间隔离。

5. 查询子图状态#

我们通过graph.get_state(config, subgraphs=True)来获取快照,然后可以用.tasks[0].state来看子图的内部状态。

下面给一个最小的可运行子图示例,包含了子图持久化、namespace隔离、查询子图状态、查看子图流输出等,包含详细注释:

Python3 点击展开代码
193 lines 展开代码

专题阅读

LangGraph

这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。

当前进度9 / 11

留言区

留言

欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。

0

正在加载评论...

0 / 2000

阅读导航

文章目录

当前阅读位置将在这里显示

0 节