使用子图
一句话
子图(Subgraph)是一个作为另一个图中节点(node)使用的图(graph),用于构建多智能体系统、重用节点集合或分布式开发。
什么时候翻这页
当你需要:
- 构建多智能体系统
- 在多个图中重用一组节点
- 让不同团队独立开发图的不同部分
- 管理子图与父图之间的状态通信
- 控制子图数据的持久化方式
核心概念
- 子图(Subgraph): 作为节点使用的图
- 状态模式(State Schema): 父图和子图之间的数据结构
- 调用子图(Call a subgraph): 在节点函数内部调用子图
- 添加子图(Add a subgraph): 将编译后的子图直接添加为节点
- 持久化模式(Persistence modes): 控制子图内部数据在调用之间的保留方式
怎么做
定义子图通信
有两种主要模式:
-
在节点内调用子图(适用于不同状态模式)
- 父图和子图有不同的状态模式(无共享键)
- 需要在调用前后转换状态
- 使用包装函数映射父状态到子图输入和子图输出回到父状态
-
将子图作为节点添加(适用于共享状态键)
- 父图和子图共享状态键
- 子图直接读写与父图相同的通道
- 直接将编译后的子图传递给
add_node,无需包装函数
子图持久化
三种持久化模式:
-
每次调用(Per-invocation)(默认)
- 每次调用都重新开始,继承父图的 checkpointer
- 支持中断(interrupts)和持久执行
- 适用于大多数应用,包括多智能体系统
-
每线程(Per-thread)
- 状态在同一线程的多次调用中累积
- 每次调用从上次停止的地方继续
- 适用于需要多轮对话记忆的子智能体
-
无状态(Stateless)
- 无 checkpointing,像普通函数调用一样运行
- 不支持中断或持久执行
- 如果进程在运行中崩溃,子图无法恢复
查看子图状态
启用持久化后,可以使用 subgraphs 选项检查子图状态:
- 每次调用模式:仅返回当前调用的子图状态
- 每线程模式:返回该线程上所有调用的累积子图状态
流式传输子图输出
使用事件流(event streaming)观察嵌套图执行:
stream = graph.stream_events({"foo": "foo"}, version="v3")
for subgraph in stream.subgraphs:
print(subgraph.graph_name, subgraph.path)
for snapshot in subgraph.values:
print(subgraph.path, snapshot)
命令 / API 速查
subgraph_builder = StateGraph(SubgraphState): 创建子图构建器subgraph = subgraph_builder.compile(): 编译子图subgraph = subgraph_builder.compile(checkpointer=None): 每次调用模式(默认)subgraph = subgraph_builder.compile(checkpointer=True): 每线程模式subgraph = subgraph_builder.compile(checkpointer=False): 无状态模式builder.add_node("node_name", subgraph): 将子图作为节点添加graph.get_state(config, subgraphs=True): 获取子图状态stream = graph.stream_events(input, version="v3"): 流式传输事件
与 Hello-Agents / Claude Code 的联系
在 Hello-Agents 中,我们学习了基本的 LangGraph 概念和简单的图构建。子图功能扩展了这些概念,允许你构建更复杂的多智能体系统,其中每个智能体可以作为子图实现。这与 Hello-Agents 中介绍的多智能体系统概念相呼应,但提供了更细粒度的控制和组织方式。
初学者易错点
- 状态模式不匹配:忘记在父图和子图之间正确转换状态会导致数据丢失或错误
- 持久化模式选择不当:选择错误的持久化模式可能导致子图无法记住上下文或产生不必要的内存开销
- 并行调用冲突:每线程子图不支持并行工具调用,会导致 checkpoint 冲突
- 命名空间隔离:多个每线程子图需要适当的命名空间隔离,否则状态会相互覆盖
- 子图状态查看限制:子图状态查看要求 LangGraph 能够静态发现子图,在某些间接调用模式下可能不工作