实用功能

Command 对象

使用 Command 对象实现节点内的动态路由和状态更新组合

📚 学习目标

学完这篇文章后,你将能够:

  • 理解 Command 对象如何替代传统的返回值+路由模式
  • 在节点内部动态决定跳转目标 (goto)
  • 将状态更新与控制流合并为一个操作

前置知识

在开始学习之前,建议先阅读:

你需要了解:

  • 传统的 addConditionalEdges 路由方式

1️⃣ 传统模式 vs Command 模式

传统模式

你需要:

  1. 这里定义节点函数 nodeA
  2. 那里定义路由函数 routeLogic
  3. 在 Graph 定义时 addConditionalEdges("nodeA", routeLogic)

这种方式逻辑分散在两处。

Command 模式

节点直接返回:“更新这个状态,然后去那个节点”。

import { Command } from '@langchain/langgraph';

const nodeA = (state) => {
  if (state.value > 10) {
    return new Command({
      update: { value: state.value + 1 }, // 更新状态
      goto: "node_b" // 直接跳转
    });
  }
  
  return new Command({
    update: { value: 0 },
    goto: END // 结束
  });
};

优点:逻辑内聚,不需要单独定义条件边。


2️⃣ 组合状态更新与跳转

Command 对象的核心属性:

  • update: (可选) 像普通节点返回值一样更新状态。
  • goto: (可选) 指定下一个节点的名字(字符串)或 END
// 仅跳转,不更新状态
new Command({ goto: "next_node" });

// 仅更新状态,不指定跳转(遵循默认边)
// 这等同于直接返回对象,但在多子图场景下更有用
new Command({ update: { key: "value" } }); 

3️⃣ 在子图中使用 Command

Command 在子图通信中非常强大。它可以让子图直接控制父图的流向(慎用,会增加耦合),或者更常见的是,用于在子图内部灵活调度。


4️⃣ 与人机交互结合:resume 用于“从断点继续”

当你使用 interrupt 暂停图执行后,恢复时通常会传入 new Command({ resume: ... })

import { Command } from '@langchain/langgraph';

// 用户在 UI 上点了“批准”
await app.invoke(new Command({ resume: 'approved' }), {
  configurable: { thread_id: 'thread-1' },
});

这类场景最常见于:审批流、编辑流、人工标注等。


💡 练习题

  1. 重构题:回顾你的 ReAct Agent 代码。尝试使用 Command 对象重写 shouldContinue 逻辑,将其合并到 AgentNode 中。(注意:这可能需要你的 Graph 结构允许 AgentNode 直接连接到 ToolNode,而不需要显式的中间条件边,虽然在 ReAct 中通常还是习惯用条件边,但尝试思考如何用 Command 实现)。

📚 参考资源

官方文档

本项目相关内容


✅ 总结

本章要点

  • Command 提供了一种“节点自治”的流控制方式。
  • goto 属性让节点可以动态决定下一站。
  • 它让复杂的动态图结构代码更加紧凑。

下一步:所有的这些功能,在实际业务中怎么用?让我们进入 常见用例

登录以继续阅读

解锁完整文档、代码示例及更多高级功能。

立即登录

On this page