如何将控制流与状态更新结合使用命令模式¶
结合控制流(边)和状态更新(节点)是非常有用的。例如,您可能想要在同一个节点中同时执行状态更新和决定下一个要转到的节点。LangGraph 提供了一种方法,可以通过从节点函数返回 Command 对象来实现这一点:
def my_node(state: State) -> Command[Literal["my_other_node"]]:
return Command(
# 状态更新
update={"foo": "bar"},
# 控制流
goto="my_other_node"
)
本指南展示了如何使用 Command 在您的 LangGraph 应用中添加动态控制流。
设置¶
首先,安装所需的包。
为LangGraph开发设置 LangSmith
注册LangSmith,以快速发现问题并提升您的LangGraph项目的性能。LangSmith使您能够使用跟踪数据来调试、测试和监控您使用LangGraph构建的LLM应用程序——了解如何开始 请点击这里。
让我们创建一个简单的图形,包含3个节点:A、B和C。我们将首先执行节点A,然后根据节点A的输出决定接下来是前往节点B还是节点C。
定义图形¶
import random
from typing_extensions import TypedDict, Literal
from langgraph.graph import StateGraph, START
from langgraph.types import Command
# 图态定义:图态是一种量子态,其描述通过图论中的图来表示。在量子信息中,图态通常与多体量子系统相关联,其中每个节点代表一个量子比特,而边表示节点之间的纠缠关系。图态能够用于多种量子计算和量子通信任务,特别是在量子网络和量子态传输中具有重要应用。
class State(TypedDict):
foo: str
# 定义节点
def node_a(state: State) -> Command[Literal["node_b", "node_c"]]:
print("Called A")
value = random.choice(["a", "b"])
# 这是一个条件边函数的替代方案。
if value == "a":
goto = "node_b"
else:
goto = "node_c"
# 请注意,Command 允许您既更新图形状态又路由到下一个节点。
return Command(
# 这是状态更新。
update={"foo": value},
# 这是边缘的替代品。
goto=goto,
)
# 节点B和C没有变化。
def node_b(state: State):
print("Called B")
return {"foo": state["foo"] + "b"}
def node_c(state: State):
print("Called C")
return {"foo": state["foo"] + "c"}
API Reference:
StateGraph | START
我们现在可以使用上述节点创建 StateGraph。请注意,图中没有用于路由的 条件边!这是因为控制流是在 node_a 中通过 Command 定义的。
builder = StateGraph(State)
builder.add_edge(START, "node_a")
builder.add_node(node_a)
builder.add_node(node_b)
builder.add_node(node_c)
# 注意:节点 A、B 和 C 之间没有边!
graph = builder.compile()
!!!重要
您可能注意到我们使用了 Command 作为返回类型注解,例如 Command[Literal["node_b", "node_c"]]。这是图形渲染所必需的,并告诉 LangGraph node_a 可以导航到 node_b 和 node_c。
如果我们多次运行该图,我们会看到它根据节点A中的随机选择采取不同的路径(A -> B或A -> C)。