十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CopilotKit 声明式生成式 UI 实战:基于 CrewAI Conversational Flows 的 A2UI 动态 Schema 目录开发

CopilotKit 声明式生成式 UI 实战:基于 CrewAI Conversational Flows 的 A2UI 动态 Schema 目录开发 CopilotKit 声明式生成式 UI 实战基于 CrewAI Conversational Flows 的 A2UI 动态 Schema 目录开发【免费下载链接】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 仓库中showcase/integrations/crewai-conversational-flows的声明式生成式 UIDeclarative Generative UI即 A2UI Dynamic SchemaDemo 为研究对象完整讲解前端注册自定义组件目录 → 运行时注入render_a2ui工具 → 后端 Flow 强制调用 → 运行时二次 LLM 渲染为 UI 操作流的完整链路并附上该 Demo 的 QA 验收清单与 Playwright 端到端测试依据。读完本文你将掌握如何用 Zod Schema React Renderer 构建自己的 A2UI 组件目录、如何用 AG-UI 协议打通 CrewAI Flow 与 CopilotKit Runtime以及如何用data-testid与 DOM 指纹对动态渲染的 UI 进行自动化验收。关联文档与源码证据位于QA 验收清单、Demo 页面源码、专用 Runtime 路由、后端 CrewAI Flow、E2E 测试。一、什么是声明式生成式 UIA2UI Dynamic Schema 模式在传统 Agent 应用中前端组件与后端 Agent 之间通常靠硬编码的协议字段耦合后端返回什么结构前端就渲染什么结构。CopilotKit 的 A2UIAgent-to-UI协议则采用声明式思路——Agent 只负责输出要渲染什么组件、传什么属性真正怎么画由前端注册的 React 组件目录决定。本 Demo 所在的crewai-conversational-flows集成示例演示的是A2UI 动态 SchemaBYOCBring Your Own Components模式其核心特征是前端在运行期通过a2ui{{ catalog: myCatalog }}把一份自定义组件目录注册给 CopilotKit Provider组件目录由平台无关的 Zod 定义definitions.ts与React 实现renderers.tsx两部分组成运行时会把目录中的 Schema 序列化进 Agent 的上下文让大模型知道可以画哪些组件、每个组件接受什么属性后端 CrewAI Flow 强制调用运行时注入的render_a2ui工具运行时拦截该工具调用并执行一次二次 LLM 渲染把流式工具调用转换成前端可消费的操作流operations。该 Demo 的完整工程上下文记录在页面源码 page.tsx 的注释中它定义了一套带品牌风格的 React 组件与 Zod Schema通过createCatalog(..., { includeBasicCatalog: true })生成目录并导出myCatalog再交给 Provider 消费专用运行时路由负责注入render_a2ui后端 Flow 强制使用该工具运行时中间件负责把流式工具调用变为前端绘制的 UI 操作。二、QA 验收清单逐条解读八个检查点仓库中的 QA 文档 declarative-gen-ui.md 是本文最核心的验收骨架它列出了八条人工验收步骤全部针对/demos/declarative-gen-ui页面。下面逐条解读其验证意图并给出对应源码依据。1. 页面与根节点渲染访问/demos/declarative-gen-ui验证页面根节点data-testiddeclarative-gen-ui-root是否渲染。该页面由 page.tsx 实现是典型的use client组件用CopilotKit runtimeUrl/api/copilotkit-declarative-gen-ui agentdeclarative-gen-ui a2ui{{ catalog: myCatalog }}包裹Chat /。根节点的data-testid用于端到端测试的稳定定位与 E2E 用例中page.goto(/demos/declarative-gen-ui)的入口一致。2. 预置建议 Pill验证 composer 渲染出四个预置的建议 Pill。四个 Pill 定义在 suggestions.ts 中通过useConfigureSuggestions注册且available: always表示始终可用Show a KPI dashboard→ 消息Show me my sales dashboard for this quarter.Team performance→ 消息How are our sales reps performing against quota?Anything at risk?→ 消息Are any accounts or pipeline deals at risk this quarter?Top account details→ 消息Pull up the details on our biggest account.需要注意文件注释明确指出Pill 的提示文案是自然语言业务问题图表类型的选择权不在前端而在 Agent 的 system prompt 中即 declarative_gen_ui.py 里的DECLARATIVE_GEN_UI_BACKSTORY。每个 Pill 对应一个不同的目录组件供 D5 探针与 E2E 测试分别断言。同时E2E 测试 里断言的是KPI dashboard / Pie chart — sales by region / Bar chart — quarterly revenue / Status report四个文案与 QA 清单保持同步说明QA 文档、E2E 测试、Pill 定义三者必须联动更新。3. 点击Show a KPI dashboardPill点击该 Pill验证 Agent 调用render_a2ui并出现一个组合式 KPI 仪表盘。这是整个模式的黄金路径。其背后的强制机制见后端 Flow# src/agents/declarative_gen_ui.py if render_a2ui not in action_names: raise RuntimeError( CopilotKit did not inject the required render_a2ui tool. Check a2ui.injectA2UITool on the declarative GenUI runtime. )Flow 先检查运行时是否注入了render_a2ui工具随后在acompletion中显式传tool_choice{type: function, function: {name: render_a2ui}}并关闭parallel_tool_calls确保每一轮对话都强制走 A2UI 渲染。注释中还解释了为什么不直接用ChatWithCrewFlow它会把 crew 本身作为一个工具暴露给模型导致真实模型跑一遍 crew 然后返回纯文本而不是挂载请求的 UI 表面。KPI 仪表盘的组合规则写在 sales-context.ts 的COMPOSITION_RULES中整体快照应输出一个Column(gap 16)第一个子节点是 4 个 Metric 瓦片的Row随后是 PieChart按地区营收与 BarChartJan–Jun 每月营收并列的Row且不得用 StatusBadge、DataTable 或 InfoRow仪表盘外不得再包一层 Card图表自带卡片样式。4. 点击Pie chart — sales by regionPill验证渲染出带品牌色与可读图例的 PieChart。PieChart 的定义Schema位于 definitions.tsprops 为title、description和data: { label: string; value: number }[]。其 React 实现位于 renderers.tsx 的DonutChart这是一个用circlestroke-dasharray手工绘制的环形图按比例把圆周切成多个弧形切片切片颜色取自本地 ShadCN 风格CHART_COLORS调色板zinc 系 7 色图例行展示色块、名称、数值与百分比。E2E 测试对这种无 testid 的视觉指纹做了强断言背景圆 切片圆合计svg circle数量 ≥ 3且存在形如45%的百分比图例文本由于二次 LLM 渲染是多步的冷启动时渲染可能耗时 30–60 秒因此渲染断言统一使用 60–90 秒的预算。5. 点击Bar chart — quarterly revenuePill验证渲染出带四个带标签柱体的 BarChart。BarChart 基于 Recharts 构建ResponsiveContainer内嵌RechartsBarChart带CartesianGrid虚线、禁用纵向网格线、X/Y 轴去掉轴线与刻度线颜色跟随--border/--muted-foreground主题变量、自定义 Tooltip 样式以及maxBarSize{48}的圆角柱体。源码中还有两处值得注意的细节动画指纹柱体用自定义AnimatedBarshape 包裹仅对新出现的柱体应用barSlideIn关键帧动画0.5s、cubic-bezier(0.16,1,0.3,1)关键帧通过内联style局部注入不污染globals.css回归防护E2E 测试 中明确标注的 #4734 回归旧版部署曾出现A2UI render error: Cannot create component root without a type循环报错原因是二次 LLM 的render_a2ui工具调用在防御性校验丢弃畸形组件之前就被 A2UI 中间件拦截。修复方式是重命名绕开拦截测试中显式断言该类报错文案与Catalog not found的计数均为 0同时断言同一时刻只有一个ResponsiveContainer防止循环渲染堆叠多个图表。6. 点击Status reportPill验证渲染出带 StatusBadge 子节点的 CardAPI / database / workers。对应组件是CardStatusBadge的组合。Card的 renderer 输出data-testiddeclarative-card支持title、可选subtitle与单一child插槽StatusBadge输出data-testiddeclarative-status-badgevariant枚举为success | warning | error | info默认info。风险类问题的组合规则同样来自COMPOSITION_RULES先是一行 3 个 Metric 瓦片ARR 风险 $615k、风险账户 3 个、最大敞口 Northwind $340k再按账户逐个渲染紧凑 CardCard 内用StatusBadgehigh severity 用error否则warning加一行 Text 说明原因与建议动作。7. 自由输入兜底输入自由文本如Show me a pie chart of traffic sources并发送验证 Agent 跳出建议流程后仍能输出 PieChart。这验证的是提示词兜底能力当用户不点 Pill、直接自由提问时Agent 依然遵循DECLARATIVE_GEN_UI_BACKSTORY中的组件选择规则——part-of-whole类问题选 PieChart、trend/comparison类问题选 BarChart且永远不要反问用户要哪种图表由 Agent 自行决定并输出完整组件树。三、从源码看 A2UI 目录的三层结构声明式 UI 的核心资产是组件目录Catalog本 Demo 把它拆成三个文件、三个职责1. 定义层definitions.ts平台无关的 Zod Schema每个组件声明四件事组件名、用途描述写给 LLM 看的、props 的 Zod Schema、以及约束说明。本 Demo 注册了 7 个自定义组件组件名props 要点用途Cardtitle、可选subtitle、可选child插槽带标题的容器组合相关内容StatusBadgetext、variant: success/warning/error/info状态色块healthy/degraded/down 等Metriclabel、value、可选trend: up/down/neutralKPI 关键指标如 Revenue • $12.4k • upInfoRowlabel、value紧凑的标签: 值事实行PrimaryButtonlabel、可选action派发回 Agent主 CTA 按钮PieCharttitle、description、data: {label, value}[]环形图用于整体占比分析BarCharttitle、description、data: {label, value}[]柱状图用于跨类别比较DataTablecolumns: {key, label}[]、rows: Recordstring, string\|number[]排名/明细表格E2E 中 Team performance 场景定义层有一处非常实战的注释definitions.tsDataTable本应通过z.object(...).refine(...)强制行键必须是columns[].key的子集但宿主目录包的CatalogComponentDefinition类型要求props: ZodObject运行时检查.shaperefine返回的ZodEffects会同时破坏satisfies CatalogDefinitions类型断言与运行期.shape访问因此只能把约束写进描述文本让 LLM 遵守硬性校验留给渲染管线渲染层对未知行键渲染空单元格。2. 实现层renderers.tsxReact 组件myRenderers: CatalogRenderersMyDefinitions把定义与实现一一对应并大量使用 ShadCN 风格本地原语Card、Badge、Button与主题 CSS 变量--card、--border、--muted-foreground。实现层还承担了布局职责例如Metric用flex-1 min-w-[120px]保证一行 3 个指标在 600px 卡片列中均分约 200px 宽PieChart/BarChart用flex-1 min-w-0保证同一 Row 内多图均分宽度InfoRow用border-b last:border-b-0避免最后一行悬挂分隔线。3. 组装层catalog.tscreateCatalog// src/app/demos/declarative-gen-ui/a2ui/catalog.ts export const myCatalog createCatalog(myDefinitions, myRenderers, { catalogId: declarative-gen-ui-catalog, includeBasicCatalog: true, });createCatalog把定义 × 实现组装成 Provider 可消费的目录includeBasicCatalog: true会合并 CopilotKit 内置 A2UI 原语Column、Row、Text、Image、Card、Button、List、Tabs 等让 Agent 可以自由混排自定义组件与基础组件。catalogId则与运行时路由中的defaultCatalogId严格对应见下节。四、专用 Runtime 路由render_a2ui注入与目录绑定Demo 使用了一个独立于主路由的专用 Next.js Route Handlerroute.ts。它的关键配置有三处const runtime new CopilotRuntime({ agents, a2ui: { defaultCatalogId: declarative-gen-ui-catalog, }, });Agent 绑定HttpAgent指向AGENT_URL/conversational_flows/declarative-gen-ui默认http://localhost:8000可由环境变量覆盖即agent_server.py挂载的专用 FastAPI 端点保证该 Demo 运行在属于自己的 Flow 上injectA2UITool默认为 true由运行时把render_a2ui前端工具注入给后端 FlowFlow 再强制使用见第二节defaultCatalogId必须钉死注释解释了这是踩坑后的补丁——遵循工具使用指南的模型会省略catalogId此时中间件会回退到未注册的规范基础目录导致 Catalog not found 渲染错误。把默认目录 ID 钉为页面实际注册的declarative-gen-ui-catalog即可保证二次 LLM 渲染使用正确的组件集。请求经由createCopilotRuntimeHandler({ runtime, basePath, mode: single-route })处理异常统一以{ error, stack }JSON 形式返回 500。五、后端 CrewAI Flow状态、系统提示与强制渲染后端由 declarative_gen_ui.py 提供使用 CrewAI 的Flow原语而非带 crew 的ChatWithCrewFlow。核心包括状态定义DeclarativeGenUIState(CopilotKitState)保留 AG-UI CrewAI 端点准备好的上下文字段——context: list[dict]与别名ag-ui的ag_ui字典系统提示组装_system_prompt把state.context中的条目逐个拼成{description}:\n{value}段落若ag_ui中携带a2ui_schema再追加 A2UI catalog schema and tool usage guide 段落。这印证了目录 Schema 是在请求期被运行时序列化进copilotkit.context的强制渲染检查render_a2ui存在后用acompletion(modelopenai/gpt-5.4, ..., toolsactions, tool_choice{... render_a2ui}, parallel_tool_callsFalse, streamTrue)流式调用再把首个 choice 的消息追加回state.messages。此外DECLARATIVE_GEN_UI_BACKSTORY还承担数据接地职责Agent 被设定为虚构 B2B 服装公司 Vantage Threads 的销售分析师所有数字必须来自 App Context 中的销售数据集不得虚构每次回答必须调用render_a2ui绘制可视化表面聊天回复只保留一句话。六、上下文接地前端如何把数据与组合规则交给 Agent前端通过 sales-context.ts 的useSalesAnalystContext()注册两条 Agent 上下文销售数据集Q2 营收 $4.2M环比 12%、按地区营收NA $1.9M / EMEA $1.3M / APAC $720k / LATAM $280k、各月营收、销售代表配额达成率、3 个风险账户明细、最大客户 Meridian Apparel Group 画像及其产品线营收等仪表盘组合规则五条按问题形状选组件的规则快照→KPI 仪表盘、团队表现→表格、风险→状态徽章、单账户→信息行、部分占比→饼图、趋势比较→柱状图并强调组合要大方仪表盘要像真正的分析产品而不是单个组件。useAgentContext注册的上下文会同时到达主 AgentApp Context与二次 A2UI 规划 LLM——运行时把前端上下文条目序列化进其系统指令从而保证Flow 画什么与前端画得出什么基于同一份数据与规则这也是 QA 中每个数字都必须与数据集一致的前提。七、端到端验证从 QA 清单到 Playwright 自动断言E2E 测试 是 QA 清单的自动化镜像二者通过文件头注释显式互链QA reference: qa/declarative-gen-ui.md。其设计要点入口beforeEach跳转/demos/declarative-gen-ui首屏断言仅验证输入框可见且没有任何.recharts-responsive-container首帧不渲染 A2UI 表面Pill 文案断言用data-testidcopilot-suggestion逐个匹配四个 Pill 的原文标题渲染指纹断言PieChart 看svg circle数量与\d%图例文本BarChart 看.recharts-responsive-container与.recharts-bar-rectangle数量KPI 看[data-testiddeclarative-metric]≥ 3Status report 看[data-testiddeclarative-status-badge]≥ 1时间预算因二次 LLM 渲染冷启动可达 30–60 秒用例test.setTimeout(120_000)渲染断言普遍用 60–90 秒轮询回归护栏断言无 Cannot create component ... without a type 与 Catalog not found 报错且同一时刻图表容器 ≤ 1防止循环渲染堆叠。测试注释还记录了历史教训W8-7 曾因 aimock fixtures 在单次响应里同时返回 content 与 toolCalls导致前端在 A2UI 工具调用渲染前就关闭了 assistant 回合KPI 与 StatusReport 用例在 Railway 上偶发跳过拆分开 fixtures提交 2436adba6后四个 Pill 全部稳定通过。这提醒我们QA 清单、E2E 用例与 aimock 录制数据必须视为同一套验收体系。八、给开发者的实操要点总结按定义—实现—组装三文件组织目录Zod Schema 写给模型看、React 实现写给人看、createCatalog负责合并内置基础目录在定义描述里写清楚约束受宿主类型限制无法用.refine强校验时把规则写进description让 LLM 遵守并在渲染层做容错空单元格、String(row[col.key] ?? )用tool_choice强制 A2UIFlow 层显式tool_choice指向render_a2ui并关闭并行工具调用避免模型跑完 crew 返回纯文本defaultCatalogId与页面注册的catalogId必须一致否则二次 LLM 回退到未注册目录会报 Catalog not found上下文是双通道数据与组合规则通过useAgentContext注册会同时进入主 Agent 与二次渲染 LLM保证数据接地与组合一致验收三件套联动QA 清单、Playwright 断言、Pill 文案三者必须同步更新对纯视觉组件用 DOM 指纹donut SVG 圆、Recharts 类名、testid、百分比图例做稳定断言并预留 60–90 秒渲染预算。九、相关文档与代码索引QA 验收清单showcase/integrations/crewai-conversational-flows/qa/declarative-gen-ui.mdDemo 页面与聊天组件page.tsx、chat.tsx目录三件套definitions.ts、renderers.tsx、catalog.ts建议与上下文suggestions.ts、sales-context.ts专用 Runtimeroute.ts后端 CrewAI Flowdeclarative_gen_ui.py端到端测试tests/e2e/declarative-gen-ui.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),仅供参考
返回列表