Skip to main content
智能体可以调用外部工具,如天气 API、计算器、网络搜索、数据库查询等。结果是原始 JSON。本模式展示了如何为智能体的每个工具调用渲染结构化的、类型安全的 UI 卡片,包含加载状态和错误处理。

工具调用的工作原理

当 LangGraph 智能体决定需要外部数据时,它会在 AI 消息中发出一个或多个工具调用。每个工具调用包含:
  • name:被调用的工具(如 "get_weather""calculator"
  • args:传递给工具的结构化参数
  • id:将调用与其结果关联的唯一标识符
智能体运行时执行工具,结果以 ToolMessage 形式返回。useStream hook 将所有这些统一为一个可以直接渲染的 toolCalls 数组。

设置 useStream

第一步是将 useStream 连接到你的智能体后端。hook 返回响应式状态,包括一个随智能体流式输出实时更新的 toolCalls 数组。 定义一个与你的智能体状态 schema 匹配的 TypeScript 接口,并将其作为类型参数传递给 useStream,以获得类型安全的状态值访问。在以下示例中,将 typeof myAgent 替换为你的接口名称:

ToolCallWithResult 类型

toolCalls 数组中的每个条目都是一个 ToolCallWithResult 对象:

按消息过滤工具调用

一条 AI 消息可能触发多个工具调用,你的聊天中可能包含多条 AI 消息。要在每条消息下渲染正确的工具卡片,通过将 call.id 与消息的 tool_calls 数组匹配来过滤:

构建专用工具卡片

不要直接展示原始 JSON,而是为每个工具构建专门的 UI 组件。使用 call.name 选择正确的卡片:

天气卡片示例

加载和错误状态

始终处理待处理和错误状态,为用户提供清晰的反馈:

类型安全的工具参数

如果你的工具使用结构化 schema 定义,可以使用 ToolCallFromTool 工具类型获取完全类型化的 args
使用 ToolCallFromTool 提供编译时安全性。如果工具 schema 变更,你的 UI 组件会立即标记类型错误。

在流式文本中内联渲染工具调用

工具调用经常与流式文本交织出现。useStream hook 保持 toolCalls 与流同步,因此待处理卡片在智能体发出调用时立即出现,甚至在工具完成执行之前。 这意味着用户看到:
  1. AI 的文本随流式输出出现
  2. 工具调用发出时立即出现加载卡片
  3. 工具完成后卡片更新显示结果
工具调用原地更新。同一个 call.id"pending" 过渡到 "completed"(或 "error"),因此你的 UI 使用新状态重新渲染同一个组件。

处理多个并发工具调用

智能体可以并行调用多个工具。toolCalls 数组将同时包含多个 state: "pending" 的条目。每个独立解析,因此你的 UI 应优雅地处理部分完成:

最佳实践

构建工具调用 UI 时请遵循以下准则:
  • 始终处理所有三种状态pendingcompletederror。用户不应看到空白卡片。
  • 安全地解析结果。工具结果以字符串形式到达。将 JSON.parse() 包裹在 try/catch 中,解析失败时显示回退内容。
  • 提供通用回退。不是每个工具都需要定制卡片。为未知工具名称渲染可折叠的 JSON 视图。
  • 加载时显示工具名称和参数。用户想知道智能体正在做什么,即使结果尚未到达。
  • 保持卡片紧凑。工具卡片与聊天消息内联显示。避免用过大的控件淹没对话。