资讯动态

CopilotKit × Agno 前端工具(In-App Actions)实战指南:让 Agent 通过 `useFrontendTool` 直接驱动 React 界面

发布时间:2026/9/11 22:50:04 来源:尧图企业网站定制
CopilotKit × Agno 前端工具In-App Actions实战指南让 Agent 通过useFrontendTool直接驱动 React 界面【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit本指南围绕 CopilotKit 与 Agno 集成仓库中的Frontend Tools即 In-App Actions功能展开以showcase/integrations/agno/qa/frontend-tools.md这份 QA 检查清单为核心骨架结合frontend-tools演示的完整源码与端到端测试系统讲解前端工具的概念、注册方式、Agno 后端工具声明、交互链路与 QA 验证方法。读完本文你将掌握如何在自己的 React 应用中注册一个由 Agent 按对话语义自动触发的前端工具并通过 Playwright 测试与 QA 清单对工具被正确调用、界面状态真实变更进行可复现的验证。一、什么是 Frontend ToolsAgent 直接调用住在浏览器里的函数传统 Agent 工具通常运行在服务端调用数据库、外部 API。而 CopilotKit 的Frontend ToolsIn-App Actions提供了一种相反的模型工具函数本身运行在 React 客户端Agent 在推理对话时决定是否调用它调用结果通过运行时协议回传给 Agent。这一点在演示的说明文件 src/app/demos/frontend-tools/README.md 中定义得非常明确Frontend tools (a.k.a. in-app actions) let the agent call functions that live in your React app. The agent reasons about when to invoke them based on natural conversation.翻译过来即前端工具让 Agent 调用活在 React 应用里的函数Agent 基于自然对话进行推理自行决定何时调用它们。这解决了传统 AI 应用LLM 只能输出文本、无法真正操作界面的痛点——例如本演示中用户说把背景改成蓝紫渐变Agent 直接改掉了页面的背景样式。前端工具与后端工具的分工以本演示所在的 Agno 集成仓库为例工具被清晰地划分为两类工具类型运行位置典型代表src/agents/main.py服务端工具Agno AgentPythonget_weather、query_data、get_stock_price、search_flights、roll_dice前端工具In-App ActionsReact 浏览器端change_background本演示主角、book_call、request_user_approval、generate_task_steps值得注意的细节在 Agno 后端的 main.py 中change_background同样被声明为一个tool但通过external_executionTrue标记为由外部前端执行的工具tool(external_executionTrue) def change_background(background: str): Change the background color of the chat. ONLY call this tool when the user explicitly asks to change the background. Never call it proactively or as part of another response. Can be anything that the CSS background attribute accepts. Prefer gradients. Args: background (str): The CSS background value. Prefer gradients. 这里的函数体为空是刻意为之external_executionTrue告诉 Agno 运行时——这个工具的 schema 我会给 LLM 看但真正的执行逻辑在浏览器端。后端只负责把工具签名与描述暴露给 LLM执行权完全交给前端。同时docstring 里ONLY call this tool when the user explicitly asks to change the background这条指令会被注入到系统提示词中约束 Agent 不要主动、不要在其他回复中顺带调用保证工具的触发严格以用户显式请求为前提。二、仓库中的 Frontend Tools 演示结构与运行入口整个演示位于showcase/integrations/agno目录前端是 Next.js 应用其关键文件为src/app/demos/frontend-tools/page.tsx — 演示页面注册前端工具、挂载 CopilotSidebarsrc/app/demos/frontend-tools/background.tsx — 背景容器组件工具的被操作对象src/app/demos/frontend-tools/suggestions.ts — 预设的对话建议Suggestion Pillssrc/app/demos/frontend-tools/README.md — 该演示的交互说明src/agents/main.py — Agno 后端 Agent声明change_background工具并配置模型tests/e2e/frontend-tools.spec.ts — Playwright 端到端测试qa/frontend-tools.md — 本次文章骨架来源的 QA 检查清单。页面通过CopilotKit组件连接后端运行时runtimeUrl/api/copilotkit、agentfrontend_tools并挂载了默认展开的CopilotSidebarexport default function FrontendToolsDemo() { return ( CopilotKit runtimeUrl/api/copilotkit agentfrontend_tools Chat / /CopilotKit ); }其中agentIdfrontend_tools与后端 Agent 名称一一对应确保前端会话路由到正确的 Agno Agent。三、核心 APIuseFrontendTool注册一个前端工具前端工具通过 React HookuseFrontendTool注册完整代码如下摘自 page.tsxuse client; import React, { useState } from react; import { CopilotKit, CopilotSidebar, useFrontendTool, } from copilotkit/react-core/v2; import { z } from zod; import { Background, DEFAULT_BACKGROUND } from ./background; import { useFrontendToolsSuggestions } from ./suggestions; function Chat() { const [background, setBackground] useStatestring(DEFAULT_BACKGROUND); useFrontendTool({ name: change_background, description: Change the page background. Accepts any valid CSS background value — colors, linear or radial gradients, etc., parameters: z.object({ background: z .string() .describe(The CSS background value. Prefer gradients.), }), handler: async ({ background }) { setBackground(background); return { status: success }; }, }); useFrontendToolsSuggestions(); // ... }useFrontendTool各配置项详解配置项作用本演示中的值name工具的唯一标识必须与后端声明的工具名一致否则 Agent 无法把工具调用路由到前端change_backgrounddescription工具能力描述是 LLM 决定何时调用的关键依据Change the page background. Accepts any valid CSS background value — colors, linear or radial gradients, etc.parameters使用 Zod schema 定义参数结构会被转换为工具签名暴露给 LLMz.object({ background: z.string().describe(The CSS background value. Prefer gradients.) })handler实际执行函数接收 LLM 填充的参数运行在浏览器端返回值会作为工具结果回传给 Agentasync ({ background }) { setBackground(background); return { status: success }; }几个关键实现细节Zod 描述即 LLM 提示parameters用 Zod 定义其中.describe(...)里的文字Prefer gradients会被原样带入工具 schema引导 LLM 生成更符合期望的参数值。这与后端 Python docstring 中的 Prefer gradients 前后呼应保证前后端对参数的语义约束一致。Handler 是纯前端闭包handler直接操作 React 的setState无需任何网络请求即可改变界面它返回{ status: success }作为工具执行结果Agent 拿到结果后可继续组织回复。自动广告Auto-advertise按演示 README 的说明CopilotKit 会自动把该工具广告给 AgentCopilotKit automatically advertises the tool to the agent开发者无需在运行时层面做额外的工具注册只需保证useFrontendTool的name与后端工具名匹配。被操作对象Background 容器工具改变的不是一个魔法变量而是一个真实的 DOM 容器。background.tsx 定义了默认值与容器// Solid indigo by default — gives the demo a clean canvas while the agents // change_background tool is the star of the show. export const DEFAULT_BACKGROUND #4f46e5; export function Background({ background, children }) { return ( div >useConfigureSuggestions({ suggestions: [ { title: Sunset theme, message: Make the background a sunset gradient. }, { title: Forest theme, message: Switch to a deep green forest gradient. }, { title: Cosmic theme, message: Make it a navy → magenta cosmic gradient. }, ], available: always, });用户点击Sunset theme等按钮实际发送的是message字段的完整自然语言指令由 Agent 解析后再调用change_background。这既降低了用户的使用门槛也为测试提供了稳定的输入。四、QA 检查清单逐条解读从清单到代码与测试的双向印证qa/frontend-tools.md 是本次演示的手工 QA 清单共分前置条件与三大检查块。下面逐条对照源码与测试说明该检查为什么存在、对应的实现证据在哪。前置条件Demo deployed at/demos/frontend-toolsAgent backend healthy演示页面路由即 src/app/demos/frontend-tools/page.tsxNext.js App Router 按目录生成/demos/frontend-tools路径。Agent backend healthy要求 Agno 后端src/agents/main.py与/api/copilotkit运行时路由正常因为前端工具的执行虽然发生在浏览器但工具的触发决策LLM 推理仍然依赖后端 Agent 的在线状态。检查块 1基础功能导航到/demos/frontend-tools验证聊天框渲染placeholder 为 Type a message验证data-testidbackground-container可见且为默认背景这些手工步骤在端到端测试中都有自动化对应frontend-tools.spec.tstest(page loads with chat input and background container, async ({ page }) { await page.goto(/demos/frontend-tools); await expect(page.getByPlaceholder(Type a message)).toBeVisible(); await expect( page.locator([data-testidfrontend-tools-background]), ).toBeVisible(); }); test(background container starts with the solid indigo default, async ({ page }) { const bg page.locator([data-testidfrontend-tools-background]); const initial await bg.getAttribute(style); expect(initial ?? ).toContain(#4f46e5); });注意一个值得留意的细节QA 清单中写的 testid 是background-container而当前源码 background.tsx 与 e2e 测试实际使用的 testid 是frontend-tools-background。这说明清单与实现可能存在版本漂移——在手工执行 QA 时应以当前源码中的data-testidfrontend-tools-background为准。这本身也提醒我们QA 清单需要与测试代码保持同步testid 这类测试契约一旦变更清单和断言都要一起更新。检查块 2功能特定检查核心链路提问 Change the background to a blue-to-purple gradient验证change_background前端工具被调用且 background-container 的样式发生变化这是整个清单的核心验证自然语言 → LLM 决策 → 前端工具执行 → 界面状态变更的完整闭环。其链路为用户在CopilotSidebar输入框输入或点击建议按钮如 Make the background a sunset gradient.Agno Agentmain.py模型OpenAIChat(idgpt-4o, timeout120)基于系统指令Only call change_background when the user explicitly asks to change colors/background决定调用工具工具调用通过/api/copilotkit运行时被路由到浏览器端useFrontendTool注册的handler执行setBackground(background)Background容器的style{{ background }}更新700ms 过渡后背景变为用户要求的渐变。e2e 测试没有去断言 LLM 生成的文本而是断言可观察的副作用inline style 的变化——这是前端工具测试的正确姿势。测试注释中写得很清楚frontend-tools.spec.tsWe assert on the observable side effect (inline style changes) rather than on any LLM-generated text.例如Sunset 主题测试轮询 style 属性要求出现linear-gradient或radial-gradienttest(Sunset theme pill triggers a gradient change, async ({ page }) { await page.getByRole(button, { name: /Sunset theme/i }).click(); const bg page.locator([data-testidfrontend-tools-background]); await expect .poll( async () { const s (await bg.getAttribute(style)) ?? ; return /linear-gradient|radial-gradient/.test(s); }, { timeout: 45000 }, ) .toBe(true); });这里有两个测试要点值得学习用.poll()而非即时断言LLM 推理 网络往返需要时间45 秒轮询超时给足链路余量同时最终收敛到确定的状态断言断言泛化模式而非精确值Sunset 主题断言linear-gradient|radial-gradient正则而不是写死某个渐变色因为 LLM 每次生成的渐变参数可能不同——只要工具的类别性副作用产生了渐变背景成立就算调用成功。类似的Forest 主题测试则断言 style 离开默认值#4f46e5test(Forest theme pill mutates the background inline style, async ({ page }) { await page.getByRole(button, { name: /Forest theme/i }).click(); const bg page.locator([data-testidfrontend-tools-background]); await expect .poll(async () { const s (await bg.getAttribute(style)) ?? ; return !s.includes(#4f46e5); }, { timeout: 45000 }) .toBe(true); });检查块 3错误处理无未捕获的控制台错误这条检查对应前端工具链路中的一个真实风险点如果useFrontendTool的name与后端工具名不匹配或handler抛出异常、返回值格式不符合协议浏览器控制台会出现未捕获错误且 Agent 可能收不到工具结果。因此 QA 阶段应打开 DevTools Console 全程观察e2e 阶段同样可以在 Playwright 的page.on(console)/page.on(pageerror)中注册监听把无控制台错误转成自动化断言。五、底层支撑运行时如何把工具调用送到浏览器前端工具之所以能工作依赖 CopilotKit 的运行时协议在前后端之间传递工具调用。从 main.py 的 Agent 配置可以反推几项关键支撑设计agent Agent( modelOpenAIChat(idgpt-4o, timeout120), db_create_session_db(), # SQLite 会话存储位于可写的 /tmp/agno.db tools[...change_background...], tool_call_limit15, # 防止工具调用死循环 ... )会话可恢复db注释指出Frontend and HITL tools pause the run before the browser responds——前端工具的执行会暂停 Agent 的 run等待浏览器端 handler 完成后恢复。因此 Agent 的会话必须持久化到可恢复的存储这里是 SQLite否则工具结果回来后无法续跑。tool_call_limit15限制单次 run 的工具调用次数防止 LLM 陷入工具调用死循环Prevent runaway tool-call loops — same guard as the ag2 package。超时放宽timeout120前端工具的链路更长LLM → 运行时 → 浏览器 → 回传默认 httpx 超时太短会触发 Request timed out所以显式提升到 120 秒。这些配置共同保证了change_background这类暂停-恢复型工具在高延迟链路下的可靠性是前端工具落地时必须同步考虑的运行时因素。六、实战建议如何在自己的应用中复刻这套模式结合本演示在自研应用中落地前端工具推荐按以下步骤后端声明工具壳在 Agno或其他支持external_execution的框架中用tool(external_executionTrue)声明工具签名与 docstringdocstring 里写清楚触发条件如仅在用户明确要求时调用与参数约束如接受任意合法 CSS background 值优先渐变前端注册同名工具用useFrontendTool({ name, description, parameters, handler })注册确保name与后端一致parameters用 Zod 定义并在.describe()中补充对 LLM 的引导把状态接到真实 UIhandler 中更新 React state并将被操作容器暴露data-testid与data-background-value之类的可观测锚点为测试和 QA 提供稳定的定位与断言接口提供建议入口用useConfigureSuggestions配置几个高频场景的建议按钮降低触发门槛同时给自动化测试提供确定性的输入测试断言副作用Playwright 中轮询断言 UI 的可观察变化style、DOM 属性而不是断言 LLM 文本对渐变等 LLM 可能给出不同参数值的场景用正则做类别级断言QA 清单与测试同步维护像本仓库那样让 qa/frontend-tools.md 与 frontend-tools.spec.ts 相互对应testid 等测试契约变更时双向更新避免清单漂移。七、总结CopilotKit 的 Frontend ToolsIn-App Actions为Agent 驱动的 UI提供了一条简洁而完整的路径后端声明、前端执行、运行时桥接。本仓库的frontend-tools演示用不足百行的前端代码实现了一句话改掉整页背景的完整能力闭环并以一份 QA 清单 一组 Playwright 测试把这条链路变成了可反复验证的工程实践。无论是继续探索 src/app/demos/frontend-tools/page.tsx 的注册细节、src/agents/main.py 的external_execution机制还是直接运行 tests/e2e/frontend-tools.spec.ts 观察测试如何断言副作用你都可以从当前仓库获得一手证据。核心方法论只有一句让 Agent 拥有点击界面的能力并用可观察的 DOM 副作用来证明它真的做到了。【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价