首页 › G LangGraph Agent 编排 › G2 控制流进阶 › 03

G2-03 · Subgraph 子图:图里套图的分层设计

进阶阶段约 180 分钟阶段:G2 控制流进阶

阶段:G2-控制流进阶 | 预计耗时:60 分钟 | 前置:G2-02 Send 并行分发 代码:要你自己敲成 langgraph-learn/examples/g2_subgraph.py 这是 G1-03"数学解题图"的升级——把单张图变成可复用的模块

学习目标

  1. 掌握子图三种接法:当节点直接挂 / 共享 State / 命名空间隔离(重点前两种)
  2. 亲手把"解题子图"套进"路由外壳",理解分层的价值:每层独立开发、独立测试、独立复用
  3. 会把 G1-03 的成果真正变成一个可插入模块

核心知识

1. 子图 = 编译好的图当节点用

solver = build_solver_graph().compile()          # 你 G1-03 写的解题图

builder.add_node("solver", solver)               # 就这一行——图当节点挂
builder.add_edge("router", "solver")

前提:两层图的 State 结构兼容(子图输出的 key 主图能读)。最省心的做法是主图 State 是子图 State 的超集。

2. 为什么要分层(工程视角)

单张巨图 分层子图
节点几十个,图看不懂 每层 3-5 个节点,Studio 逐层看
改一处怕牵全身 子图内部随便改,外壳无感
没法复用 解题子图可插到客服图、教学图里
无法分团队开发 子图=微服务的最小仿真

3. 命名空间隔离(了解)

子图与主图 State 不兼容时,包一层"转接节点"做字段映射(def bridge(state): return {"problem": state["text"]})。G7 实战项目多模块拼接时你会用到。

实验任务

任务 1:把 G1-03 的解题图改造成子图(25 分钟)

  • 把 g1_handmade_react.py 的 builder 部分封装成 def build_solver_graph(): ... 返回编译后图
  • 新建 g2_subgraph.py:路由外壳图(router 节点判断"数学题还是闲聊"——可以先用关键词 if/else,不用 LLM),数学题 → 挂上去的 solver 子图,闲聊 → 直接回复节点
  • 外壳 State:{"text": str, "reply": str, "messages": Annotated[list, add_messages]}——messages 字段与子图对接

任务 2:Studio 里分层看(15 分钟)

langgraph.json 加一行挂上这个新图,在 Studio 里观察:外壳图上 solver 显示为一个节点;点进去看它内部展开的循环结构——这就是"封装"的视觉含义。

任务 3:复用性测试(15 分钟)

再搭一个 10 行的"教学外壳"(教学语气回复 + 同一个 solver 子图)——同一份子图服务两个外壳,一行 import 都不用改 solver。这就是分层的回报。

验收标准

衔接下一阶段

控制流三件套(Command/Send/Subgraph)齐了 → G3-01 Checkpointer 与 thread_id:进入本框架的灵魂——持久化。

小测验(3 题)

答完立即判分,错题给解析;得分存本地。实验与实操题不上网测:回对话找老师验收。