跳转到主要内容
客户端工具可以通过允许 Agent 在客户端操作来增强您的 Agent。
框架兼容性
  • ✅ AG-Kit (TypeScript)
  • ✅ LangGraph (TypeScript)
  • ✅ LangGraph (Python)
本页假设您已经配置好 useChat(消息循环、渲染)。如果没有,请从构建 Copilot 聊天 UI 开始。

定义客户端工具

AG-Kit SDK 提供 2 种方式来定义不同行为的客户端工具:
  • 自动运行:使用 handler 定义客户端工具,自动运行并重新生成响应。
  • 让前端控制:使用 renderAndWaitForResponse 定义客户端工具,渲染组件并定义何时运行和重新生成响应。

1) 自动运行

当 Agent 调用具有 handler 的工具时,一旦输入可用,它就会在客户端自动运行。返回一个字符串作为工具的结果,当 handler 完成时将发送给 Agent。 要添加自动运行的客户端工具,首先定义一个带有 handler 的工具:
import { clientTool } from '@ag-kit/ui-react';
import { z } from 'zod';

const alertUser = clientTool({
  name: "alert",
  description: "向用户发出警报",
  parameters: z.object({ message: z.string() }),
  handler: async ({ message }) => {
    alert(message);
    return "done"; // 作为工具结果发送给 Agent
  },
});
然后使用 useChat 构建 UI,将工具传递给 tools 选项:
import { useChat } from '@ag-kit/ui-react';
import { useState } from 'react';

function Chat() {
  const { uiMessages, sendMessage, streaming } = useChat({
    url,
    clientTools: [alertUser],
  });
  const [input, setInput] = useState("");

  return (
    <div>
      <div>
        {uiMessages.map((m, mi) => (
          <div key={mi}>
            <p>角色: {m.role}</p>
            {m.parts.map((p, pi) => {
              switch (p.type) {
                case "text":
                  return (
                    <p key={pi}>
                      {m.role}: {p.text}
                    </p>
                  );
                case "tool-call":
                  return (
                    <div key={pi}>
                      <p>工具名称: {p.name}</p>
                      <p>工具调用参数: {p.arguments}</p>
                      {p.result && <p>工具调用结果: {p.result}</p>}
                    </div>
                  );
                default:
                  return null;
              }
            })}
          </div>
        ))}
      </div>

      <input value={input} onChange={(e) => setInput(e.target.value)} />
      <button onClick={() => sendMessage(input)} disabled={streaming}>
        发送
      </button>
    </div>
  );
}
通过发送以下内容与 UI 交互:
向用户发出台风警报。
然后 Agent 将进行工具调用以实际弹出警报。

2) 让前端控制

这种方法允许前端控制工具调用的执行方式,包括处理用户交互、渲染自定义 UI,以及确定何时以及如何将结果提交回 Agent。这为需要前端逻辑的复杂交互提供了更大的灵活性。 要添加完全受控的客户端工具,首先定义一个带有 renderAndWaitForResponse 的工具:
import { clientTool } from '@ag-kit/ui-react';
import { z } from 'zod';

const alertUser = clientTool({
  name: "alert",
  description: "向用户发出警报",
  parameters: z.object({ message: z.string() }),
  renderAndWaitForResponse: ({ input, submitToolResult }) => (
    <div className="space-x-2">
      <span>{input.message}</span>
      <button
        onClick={() => {
          alert(input.message);
          submitToolResult?.("done");
        }}
      >
        允许
      </button>
      <button onClick={() => submitToolResult?.("用户拒绝了警报")}>
        取消
      </button>
    </div>
  ),
});
然后使用 useChat 构建 UI,将工具传递给 tools 选项。由于我们刚刚为工具调用定义了自定义 UI,现在工具调用消息部分将有一个可以调用的 render 函数。
import { useChat } from '@ag-kit/ui-react';
import { useState } from 'react';

function Chat() {
  const { uiMessages, sendMessage, streaming } = useChat({
    url,
    clientTools: [alertUser],
  });
  const [input, setInput] = useState("");

  return (
    <div>
      <div>
        {uiMessages.map((m, mi) => (
          <div key={mi}>
            <p>角色: {m.role}</p>
            {m.parts.map((p, pi) => {
              switch (p.type) {
                case "text":
                  return (
                    <p key={pi}>
                      {m.role}: {p.text}
                    </p>
                  );
                case "tool-call":
                  return p.render?.();
                default:
                  return null;
              }
            })}
          </div>
        ))}
      </div>

      <input value={input} onChange={(e) => setInput(e.target.value)} />
      <button onClick={() => sendMessage(input)} disabled={streaming}>
        发送
      </button>
    </div>
  );
}
通过发送以下内容与 UI 交互:
向用户发出台风警报。
然后 Agent 将进行工具调用。与自动运行方法的不同之处在于,现在我们为工具调用渲染自定义 UI,用户与 UI 交互后控制工具调用的执行方式。

选择方法

  • 从简单开始:当不需要 UI 时使用 handler
  • 需要用户输入:使用 renderAndWaitForResponse 渲染 UI 并提交结果。