用 `useDefaultRenderTool` 为 Google ADK Agent 实现品牌化通配工具渲染:CopilotKit Custom Catch-all 实战与 QA 验证
2026/9/13 5:09:37 网站建设 项目流程

useDefaultRenderTool为 Google ADK Agent 实现品牌化通配工具渲染:CopilotKit Custom Catch-all 实战与 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 的 v2 React 核心中,useDefaultRenderTool是一个"通配(wildcard)"级别的工具渲染器注册入口:它只注册一个渲染组件,接管页面上所有未被具名渲染器认领的工具调用。本文以 CopilotKit 仓库中 Google ADK 集成示例tool-rendering-custom-catchall(演示页、渲染器、后端 Agent、Playwright 端到端测试、QA 清单)为主线,完整讲解这种"单一品牌化卡片 + 全工具通用"的渲染策略:如何注册、卡片如何表达工具名/状态/参数/结果、状态机如何从streaming走到done,以及如何在 QA 阶段用确定性断言验证"零具名渲染器、所有工具共用同一张品牌卡片"这一核心不变量。读完你将能照抄该模式到自己的 Agent 前端,并写出可复用的工具渲染回归测试。

1. 场景定位:Custom Catch-all 在工具渲染演进中的位置

在 showcase/integrations/google-adk 集成包中,tool-rendering系列演示共同构成了一条"工具渲染能力演进"的渐进线:

  • 默认工具渲染(默认兜底):完全依赖 CopilotKit 内置的DefaultToolCallRenderer,零自定义;
  • Custom Catch-all(本文主角):注册一个自定义通配渲染器,替换掉内置默认 UI,但暂不按工具名做差异化——所有工具共用一张品牌卡片;
  • 按工具具名渲染(reasoning-chain 等变体):在通配渲染器之上再叠加useRenderTool({ name: "get_weather", ... })之类的具名注册,实现每工具专属 UI。

三条路径共享同一套后端工具面。自定义通配变体的核心不变量可以浓缩为一句话:零个具名渲染器 + 一个品牌化通配组件 = 每次工具调用都画同一张卡片。这一点在页面源码的头部注释里写得很清楚(page.tsx):

"Same backend tools astool-rendering-default-catchall, but this cell opts out of CopilotKit's built-in default tool-call UI by registering a SINGLE custom wildcard renderer viauseDefaultRenderTool. The same branded card now paints every tool call — no per-tool renderers yet."

2. 前置条件与演示注册链路

2.1 前置条件(来自 QA 清单)

QA 文档(tool-rendering-custom-catchall.md)给出的运行前提是:

  • 演示应用已部署且可访问;
  • Agent 后端健康(检查/api/health);
  • Agent slugtool-rendering-custom-catchall已在/api/copilotkit注册。

这条 slug 链路在仓库里有完整的落点:

  1. 前端页面通过<CopilotKit runtimeUrl="/api/copilotkit" agent="tool-rendering-custom-catchall">绑定 agent 名;
  2. route.ts 中的agentNames数组声明了"tool-rendering-custom-catchall",运行时为每个名字创建一个HttpAgent,代理到 Python 后端的AGENT_URL/<name>(默认http://localhost:8000);
  3. registry.py 的AGENT_REGISTRY把该名字映射到tool_rendering_custom_catchall_agent
  4. 后端agent_server.py遍历注册表,把每个 Agent 以<agent_name>挂载为独立的 ADKAgent 中间件;
  5. manifest.yaml 将该 demo 登记为独立特性(id: tool-rendering-custom-catchallroute: /demos/tool-rendering-custom-catchall)。

也就是说,前端agentprop → Next.js 运行时路由 → Python 后端挂载路径,三层名字必须一致,QA 第 7 步的"slug 已注册"检查才成立。

2.2 前端 Agent 后端定义

后端就是一个标准的 Google ADKLlmAgent(tool_rendering_custom_catchall_agent.py):

tool_rendering_custom_catchall_agent = LlmAgent( name="ToolRenderingCustomCatchallAgent", model=get_model(), instruction=TOOL_RENDERING_INSTRUCTION, tools=[get_weather, search_flights, get_stock_price, roll_d20], after_model_callback=stop_on_terminal_text, )

四个工具来自 tool_rendering_common.py,与tool-rendering基础变体完全一致,且特意与 langgraph-python 集成保持"镜像工具面",以便两组集成共用同一套 aimock 录制夹具和 Playwright 测试。值得注意的细节:

  • get_weather返回确定性的 mock 载荷(temperature: 68humidity: 55wind_speed: 10conditions: "Sunny"),这正是 QA 文档第 1 节要求核对的确切字段;
  • roll_d20value参数与get_stock_priceprice_usd/change_pct参数允许 LLM 或测试夹具传入确定值,测试场景里可据此断言"第 5 张卡片结果恰好是 20";
  • stop_on_terminal_text回调(shared_chat.py)是避免 ADK 代理循环无限重发工具调用的关键守卫,工具渲染 QA 中"链式调用正常收敛"依赖它。

3. 前端注册:一个通配渲染器接管所有工具调用

页面源码 page.tsx 的核心只做了三件事:包CopilotKit、注册通配渲染器、渲染CopilotChat

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 agentId="tool-rendering-custom-catchall" className="h-full rounded-2xl" /> ); }

布局层与 QA 文档描述一致:外层flex justify-center items-center h-screen w-full使聊天界面居中且占满全高,聊天容器max-w-4xl限宽、rounded-2xl圆角。

几个关键点:

  • useDefaultRenderTool就是useRenderTool({ name: "*" }):它注册的是"默认通配"级别。源码注释明确写为 "a convenience wrapper arounduseRenderTool({ name: "*", ... })"——即这个渲染器只在没有具名渲染器匹配时才被调用。在这个 demo 里没有注册任何具名渲染器,因此所有工具调用必然走它;
  • hooks 从@copilotkit/react-core/v2导入CopilotKitCopilotChatuseDefaultRenderTool,这是 v2 核心包的导出路径;
  • useSuggestions来自同目录的 suggestions.ts,通过useConfigureSuggestions提供 4 个建议 pill:
建议标题触发消息
Weather in SFWhat's the weather in San Francisco?
Find flightsFind flights from SFO to JFK.
Roll a d20Roll a 20-sided die.
Chain toolsChain a few tools in this single turn: get the weather in Tokyo, search flights from SFO to Tokyo, and roll a d20.

available: "always"表示建议始终可用。点击建议会填充输入框或直接发送消息(QA 第 1 节的要求),其中 "Chain tools" 用于触发"链式工具调用",验证多张卡片连续渲染。

4. 品牌化通配卡片:CustomCatchallRenderer 的结构与状态机

渲染器本体在 custom-catchall-renderer.tsx。它接收四个入参:name(工具名)、status(三态)、parameters(参数对象)、result(结果字符串),输出一张 shadcn 风格的<Card />

4.1 状态机定义

export type CatchallToolStatus = "inProgress" | "executing" | "complete";

三个内部状态在describeStatus中映射为对外可见的状态徽章(QA 文档提到的"amber → lavender/indigo → green"渐变即来自这里):

内部状态徽章文案徽章变体状态圆点
inProgressstreamingwarningbg-amber-500 animate-pulse(琥珀色呼吸动画)
executingrunningsecondarybg-neutral-500 animate-pulse(灰紫色呼吸动画)
completedonesuccessbg-emerald-500(稳定绿色)

QA 文档中的"过渡streamingrunningdone"即对应这三个状态的顺序流转。

4.2 卡片结构与 contenteditable="false">【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询