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

工具调用的工作原理

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

设置 useStream

第一步是将 useStream 连接到您的代理后端。该钩子返回响应式状态,包括一个 toolCalls 数组,该数组在代理流式传输时实时更新。 导入您的代理,并将 typeof myAgent 作为类型参数传递给 useStream,以实现对状态值的类型安全访问:

ToolCallWithResult 类型

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

按消息过滤工具调用

一条AI消息可能触发多个工具调用,而您的聊天可能包含许多AI消息。要为每条消息渲染正确的工具卡片,请通过匹配 call.id 与消息的 tool_calls 数组进行过滤:

构建专用工具卡片

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

天气卡片示例

加载和错误状态

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

类型安全的工具参数

如果您的工具是用结构化模式定义的,您可以使用 ToolCallFromTool 工具类型来获得完全类型化的 args
使用 ToolCallFromTool 可提供编译时安全性。如果工具模式发生变化,您的UI组件将立即标记类型错误。

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

工具调用通常与流式文本交错到达。useStream 钩子使 toolCalls 与流保持同步,因此待处理卡片会在代理发出调用后立即出现,即使工具尚未完成执行。 这意味着用户会看到:
  1. AI的文本流式传输进来
  2. 工具调用发出时立即显示加载卡片
  3. 工具完成后卡片更新以显示结果
工具调用会就地更新。相同的 call.id"pending" 转换为 "completed"(或 "error"),因此您的UI会使用新状态重新渲染相同的组件。

处理多个并发工具调用

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

最佳实践

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