Command与动态跳转

有时下一跳取决于节点内部逻辑(刚调了外部 API 才知道去哪个子流程),单独抽 router 函数显得割裂。Command 让节点同时返回 state 更新goto 目标,实现动态跳转。


1. 定位

维度 内容
角色 节点内声明下一节点(动态边)
输入 → 输出 节点返回 Command(update=..., goto=...)
核心 API Commandgoto
依赖 LangChain

2. 图拓扑

节点表

节点名 职责 读 State 写 State
dispatch 决定分支 mode mode, log
path_a 分支 A log
path_b 分支 B log

边表

目标 类型
START dispatch 固定
dispatch path_a / path_b Command.goto(动态)
path_a END 固定
path_b END 固定

使用 Command 时,dispatch 不必再 add_conditional_edges;但仍需注册 path_a、path_b 节点。


3. invoke 生命周期

1
2
3
4
1. dispatch 读 mode="b"
2. 返回 Command(update={"log": ["→b"]}, goto="path_b")
3. 合并 update,调度器跳转 path_b(跳过 path_a)
4. path_b → END

Superstep:Command 在节点执行结束的同一 superstep 应用 update 并解析 goto。


4. 原理

4.1 Command 结构

1
2
3
from langgraph.types import Command

return Command(update={"log": ["x"]}, goto="path_b")

goto 可以是节点名、ENDSend 列表(高级)。

4.2 与 conditional_edges 选型

  • 分支逻辑简单、可读性优先 → conditional_edges
  • 分支与节点副作用紧耦合 → Command

4.3 resume 场景

interrupt 恢复时也常用 Command(resume=...)(见中断专篇)。


5. 最小可运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import operator
from typing import Annotated, TypedDict

from langgraph.graph import StateGraph, START, END
from langgraph.types import Command


class State(TypedDict):
mode: str
log: Annotated[list[str], operator.add]


def dispatch(state: State) -> Command:
target = "path_b" if state["mode"] == "b" else "path_a"
return Command(update={"log": [f"goto:{target}"]}, goto=target)


def path_a(_: State) -> dict:
return {"log": ["ran_a"]}


def path_b(_: State) -> dict:
return {"log": ["ran_b"]}


builder = StateGraph(State)
builder.add_node("dispatch", dispatch)
builder.add_node("path_a", path_a)
builder.add_node("path_b", path_b)
builder.add_edge(START, "dispatch")
builder.add_edge("path_a", END)
builder.add_edge("path_b", END)

graph = builder.compile()
print(graph.invoke({"mode": "b", "log": []})["log"])
# ['goto:path_b', 'ran_b']

6. 执行追踪

mode=”b”

步骤 节点 log
1 dispatch ["goto:path_b"]
2 path_b ["goto:path_b","ran_b"]

mode=”a”:dispatch goto path_a,不会执行 path_b。


重要配置参数

参数 类型 / 默认 作用与影响 参考起点 配置指导
Command(update=...) dict partial state 与节点返回一致 可仅 goto
Command(goto=...) str / END 下一节点 动态名 必须已 add_node
Command(resume=...) Any 中断恢复 HITL 篇 与 interrupt 成对
无 static 出边 dispatch 靠 Command 单入口 path 仍要 add_edge→END
goto 无效节点 运行错误 单元测试 枚举目标名
与 Send 组合 list[Send] 动态并行 map 场景 见 Send 篇

7. 易踩坑

  1. goto 目标未 add_node:invoke 失败。
  2. 同时写 conditional_edges 与 Command:可能冲突,择一。
  3. Command 未 import 正确路径langgraph.types.Command

小结

  • Command 把「更新 state」和「下一跳」合成一次返回。
  • 适合节点内决策跳转;简单分支仍推荐 conditional_edges + path_map
  • 恢复流程用 Command(resume=…) 与 interrupt 配合。

参考链接

-------------本文结束感谢您的阅读-------------