Skip to main content
LangGraph 智能体并非黑盒。每个图都由命名节点组成,这些节点按顺序或并行执行:分类、研究、分析、综合。图执行卡片通过为每个节点渲染一张卡片,显示其状态、实时流式传输其内容,并跟踪整个工作流的完成情况,使这一流水线变得可见。用户可以清晰地看到智能体正在做什么、当前处于哪一步骤,以及每个步骤产生了什么结果。

图节点如何映射到 UI 卡片

一个 LangGraph 图定义了一系列节点,每个节点负责一项特定任务。例如,一个研究流水线可能包含:
  1. 分类:对用户查询进行分类
  2. 研究:收集相关信息
  3. 分析:从研究中得出结论
  4. 综合:生成最终的、经过润色的响应
每个节点将其输出写入图状态的特定键。通过将这些节点名称和状态键映射到 UI 组件,您可以创建整个流水线的可视化表示。

设置 useStream

像往常一样连接 useStream。您将使用的关键属性是 messages(用于流式内容路由)、values(用于已完成的节点输出)和 getMessagesMetadata(用于识别每个令牌是由哪个节点产生的)。 定义一个与您的智能体状态模式匹配的 TypeScript 接口,并将其作为类型参数传递给 useStream,以便对状态值(包括每个流水线节点的自定义状态键)进行类型安全访问。在下面的示例中,将 typeof myAgent 替换为您的接口名称:

将流式令牌路由到节点

当智能体流式传输时,每条消息都附有元数据,用于标识是哪个图节点产生了它。使用 getMessagesMetadata 提取 langgraph_node 值,并将令牌路由到正确的卡片:
这为您提供了一个从节点名称到其当前流式内容的映射。随着令牌到达,相应的卡片会实时更新。
streamMetadata.langgraph_node 字段由 LangGraph 自动设置。您在后端不需要任何特殊配置。只需像往常一样流式传输消息,元数据就会包含在内。

确定节点状态

每个节点可能处于四种状态之一:未开始、流式传输中、已完成或空闲。您可以从两个来源推导出状态:流式内容映射(用于活动节点)和 stream.values(用于已完成的节点):

构建流水线进度条

顶部的水平进度条为用户提供了整个流水线的鸟瞰视图。每个步骤都是一个带标签的段,随着节点完成而填充:

构建可折叠的 NodeCard 组件

每个节点都有自己的卡片,显示状态徽章、内容(流式或最终)以及用于长输出的可折叠主体:

流式内容与已完成内容

每个节点有两个内容来源,选择合适的来源对于流畅的用户体验很重要: 模式是:显示流式内容以获取实时更新,节点完成后回退到已提交的状态值。
流式内容可能包含部分令牌或尚未完全形成的 Markdown。如果您渲染 Markdown,请确保您的渲染器能够优雅地处理不完整的语法(例如,未闭合的粗体标记 **)。

整体整合

以下是结合了路由、状态检测和卡片渲染的完整卡片列表:

使用场景

图执行卡片适用于任何需要可见性的多步骤流水线:
  • 研究流水线:分类 → 收集来源 → 分析 → 综合报告
  • 内容生成:大纲 → 草稿 → 事实核查 → 编辑 → 发布
  • 数据处理:摄取 → 验证 → 转换 → 聚合 → 导出
  • 代码生成:理解需求 → 规划架构 → 编写代码 → 审查 → 测试
  • 决策工作流:收集上下文 → 评估选项 → 评分备选方案 → 推荐

处理动态流水线

并非所有图都有固定的节点集。一些流水线会根据输入添加或跳过节点。通过检查哪些状态键实际有值来处理这种情况:
这确保您的 UI 只显示与当前执行相关的节点的卡片,避免出现空的占位卡片。
如果您的图具有条件分支(例如,对于简单的查询跳过“研究”步骤),被跳过的节点将永远不会出现在流式内容或状态值中。您的流水线进度条应通过变灰或隐藏跳过的步骤来反映这一点。

最佳实践

  • 声明式定义节点。将您的 PIPELINE_NODES 数组作为单一事实来源,映射节点名称、状态键和显示标签。
  • 优先使用流式内容处理活动节点。它为用户提供即时反馈。仅在节点完成后才回退到已提交的状态值。
  • 自动折叠已完成的节点。在长流水线中,自动折叠已完成的卡片,以便用户可以专注于当前活动的步骤。
  • 显示预估时间。如果您有每个节点所需时间的历史数据,请显示时间预估以设定用户期望。
  • 添加全局进度指示器。在流水线视图的顶部,用整体进度条(例如,“第 2 步,共 4 步”)来补充每个节点的卡片。
  • 按节点处理错误。如果某个节点失败,在其卡片中显示错误,而不要折叠整个流水线。其他节点可能仍会成功完成。