CopilotKit Tool-Based Generative UI:用 useComponent 将 Agent 工具调用渲染为自定义 React 组件

发布时间:2026/9/12 1:29:55
CopilotKit Tool-Based Generative UI:用 useComponent 将 Agent 工具调用渲染为自定义 React 组件 CopilotKit Tool-Based Generative UI用 useComponent 将 Agent 工具调用渲染为自定义 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 仓库内置示例gen-ui-tool-basedTool-Based Generative UI展开讲解“受控生成式 UI”的核心模式Agent 调用一个返回结构化数据的工具前端不再以纯文本展示结果而是通过useComponent把该工具调用映射为自定义 React 组件如柱状图、饼图并根据args参数、result结果与status状态呈现加载态与完成态。读完本文你将掌握useComponent的注册机制、Zod 参数 Schema 的写法、渲染器生命周期、后端 Agent 的系统提示词配置以及对应的端到端测试验证方式。一、什么是 Tool-Based Generative UI在传统聊天界面中Agent 调用工具后无论返回多复杂的数据前端通常只能把结果以文本形式输出。Tool-Based Generative UI 改变了这一范式Agent 调用一个返回结构化数据的工具前端将该工具结果渲染为自定义 React 组件而不是纯文本。这是 CopilotKit 中“受控生成式 UIcontrolled generative UI”的一种实现——UI 形态不是由 Agent 自由组合而是由开发者预先注册好的组件集合决定Agent 负责“选哪个组件、填什么数据”。这种模式适合图表、卡片、表单等数据形态相对固定的场景既保留了 Agent 的自主决策能力又保证界面风格与交互体验完全可控。在仓库的示例清单 showcase/integrations/built-in-agent/manifest.yaml 中该示例的正式定义为名称Generative UI: useComponent描述Agent 使用工具来触发 UI 生成Agent uses tools to trigger UI generation路由/demos/gen-ui-tool-based标记controlled-generative-ui示例自身源码位于 showcase/integrations/built-in-agent/src/app/demos/gen-ui-tool-based/ 目录由 4 个文件组成page.tsx聊天页面与渲染器注册、bar-chart.tsx柱状图组件、pie-chart.tsx饼图组件、suggestions.ts建议提示词。二、核心 APIuseComponent 注册渲染器在 page.tsx 中整个演示的核心只有两处useComponent调用——把工具名映射到渲染组件use client; import { CopilotChat, CopilotKit, useComponent } from copilotkit/react-core/v2; import { BarChart, barChartPropsSchema } from ./bar-chart; import { PieChart, pieChartPropsSchema } from ./pie-chart; import { useSuggestions } from ./suggestions; function Chat() { useComponent({ name: render_bar_chart, description: Display a bar chart with labeled numeric values., parameters: barChartPropsSchema, render: BarChart, }); useComponent({ name: render_pie_chart, description: Display a pie chart with labeled numeric values., parameters: pieChartPropsSchema, render: PieChart, }); useSuggestions(); return ( div classNameflex justify-center items-center h-screen w-full div classNameh-full w-full max-w-4xl CopilotChat agentIdgen-ui-tool-based classNameh-full rounded-2xl / /div /div ); } export default function ControlledGenUiDemo() { return ( CopilotKit runtimeUrl/api/copilotkit agentgen-ui-tool-based Chat / /CopilotKit ); }2.1 配置项说明配置项类型作用namestring工具名Agent 在对话中会以该名称发起工具调用同时作为渲染器匹配的键descriptionstring给模型的工具描述帮助 Agent 判断何时调用该组件parametersStandard Schema V1如 Zod工具入参的结构化 Schema同时用于推导渲染组件的 props 类型renderComponentType实际渲染的 React 组件组件接收 Schema 推断出的 propsagentIdstring可选限定该渲染器只作用于指定 AgentfollowUpboolean可选是否允许渲染后的组件继续触发后续对话2.2 useComponent 的底层实现从 packages/react-core/src/v2/hooks/use-component.tsx 的源码可以看到useComponent是useFrontendTool的便捷封装它自动拼接出一段面向模型的工具描述前缀const prefix Use this tool to display the ${config.name} component in the chat. This tool renders a visual UI component for the user.; const fullDescription config.description ? ${prefix}\n\n${config.description} : prefix;随后把name、description、parameters转发给useFrontendTool渲染时把工具参数透传给注册的组件render: ({ args }: { args: unknown }) { const Component config.render; return Component {...(args as InferRenderPropsTSchema)} /; },也就是说渲染器注册之后会同时做两件事一是把工具声明注册进 Agent 可用的工具集模型看到的是工具名 描述 参数 Schema二是在聊天流中挂载同名的渲染器渲染器会处理历史消息中的工具调用渲染。这也是 Tool-Based Generative UI 中“Agent 调工具、前端渲染组件”的契约来源。三、用 Zod 定义组件参数让模型按 Schema 填数据为了让 Agent 生成的结构化数据能安全地进入 React 组件示例使用 Zod 为每个图表组件定义了参数 Schema并借助z.infer获得类型安全的 props。bar-chart.tsx 与 pie-chart.tsx 中的 Schema 完全一致import { z } from zod; export const barChartPropsSchema z.object({ title: z.string().describe(Chart title), description: z.string().describe(Brief description or subtitle), data: z.array( z.object({ label: z.string(), value: z.number(), }), ), }); export type BarChartProps z.infertypeof barChartPropsSchema;Schema 的要点title、description是图表标题与副标题describe()中的提示文本会随工具描述一起交给模型让模型生成更贴合语义的字段data是{ label, value }数组label为分类名value为数值通过z.infer导出BarChartProps类型useComponent会把该类型推断为render组件的 props实现端到端类型安全。3.1 渲染组件的实现要点BarChart组件基于 recharts 实现并针对“流式/增量到达的数据”做了动画处理它用useRef(new Setnumber())记录已经渲染过的数据下标只有新到达的 bar 才播放barSlideIn入场动画避免每次数据更新都整体重播const seen useRef(new Setnumber()); const isNew (i: number) { if (seen.current.has(i)) return false; seen.current.add(i); return true; };PieChart则用纯 SVG 绘制环形图先计算circumference圆周长再为每个数据项计算strokeDasharray{arc gap}与strokeDashoffset实现扇区切分并在图下方输出每个分类的数值与百分比。两个组件都处理了data为空的情况渲染“No data available”的兜底卡片——这在模型尚未产出数据时保证界面不崩溃。四、渲染器的生命周期args、result 与 statusREADME 中明确指出渲染器会收到args、result和status因此 UI 可以分别展示加载中与完成状态。这一契约在 packages/react-core/src/v2/hooks/use-render-tool.tsx 中以“判别联合”类型完整定义export interface RenderToolInProgressPropsS extends StandardSchemaV1 { name: string; toolCallId: string; parameters: PartialInferSchemaOutputS; status: inProgress; result: undefined; } export interface RenderToolExecutingPropsS extends StandardSchemaV1 { name: string; toolCallId: string; parameters: InferSchemaOutputS; status: executing; result: undefined; } export interface RenderToolCompletePropsS extends StandardSchemaV1 { name: string; toolCallId: string; parameters: InferSchemaOutputS; status: complete; result: string; }三个阶段与渲染器的对应关系为inProgress工具调用已开始、参数可能尚不完整parameters为部分值此时可渲染占位/加载 UIexecuting参数完整parameters为完整 Schema 输出工具正在执行可展示“正在处理”的状态complete工具执行完成result携带返回结果渲染器此时展示最终组件。在 use-render-tool.tsx 的注册逻辑中status分支被显式处理确保判别联合类型在args重新暴露为parameters后仍然相关而 use-frontend-tool.tsx 进一步说明了注册时的去重策略同名工具重复注册时会先console.warn提示并用最新注册覆盖卸载时移除工具声明但刻意保留渲染器保证历史聊天中的工具调用仍然可以正常渲染。在gen-ui-tool-based演示里图表组件直接消费parameterstitle、description、data因此加载态由 CopilotChat 的默认工具调用气泡兜底完成态即渲染出的图表卡片。五、后端协同命名 Agent 注册与系统提示词前端声明了工具后端则需要一个知道“何时调用这些工具”的 Agent。演示的后端在 showcase/integrations/built-in-agent/src/app/api/copilotkit/route.ts 中以命名 Agent 的方式注册gen-ui-tool-based: createBuiltInAgent({ systemPrompt: GEN_UI_TOOL_BASED_PROMPT, }),该 Agent 使用进程内运行的InMemoryAgentRunner无独立 Agent 服务并附带针对本演示的专用系统提示词GEN_UI_TOOL_BASED_PROMPT定义在 showcase/integrations/built-in-agent/src/lib/factory/demo-prompts.tsYou are a data visualization assistant. When the user asks for a chart, call render_bar_chart or render_pie_chart with a concise title, short description, and a data array of {label, value} items. Pick bar for comparisons over a small set of categories; pick pie for composition / share-of-whole. If the user names a chart subject but does NOT supply concrete numbers (e.g. show me a pie chart of website traffic by source), do NOT ask them for data. Invent plausible illustrative sample values yourself, call the appropriate render_* tool immediately, and briefly note in the follow-up that the values are illustrative samples. Always render the chart on the first turn -- never reply with a clarifying question asking for the data. Every value MUST be a non-zero number. Never emit placeholder zeros. Keep chat responses brief -- let the chart do the talking.这段提示词值得细读它把“模型行为规范”写进了 Agent 配置工具选择策略比较多个分类时用柱状图表示构成/占比时用饼图数据补全策略用户只给主题不给数据时不允许反问直接自造合理的示例数据并调用工具这一条直接规避了模型“反问用户要数据”的常见失败模式数据质量红线所有value必须非零禁止用占位零值源码注释记录了该提示词的来历——模型曾回答“我用了占位值”并绘制出全零图表回复风格聊天回复保持简短让图表本身说话。5.1 前后端工具如何汇合Agent 侧的工具面在 showcase/integrations/built-in-agent/src/lib/factory/tanstack-factory.ts 中组装服务端工具stateTools、baseServerTools、subagentTools与来自 AG-UI 协议的前端工具useComponent、useRenderTool、useFrontendTool注册的会被合并后一起声明给模型。关键逻辑是按名称去重凡是服务端已注册的工具名前端同名注册不会重复声明前端工具则以“仅声明、由前端执行”的方式参与模型发起调用后由聊天流事件驱动前端渲染器。这正是 Tool-Based Generative UI 能在“模型自主决定 前端可控渲染”之间取得平衡的底层机制。六、建议提示词引导用户发起图表请求为了让演示开箱即用suggestions.ts 通过useConfigureSuggestions配置了三枚常驻建议按钮use client; import { useConfigureSuggestions } from copilotkit/react-core/v2; export function useSuggestions() { useConfigureSuggestions({ suggestions: [ { title: Sales bar chart, message: Show me a bar chart of quarterly sales for Q1, Q2, Q3, Q4. }, { title: Traffic pie chart, message: Show me a pie chart of website traffic by source. }, { title: Market share, message: Show a pie chart of smartphone market share by brand. }, ], available: always, }); }available: always表示建议始终可用而非仅在空对话时展示。点击建议按钮即自动发送对应的message让用户无需动脑即可触发图表生成。其中“Traffic pie chart”与“Market share”刻意不给具体数字用于演示系统提示词中“自动补全示例数据”的行为。七、端到端验证与本地运行7.1 端到端测试该演示配有 Playwright 端到端测试 showcase/integrations/built-in-agent/tests/e2e/gen-ui-tool-based.spec.ts覆盖了四条关键断言页面加载后聊天输入框与三枚建议按钮data-testidcopilot-suggestion可见发送 “Show me a pie chart of revenue by category” 后助手消息data-testidcopilot-assistant-message内出现 SVG 可视化发送 “Show me a bar chart of monthly expenses” 后同样出现 SVG 可视化普通文本消息能正常获得助手回复。这些用例既验证了渲染器注册生效也验证了普通对话能力不受影响是复现与回归该功能的可靠基准。7.2 本地运行方式built-in-agent示例支持通过 CLI 一键初始化见 manifest.yaml 的cli-start入口npx copilotkitlatest init --framework built-in-agent初始化后启动 Next.js 开发服务访问/demos/gen-ui-tool-based即可体验在对话中输入“Show me a bar chart of quarterly sales…”Agent 会调用render_bar_chart前端随即渲染出带标题、副标题与七色配色的柱状图卡片。整个 Agent 运行在 Next.js 路由处理器内/api/copilotkit无需单独启动 Agent 服务。八、与其他 Generative UI 模式的边界同仓库的 manifest.yaml 将本示例标记为controlled-generative-ui与相邻模式形成清晰对比Tool Rendering工具渲染同样是为“具名后端工具”挂自定义渲染器如WeatherCard强调“把某个后端工具的结果画成卡片”而useComponent更偏向“Agent 用工具触发 UI 生成”组件注册在前端、模型按 Schema 填参。Declarative UI / A2UI声明式 UIAgent 直接输出 UI 树如Card、StatusBadge前端按目录catalog映射渲染属于“模型自由编排”而本演示的组件集合固定、参数由 Schema 约束属于“模型受限选择 数据注入”。gen-ui-agentAgent State 驱动通过共享状态流驱动 UI 更新本演示则是工具调用结果驱动一次性渲染。选择哪种模式取决于你的 UI 形态是“少量固定组件选图表”还是“模型动态拼装界面自由画布”。Tool-Based Generative UI 的定位正是前者把结构化工具结果安全、类型化地变成第一方 React 组件。参考资料仓库内演示源码showcase/integrations/built-in-agent/src/app/demos/gen-ui-tool-based/示例清单条目showcase/integrations/built-in-agent/manifest.yaml后端 Agent 注册showcase/integrations/built-in-agent/src/app/api/copilotkit/route.ts系统提示词showcase/integrations/built-in-agent/src/lib/factory/demo-prompts.ts工具合并逻辑showcase/integrations/built-in-agent/src/lib/factory/tanstack-factory.ts渲染器状态类型packages/react-core/src/v2/hooks/use-render-tool.tsxuseComponent 实现packages/react-core/src/v2/hooks/use-component.tsxuseFrontendTool 实现packages/react-core/src/v2/hooks/use-frontend-tool.tsx端到端测试showcase/integrations/built-in-agent/tests/e2e/gen-ui-tool-based.spec.ts【免费下载链接】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),仅供参考