Documentation Index
Fetch the complete documentation index at: https://docs.ag-kit.dev/llms.txt
Use this file to discover all available pages before exploring further.
客户端工具可以通过允许 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 并提交结果。