阶段:G2-控制流进阶 | 预计耗时:45 分钟 | 前置:G1 全部验收通过 代码:要你自己敲成
langgraph-learn/examples/g2_command.py
学习目标
- 掌握
Command(update=..., goto=...):更新状态+决定去向一步完成 - 理解它与"条件边"的分工:条件边是图作者定的规则,Command 是节点运行时临场决定
- 会做"审批三选一"的最小雏形(G3 审批流的地基)
核心知识
1. 两种路由方式对比
# 方式一:条件边(G1-03 学的)——路由逻辑在图定义处
builder.add_conditional_edges("review", router, ["approve_node", "reject_node"])
# 方式二:Command(本篇)——路由逻辑在节点内部,跟业务逻辑待在一起
from langgraph.types import Command
def review(state: State) -> Command:
if state["score"] > 60:
return Command(update={"log": "通过"}, goto="approve_node")
return Command(update={"log": "驳回"}, goto="reject_node")
用 Command 时节点返回值本身就是"结果+导航",goto 可以是运行时才算出来的节点名——条件边做不到这一点(条件边的候选集是写死的)。
2. 什么时候用哪个(判断力比语法值钱)
- 候选去向固定、规则简单 → 条件边(图上一眼看清)
- 去向由运行时数据决定、或需要跳很多层(goto 还能进子图)→ Command
- 两者可以混用,但同一个节点别两边都管(可读性崩坏)
实验任务
任务 1:敲出三岔路脚本(25 分钟)
# g2_command.py —— 运行时决定去哪
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.types import Command
def add_log(l: list[str], r: list[str]) -> list[str]:
return l + r
class State(TypedDict):
score: int
log: Annotated[list[str], add_log]
def grader(state: State) -> Command: # 打分后临场导航
if state["score"] >= 90:
return Command(update={"log": [f"{state['score']}分→优秀通道"]}, goto="praise")
if state["score"] >= 60:
return Command(update={"log": [f"{state['score']}分→普通通道"]}, goto="pass_line")
return Command(update={"log": [f"{state['score']}分→重修通道"]}, goto="redo")
# praise / pass_line / redo 三个节点:各返回一行 log
# 图:START→grader;三个终点都接 END
result = StateGraph(State).compile().invoke({"score": 75, "log": []})
print(result["log"])
注意:add_node 照常注册节点,不需要再给 grader 挂条件边。
任务 2:三档分数三连测(10 分钟)
score 分别 95 / 75 / 40 跑三次——验证三条通道,确认 log 都完整保留(Reducer 在工作)。
任务 3:判断题(10 分钟)
写进笔记:① 去向要根据"LLM 情绪分析结果"临场定,用哪种?② 候选去向就两个且永远固定,用哪种?说出理由。
验收标准
衔接下一阶段
单条流程会导航了 → G2-02 Send 并行分发:一次开出 N 条岔路。