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聊天界面。
定义前端操作
AG-Kit AG-Kit提供两种定义不同行为前端操作的方式:
- 自动运行:通过定义带有
handler的前端操作来自动执行并重新生成响应。
- 前端控制:通过定义带有
renderAndWaitForResponse的前端操作来渲染组件,并决定何时执行及重新生成响应。
1) 自动运行
当Agent调用带有handler的工具时,一旦输入就绪便会自动在客户端执行。返回字符串作为工具结果,该结果将在handler完成后发送给Agent。
添加自动运行前端操作时,首先定义带有handler的工具:
const alertUser = tool({
name: "alert",
description: "Alert the user",
parameters: z.object({ message: z.string() }),
handler: async ({ message }) => {
alert(message);
return "done"; // 作为工具结果发送给Agent
},
});
然后通过useChat构建UI,将工具传递给tools选项:
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>Role: {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>Tool Name: {p.name}</p>
<p>Tool Call Arguments: {p.arguments}</p>
{p.result && <p>Tool Call Result: {p.result}</p>}
</div>
);
default:
return null;
}
})}
</div>
))}
</div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={() => sendMessage(input)} disabled={streaming}>
Send
</button>
</div>
);
}
通过发送以下内容与UI交互:
Alert user about typhoon.
随后Agent将调用工具实际弹出警报。
2) 前端控制
此方式允许前端控制工具调用的执行过程,包括处理用户交互、渲染自定义UI以及决定何时及如何将结果提交回Agent。这为需要前端逻辑的复杂交互提供了更大灵活性。
添加完全受控的前端操作时,首先定义带有renderAndWaitForResponse的工具:
const alertUser = tool({
name: "alert",
description: "Alert the user",
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");
}}
>
Allow
</button>
<button onClick={() => submitToolResult?.("User refused the alert")}>
Cancel
</button>
</div>
),
});
然后通过useChat构建UI,将工具传递给tools选项。由于我们已为工具调用定义了自定义UI,现在工具调用消息部分将包含可调用的render函数。
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>Role: {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}>
Send
</button>
</div>
);
}
通过发送以下内容与UI交互:
Alert user about typhoon.
随后Agent将调用工具。与自动运行方式不同的是,现在我们会为工具调用渲染自定义UI,待用户与UI交互后再控制工具调用的执行过程。
选择方案
- 从简开始:当不需要UI时使用
handler。
- 需要用户输入:使用
renderAndWaitForResponse渲染UI并提交结果。