CopilotKit A2UI 渲染实战:从两端配置到自定义 Catalog 与避坑指南
CopilotKit A2UI 渲染实战从两端配置到自定义 Catalog 与避坑指南【免费下载链接】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 仓库中packages/a2ui-renderer/skills/a2ui-renderer/SKILL.md编写系统讲解如何在 CopilotKit v2 中渲染A2UIAgent-to-UI 声明式界面涵盖运行时CopilotRuntime与客户端CopilotKitProvider的双端接线、主题定制、自定义组件 Catalog、loading 骨架屏覆盖以及五个高频踩坑点的正确姿势。读完你不仅能十分钟跑通Agent 生成可交互 UI的最小链路还能从源码层理解/info自动探测、createA2UIMessageRenderer自动挂载与 action 桥接的底层机制写出可复用的生产级 A2UI 集成代码。A2UI 的两端架构运行时声明客户端渲染A2UI 在 CopilotKit 中由两半组成缺一不可运行时Runtime在new CopilotRuntime({...})中声明a2ui中间件配置。开启后运行时的/info端点会向客户端广播本运行时支持 A2UI。客户端Client在CopilotKitProvider 上启用a2uiprop。Provider 通过/info探测到 A2UI 已开启后会自动注入内置的createA2UIMessageRenderer——你不需要手动把渲染器接进renderActivityMessages。一旦两端同时开启Agent 即可通过createSurface/updateComponents/updateDataModel三类操作operation流式驱动客户端渲染可交互界面。整套流程的接线在 CopilotKitProvider.tsx 的a2uiprop 文档与 runtime.ts 的 middleware 类型定义中有完整注解。快速开始两端各三步配置运行时侧如app/routes/api.copilotkit.$.tsx在 Remix 风格的 API 路由中创建 runtime handlerimport type { Route } from ./types/api.copilotkit.$; import { CopilotRuntime, createCopilotRuntimeHandler, BuiltInAgent, convertInputToTanStackAI, } from copilotkit/runtime/v2; import { chat } from tanstack/ai; import { openaiText } from tanstack/ai-openai; const agent new BuiltInAgent({ type: tanstack, factory: ({ input, abortController }) { const { messages, systemPrompts } convertInputToTanStackAI(input); return chat({ adapter: openaiText(gpt-4o), messages, systemPrompts, abortController, }); }, }); const runtime new CopilotRuntime({ agents: { default: agent }, // 启用该键后/info 才会向客户端宣告 A2UI 能力 a2ui: {}, }); const handler createCopilotRuntimeHandler({ runtime, basePath: /api/copilotkit, }); export async function loader({ request }: Route.LoaderArgs) { return handler(request); } export async function action({ request }: Route.ActionArgs) { return handler(request); }a2ui键支持传一个配置对象而不是空对象。从 runtime.ts 的CopilotRuntimeMiddlewares类型可以看到它同时继承BaseCopilotRuntimeMiddlewareOptions与A2UIMiddlewareConfig并额外提供enabled?: boolean显式开关省略或传true开启 A2UI传false关闭 A2UI同时保留其余配置如schema/catalog继续生效传裸的a2ui: {}为兼容旧版而保持开启状态。你还可以通过a2ui.schema把客户端extractSchema(definitions)得到的 JSON 序列化 schema 传给运行时详见下文自定义 Catalog让中间件据此把组件能力注入 Agent 上下文。客户端侧app/root.tsx或应用外壳import { CopilotKit, CopilotChat } from copilotkit/react-core/v2; import copilotkit/react-core/v2/styles.css; export default function App() { return ( CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme: { // theme 对象会被透传给 A2UIProvider → ThemeProvider。 // tokens 映射到 A2UI basic catalog 的 CSS 变量。 colors: { primary: #0ea5e9 }, }, }} CopilotChat agentIddefault classNameh-full / /CopilotKit ); }客户端的a2uiprop 定义在 CopilotKitProvider.tsx共四个可选字段字段类型默认行为themeA2UITheme省略时使用copilotkit/a2ui-renderer内置的viewerThemecatalogCatalog省略时使用内置basicCatalogloadingComponentReact.ComponentType省略时显示默认动画骨架屏recoveryA2UIRecoveryRendererOptions省略时使用合理默认值详见下文loading 骨架一节Provider 内部通过a2uiActive runtimeA2UIEnabled || a2uiCatalogProvided判定是否激活 A2UI 渲染管线只要运行时宣告支持或客户端传入了自定义catalog内置渲染器就会被注入见 CopilotKitProvider.tsx 的builtInActivityRenderers组装逻辑。主题定制从 Token 到 CSS 变量a2ui.theme是渲染器主题的唯一入口。它会被透传给A2UIProvidercopilotkit/a2ui-renderer的低层原语之一再由其内部的ThemeProvider消费const theme { colors: { primary: #0ea5e9 } }; CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme }} CopilotChat agentIddefault / /CopilotKit从源码看A2UIProvider.tsx 的渲染顺序是A2UIActionsContext.Provider→A2UIStateContext.Provider→ThemeProvider主题 token 最终映射到 A2UI basic catalog 组件的 CSS 变量上从而统一驱动 Text、Button、Card 等所有内置组件的视觉风格。注意当前版本copilotkit/a2ui-renderer1.70.3中旧的viewerTheme导出已退化为向后兼容的空对象占位见 index.ts主题一律通过a2ui.theme传入。核心模式一自定义 Catalog 扩展组件集内置basicCatalog已提供 18 个常用组件。以 basic/index.ts 为准包括Text、Image、Icon、Video、AudioPlayer、Row、Column、List、Card、Tabs、Divider、Button、TextField、CheckBox、ChoicePicker、Slider、DateTimeInput。业务组件不在内置集里时用createCatalog(definitions, renderers)构建自定义 Catalogimport { createCatalog } from copilotkit/a2ui-renderer; import { z } from zod; const theme { colors: { primary: #0ea5e9 } }; // 定义层definitions与平台无关Zod schema 描述。 // 渲染层renderers与平台相关React 组件。 // TypeScript 会强制 renderers 的键与 definitions 的键完全一致。 const definitions { ProductCard: { description: A product card with title and price, props: z.object({ title: z.string(), price: z.number() }), }, }; const catalog createCatalog( definitions, { ProductCard: ({ props }) ( div classNamerounded-xl border p-3 div classNamefont-medium{props.title}/div div classNametext-sm text-muted-foreground${props.price}/div /div ), }, { includeBasicCatalog: true }, ); CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme, catalog }} CopilotChat agentIddefault / /CopilotKit;createCatalog的第三个参数支持两个选项见 create-catalog.tsxcatalogIdCatalog 标识默认生成copilotkit://custom-catalogURIincludeBasicCatalog是否把内置 basic catalog 合并进自定义集默认false。设置includeBasicCatalog: true时Agent 既能看到你的业务组件也能继续使用 Text、Button、Row 等通用原语。把 schema 暴露给 AgentextractSchemaimport { createCatalog, extractSchema } from copilotkit/a2ui-renderer;extractSchema(definitions)把 definitions 转换成 JSON 可序列化的视图专门用于传给运行时的a2ui.schema配置const runtime new CopilotRuntime({ agents: { default: agent }, a2ui: { schema: extractSchema(definitions) }, });重要认知extractSchema不是泛型类型工具而是一个真实的运行时函数。它在 create-catalog.tsx 中把 Zod schema 的每个属性映射为{ type, description }结构的普通对象。TypeScript 类型参数在运行时会被擦除Agent 需要的是一个真正的运行时 schema 值Zod所以不要把类型层面的推断当作运行时 schema 的替代品。核心模式二覆盖 loading 骨架屏Agent 生成界面的间隙客户端默认展示动画骨架屏。用loadingComponent覆盖成你的品牌化加载态CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme, loadingComponent: () div classNameanimate-pulseBuilding UI…/div, }} CopilotChat agentIddefault / /CopilotKitloadingComponent在 A2UIMessageRenderer.tsx 的renderLifecycle中被消费存在宿主提供的loadingComponent时优先渲染它否则回退到内置A2UIBuildingState骨架屏。若想精细控制构建中 → 重试中 → 失败的恢复态 UI可进一步使用a2ui.recovery配置showAfterMs、showAfterAttempts、debugExposure这套 OSS-162 的预绘制生命周期状态同样由renderLifecycle驱动status为failed时渲染失败态、retrying时渲染带重试提示的状态、building/默认时渲染骨架屏或自定义加载组件。常见错误与避坑指南CRITICAL忘记配置runtime.a2ui错误写法// server new CopilotRuntime({ agents: { default: agent } }); // client CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme }} /;正确写法// server new CopilotRuntime({ agents: { default: agent }, a2ui: {} }); // client CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme }} /;缺少runtime.a2ui时/info永远不会向客户端宣告 A2UI 能力Provider 的a2uiprop 会静默失效——渲染器压根不会挂载界面上什么都不会出现。注意唯一例外是客户端显式传入cataloga2uiCatalogProvided为真时也会激活 A2UI 管线但最稳妥的用法仍是两端同时开启。相关证据见 runtime.ts 与 CopilotKitProvider.tsx。HIGH手动把createA2UIMessageRenderer接进renderActivityMessages错误写法import { createA2UIMessageRenderer } from copilotkit/react-core/v2; CopilotKit runtimeUrl/api/copilotkit renderActivityMessages{[createA2UIMessageRenderer({ theme })]} /;正确写法CopilotKit runtimeUrl/api/copilotkit a2ui{{ theme }} /CopilotKitProvider 会通过/info自动探测运行时的 A2UI 能力并注入内置渲染器见 CopilotKitProvider.tsx 的renderers.unshift(createA2UIMessageRenderer({...}))。若你再手动通过renderActivityMessages传一遍就会产生双份渲染器与自动注入的那份互相竞争race导致界面重复或行为不可预期。MEDIUM每次快照都重发createSurface错误写法伪代码你的 Agent 生成器内# Pseudocode — inside your agent generator. Exact API names/kwargs vary by # A2UI SDK version; consult your SDKs docs for real call shapes. async def agent_generator(): # agent re-emits createSurface operation on every state delta async for update in stream: yield a2ui.create_surface(surface_idmain, ...) # every tick yield a2ui.update_components(...)正确写法# Pseudocode — inside your agent generator. # Emit createSurface once per surfaceId; use updateComponents / updateDataModel # for changes. async def agent_generator(): yield a2ui.create_surface(surface_idmain, ...) # once async for update in stream: yield a2ui.update_components(surface_idmain, ...)虽然客户端的SurfaceMessageProcessor会对已存在的 surface 过滤掉重复的createSurface操作见 A2UIMessageRenderer.tsx但持续重发在 Agent 侧本身就是 bug——客户端会为每次快照无谓地重跑对账逻辑造成界面闪烁。正确的契约是每个surfaceId只发一次createSurface后续变更一律用updateComponents/updateDataModel表达。MEDIUM自定义 action 桥接缺少a2uiAction清理错误写法copilotkit.setProperties({ ...copilotkit.properties, a2uiAction: msg }); await copilotkit.runAgent({ agent }); // 没有 finally —— a2uiAction 泄漏进下一次 run 的 properties正确写法try { copilotkit.setProperties({ ...copilotkit.properties, a2uiAction: msg }); await copilotkit.runAgent({ agent }); } finally { if (copilotkit.properties) { const { a2uiAction, ...rest } copilotkit.properties; copilotkit.setProperties(rest); } }内置桥接在 runA2UIAction 中始终用finally剥离a2uiAction且剥离前有copilotkit.properties的判空保护防止在解构时抛TypeError掩盖原始runAgent的错误。如果你手写桥接却跳过清理上一次的 action 会附着到后续每一次 agent 运行上造成跨轮次的脏状态。MEDIUM装错包名copilotkitnext/a2ui-renderer错误写法import { createA2UIMessageRenderer } from copilotkitnext/a2ui-renderer;正确写法// 低层原语很少直接用 —— CopilotKit Provider 的 a2ui prop 才是默认路径 import { A2UIProvider, A2UIRenderer, createCatalog, } from copilotkit/a2ui-renderer; // 自动挂载的渲染器在 react-core/v2 import { createA2UIMessageRenderer } from copilotkit/react-core/v2;本包发布名为copilotkit/a2ui-renderer见 package.json不是copilotkitnext/a2ui-renderer。copilotkitnext/前缀是其他独立发布包的保留命名空间不能默认套用到这个包上。源码级原理自动挂载、消息处理与 action 桥接理解了上面的配置与避坑点后再花两分钟看清copilotkit/a2ui-renderer在 react-renderer/index.ts 中的导出全貌你会对整条链路有更系统的认知Provider 层A2UIProvider双 Context 架构稳定 actions 与响应式 state 分离见 A2UIProvider.tsx、A2UIRenderer、ThemeProvider及useA2UI/useA2UIContext等 hooksCatalog 层createCatalog/extractSchema新 API与已废弃的createA2UICatalog/extractA2UISchema旧 API见 create-catalog.tsx、filterCatalog、basicCatalog工具层injectStyles/removeStyles、cn、动态 props 绑定所需的DynamicStringSchema/DataBindingSchema等来自a2ui/web_core的再导出。自动挂载渲染器的完整链路是运行时宣告a2ui→/info携带能力标记 →CopilotKitProvider读取runtimeA2UIEnabled→ 注入createA2UIMessageRenderer→ 其内部render函数把a2ui_operations按 surface 分组 → 每个 surface 由ReactSurfaceHost用A2UIProviderSurfaceMessageProcessorA2UIRenderer渲染。用户点击组件派发的 action经A2UIProvider的onAction回调进入runA2UIAction通过setProperties({ a2uiAction })runAgent回传 Agent并在finally中清理构成完整的Agent → 界面 → 用户操作 → Agent闭环。开发期诊断提示A2UIMessageRenderer内置了三条仅在NODE_ENV ! production时输出的开发警告遇到界面没渲染时可据此快速定位详见 A2UIMessageRenderer.tsxsurface 收到操作但从未绘制8 秒未收到onReady要么没有updateComponents操作要么组件通过path绑定数据却没有任何updateDataModel传入非空值surface 缺少ROOT_COMPONENT_ID根组件入口组件必须命名为ROOT_COMPONENT_ID渲染器从该 id 开始遍历组件树其余组件须通过child/children从根可达操作指向不存在的 surfacecreateSurface必须先于或伴随针对该 surface 的其他操作到达。这三类警告都只提示 payload 本身的问题与客户端接线无关——按提示检查 Agent 发出的操作即可。至此你已经掌握了 CopilotKit A2UI 从双端接线、主题与 Catalog 定制、骨架屏覆盖到全部高频坑点的完整知识。对照 SKILL.md 与packages/a2ui-renderer源码即可在项目中稳定落地Agent 驱动声明式 UI的能力。【免费下载链接】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),仅供参考