尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CopilotKit Tool Rendering 自定义 Catch-all 实战:基于 Agno 后端的通配符工具渲染器与 QA 验证

CopilotKit Tool Rendering 自定义 Catch-all 实战:基于 Agno 后端的通配符工具渲染器与 QA 验证 CopilotKit Tool Rendering 自定义 Catch-all 实战基于 Agno 后端的通配符工具渲染器与 QA 验证【免费下载链接】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 集成的tool-rendering-custom-catchall演示与 QA 手册为核心深入讲解如何通过useDefaultRenderTool注册单个品牌化通配符wildcard渲染器让所有后端工具调用共享同一套自定义 UI并给出完整的 QA 验证清单与 Playwright 自动化测试对照。读完本文你将掌握 V2 SDK 中工具调用渲染的注册机制、默认渲染器与自定义渲染器的替换路径以及如何用 testid 驱动的 E2E 用例验证多工具、多卡片、链式调用等复杂场景。一、这个 Demo 解决什么问题CopilotKit 的 Agno 集成示例位于 showcase/integrations/agno按功能划分成多个「cell」其中 Tool Rendering 系列专门演示工具调用结果如何在聊天流中渲染。该系列存在一个渐进式的实现梯度默认 catch-alltool-rendering-default-catchall使用框架内置的默认工具调用卡片自定义 catch-alltool-rendering-custom-catchall即本文主题退出一揽子默认 UI用单个自定义通配符渲染器接管所有工具调用Reasoning Chain 变体tool-rendering-reasoning-chain在前者基础上叠加 AG-UI 推理链事件渲染。在 manifest.yaml 中tool-rendering-custom-catchall被描述为Single branded wildcard renderer viauseDefaultRenderTool高亮文件包括后端 src/agents/main.py、前端页面、渲染器组件以及运行时路由 src/app/api/copilotkit/route.ts。QA 手册 qa/tool-rendering-custom-catchall.md 就是针对该 cell 的验收文档它要求 demo 部署在/demos/tool-rendering-custom-catchall后端 agent 健康并逐项验证品牌化 catch-all 卡片在天气、航班、骰子、工具链四个场景下的渲染行为。二、核心机制useDefaultRenderTool通配符渲染2.1 从useRenderTool到useDefaultRenderTool自定义 catch-all 的关键在 V2 SDK 提供的useDefaultRenderTool。其源码位于 packages/react-core/src/v2/hooks/use-default-render-tool.tsx本质是对useRenderTool的便捷封装export function useDefaultRenderTool( config?: { render?: (props: DefaultRenderProps) React.ReactElement | null; }, deps?: ReadonlyArrayunknown, ): void { // 用户未提供 render 时回退到框架内置 DefaultToolCallRenderer const registered userRender ? (raw) userRender(adaptRendererProps(raw)) : (raw) DefaultToolCallRenderer {...adaptRendererProps(raw)} /; useRenderTool( { name: *, render: registered /* ... */ }, deps, ); }它注册的渲染器名是*——即通配符凡是未被具名渲染器useRenderTool({ name: get_weather, ... })认领的工具调用都会落到这个 wildcard 渲染器上。因此它天然是「catch-all」get_weather、search_flights、roll_d20乃至未来新增的任何后端工具都会被同一组件接管。2.2 渲染器收到的 props 契约useDefaultRenderTool暴露给自定义render的 props 类型为DefaultRenderPropsexport type DefaultRenderProps { name: string; // 被调用工具名如 get_weather toolCallId: string; // 本次工具调用的 id parameters: unknown; // 解析后的工具入参 status: inProgress | executing | complete; // 执行状态 result: string | undefined; // 结果字符串仅 status complete 时存在 };框架内部传给注册渲染器的原始形状是{ name, toolCallId, args, status: ToolCallStatus, result }其中status是枚举ToolCallStatus。useDefaultRenderTool通过adaptRendererProps把args映射为文档契约中的parameters并通过mapToolCallStatus将枚举映射为字符串联合类型遇到未知/未来的枚举值时会输出一次 console 警告并回退到inProgress去重集合warnedUnknownStatuses保证同一异常状态只警告一次。这意味着你的自定义渲染器永远收到文档化、稳定的 props 形状不依赖框架内部实现细节。2.3 与框架内置默认渲染器的关系不传render直接调用useDefaultRenderTool()时会渲染框架内置的DefaultToolCallRenderer——一个带展开/收起交互的卡片外层容器带data-testidcopilot-tool-render。而传入自定义render后内置卡片被完全替换。这条差异是 QA 验证「确实渲染的是自定义组件而非框架兜底」的关键判据详见第四节。三、Demo 实现拆解3.1 页面注册一行通配符声明页面入口 page.tsx 中Chat组件通过useDefaultRenderTool注册唯一的自定义渲染器function Chat() { // useDefaultRenderTool 是 useRenderTool({ name: *, ... }) 的便捷封装 // 单个通配符渲染器接管所有未被具名渲染器认领的工具调用。 useDefaultRenderTool( { render: ({ name, parameters, status, result }) ( CustomCatchallRenderer name{name} parameters{parameters} status{status as CatchallToolStatus} result{result} / ), }, [], ); useSuggestions(); return ( CopilotChat agentIdtool-rendering-custom-catchall classNameh-full rounded-2xl / ); }页面外层CopilotKit指定了runtimeUrl/api/copilotkit与agenttool-rendering-custom-catchall。后端路由 src/app/api/copilotkit/route.ts 将tool-rendering-custom-catchall归入mainAgentNames数组通过HttpAgent代理到AGENT_URL/agui默认http://localhost:8000即复用 Agno 主 agent以 AG-UI 协议完成前后端通信。每个 demo cell 的 agent 名都做了别名映射保证各 cell 的前端工具/组件注册作用域互不干扰。3.2 渲染器组件品牌化的通用卡片custom-catchall-renderer.tsx 是单个 ShadCN 风格的卡片组件负责呈现所有工具调用。其核心结构如下已省略部分样式export type CatchallToolStatus inProgress | executing | complete; export interface CustomCatchallRendererProps { name: string; status: CatchallToolStatus; parameters: unknown; result: string | undefined; } export function CustomCatchallRenderer({ name, status, parameters, result }) { const parsedResult parseResult(result); const done status complete; return ( Card>tool def get_weather(location: str): Get the weather for a given location. Ensure location is fully spelled out. Args: location (str): The location to get the weather for. Returns: str: Weather data as JSON. return json.dumps(get_weather_impl(location))同文件还包含search_flights(flights: list[dict])等工具以及按 PARITY_NOTES 记录的roll_dice系列工具。前端这些工具的入参、状态、结果全部流经同一个通配符渲染器——这正是「catch-all」的语义体现。四、QA 验证步骤详解QA 手册 qa/tool-rendering-custom-catchall.md 定义了本 cell 的完整验收流程下面逐节展开并给出判据背后的实现依据。4.1 前置条件Demo 已部署可通过/demos/tool-rendering-custom-catchall访问manifest 中 route 字段确认了该路径Agent 后端健康运行时路由的GET /api/copilotkit健康探针会请求${AGENT_URL}/health并返回agent_status: reachable见 route.ts可用作后端健康检查手段。4.2 测试步骤 1基础功能打开/demos/tool-rendering-custom-catchall验证聊天界面正常渲染且展示建议词suggestion pills。对应实现四个建议词由useConfigureSuggestions提供聊天主体为CopilotChat。自动化侧Playwright 用例会等待输入框 placeholder Type a message 可见并逐一断言 4 个建议词按钮data-testidcopilot-suggestion可见见 tests/e2e/tool-rendering-custom-catchall.spec.ts。4.3 测试步骤 2功能专项检查点击 Weather in SF 后逐项验证品牌化 catch-all 卡片渲染QA 手册写作data-testidcustom-catchall-carddata-testidcustom-catchall-tool-name显示get_weatherdata-testidcustom-catchall-status最终显示 donedata-testidcustom-catchall-args与data-testidcustom-catchall-result正常渲染。命名差异提示仓库实际渲染器与 E2E 测试使用的 testid 前缀是custom-wildcard-*如custom-wildcard-card、custom-wildcard-tool-name、custom-wildcard-status、custom-wildcard-args、custom-wildcard-result而 QA 手册写作custom-catchall-*。执行手工 QA 时请按实际代码中的custom-wildcard-*定位元素语义一一对应card卡片容器、tool-name工具名、status状态徽章、args参数、result结果。另外卡片容器上的data-tool-name{name}属性可直接用于区分同一通配符外壳下的不同工具。关于状态流转点击建议词后卡片会经历streaminginProgress→runningexecuting→donecomplete三个阶段最终停在绿色 done 徽章结果区从 waiting for tool to finish… 切换为渲染好的 JSON 结果。4.4 测试步骤 3错误处理无未捕获的 console 错误。这条要求在自动化侧同样被严格执行渲染器内部所有可能抛错的点JSON 序列化、结果解析都有 try/catch 兜底SDK 侧对未知工具状态也只做一次性警告。若出现红色错误流说明渲染链路前端注册 → 运行时转发 → Agno AGUI 流存在断点需依次排查 route.ts 的 agent 别名、后端/agui接口及AGENT_URL配置。五、E2E 自动化验证QA 手册的机器可执行版qa 同目录的 Playwright 用例是 QA 手册的自动化镜像测试套件名Tool Rendering — Custom Catch-all (branded wildcard)覆盖 6 个关键场景页面加载composer 可见 4 个建议词就位同时做「负向断言」——兄弟 cell 的具名 testidweather-card、flights-card、stock-card、d20-card以及框架默认渲染器的copilot-tool-render计数均为 0证明当前页面确实由自定义通配符接管天气点击 Weather in SF断言custom-wildcard-card[data-tool-nameget_weather]出现、工具名文本为get_weather、args 区包含 San Francisco航班断言search_flights走同一外壳且结果区包含确定性航班/United|Delta|JetBlue/掷骰子roll_d20恰好渲染 5 张卡片agent 连续调用 5 次第 5 张结果包含value: 20前 4 张均非 20链式调用Chain tools 一屏挂载get_weathersearch_flightsroll_d20三张同外壳卡片统一签名跨工具断言所有卡片共享同一 wildcard 外壳tool-name 计数 args 计数 卡片总数且copilot-tool-render仍为 0——证明绘制来自单个自定义通配符而非框架兜底。用例还包含一个重要的回归场景第 6 个测试历史 bug 中d20 与 Chain-tools 的 fixture 依赖全局线程状态turnIndex、hasToolResult驱动顺序导致先点 Find flights 再点 Roll a d20 时只渲染 3 张而非 5 张、Chain-tools 的工具卡片被整体跳过。修复方案是所有后续调用均通过toolCallId串联。回归测试在同一会话内连续点击 Find flights → Roll a d20 → Chain tools断言卡片总数精确为 1 5 3 9最终文本 Done — Tokyo is sunny 可见由于多工具链叠加 LLM-mock 延迟该用例将超时上调到 240 秒。六、进阶从默认渲染到推理链理解自定义 catch-all 后可以沿 Tool Rendering 系列继续扩展对照兄弟 cell tool-rendering/page.tsx 可看到完整版实现useDefaultRenderTool与useRenderTool具名渲染器并存未认领工具回退到通配符基于自定义 catch-all 的 tool-rendering-reasoning-chain 在同一个通配符外壳上叠加 AG-UI 的REASONING_MESSAGE_*事件渲染推理链 agent 挂载于/reasoning/agui由 route.ts 的reasoningAgentNames提供别名其 QA 手册见 qa/tool-rendering-reasoning-chain.md。因此本文所讲的「一个组件接管所有工具」不是孤立的炫技而是工具渲染体系中「先统一外壳、再按需精细化」策略的第一级落地先在品牌外壳上保证全工具覆盖与 QA 可测性再针对高频工具注册具名渲染器做差异化体验。七、QA 自查清单可直接照做检查项判据定位页面可达/demos/tool-rendering-custom-catchall正常加载manifest.yaml 中 route建议词渲染4 个 pills 可见copilot-suggestiontestid通配符接管任意工具调用均出现custom-wildcard-card且copilot-tool-render计数为 0渲染器 E2E 负向断言工具名卡片头部显示真实工具名get_weather等custom-wildcard-tool-name状态终态最终状态徽章为 donecustom-wildcard-status参数与结果custom-wildcard-args/custom-wildcard-result渲染出格式化 JSON渲染器parseResult/safeStringify多工具一致性同一外壳渲染不同工具、卡片按调用序列追加data-tool-name属性 E2E 计数断言控制台无未捕获错误浏览器 DevTools / Playwright 收集【免费下载链接】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),仅供参考
返回列表