资讯动态

CopilotKit × Microsoft Agent Framework (.NET):把后端工具调用渲染为品牌化 React 组件的 Tool Rendering 实践

发布时间:2026/9/14 18:10:42 来源:尧图企业网站定制
CopilotKit × Microsoft Agent Framework (.NET)把后端工具调用渲染为品牌化 React 组件的 Tool Rendering 实践【免费下载链接】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 中 Microsoft Agent Framework (.NET) 集成的 Tool Rendering 演示 为核心完整拆解后端 .NET Agent 的工具调用如何在前端聊天流中变成一张张可交互的 React 卡片这一机制前端如何用useRenderTool按工具名注册专属渲染器并通过useDefaultRenderTool兜底后端如何用AIFunctionFactory定义工具以及工具调用结果在 .NET → AG-UI 协议 → React 渲染这条链路上的数据契约。读完你可以掌握按工具名注册定制 UI、处理 in-flight 与 completed 两种调用状态、为未覆盖工具设计通配兜底渲染以及用 Playwright 确定性 fixture 对生成式 UI 做端到端验证的完整套路。一、演示定位一个三档进阶中的完全体在 manifest.yaml 中Tool Rendering 被注册为特性tool-rendering路由/demos/tool-rendering描述为 Backend agent tools rendered as UI components并标记deployed: true。它与另外两个演示构成一个三档进阶progressiontool-rendering-default-catchall前端不写任何自定义渲染器完全依赖 CopilotKit 内置默认 UItool-rendering-custom-catchall用一个品牌化的通配渲染器useDefaultRenderTool统一绘制所有工具调用tool-rendering本文主角每个有意思的后端工具都拥有专属定制卡片再由通配渲染器兜住漏网的调用。page.tsx 顶部注释明确给出了这张映射表get_weather → WeatherCard / (per-tool renderer) search_flights → FlightListCard / (per-tool renderer) get_stock_price → StockCard / (per-tool renderer) roll_d20 → D20Card / (per-tool renderer) * → CustomCatchallRenderer / (wildcard fallback)这种专属优先、通配兜底的分层策略就是该演示要传达的核心工程模式。二、前端核心useRenderTool按工具名注册渲染器page.tsx 中页面组件先用CopilotKit指定 runtime 与 agentCopilotKit runtimeUrl/api/copilotkit agenttool-rendering ... /CopilotKit内层Chat组件在 Hook 中依次注册 4 个 per-tool 渲染器。以天气工具为例对应源码region[render-weather-tool]区域useRenderTool( { name: get_weather, parameters: z.object({ location: z.string(), }), render: ({ parameters, result, status }) { const loading status ! complete; const parsed parseJsonResultWeatherResult(result); return ( WeatherCard loading{loading} location{parameters?.location ?? parsed.city ?? } temperature{parsed.temperature} humidity{parsed.humidity} windSpeed{parsed.wind_speed} conditions{parsed.conditions} / ); }, }, [], );三个关键注册点值得注意name字符串精确匹配后端工具名。这里的四个名字get_weather、search_flights、get_stock_price、roll_d20与 .NET 后端AIFunctionFactory.Create(..., Name ...)显式指定名一一对应见第四节前后端靠工具名这条契约绑定。parameters用 Zod schema 声明工具入参渲染回调中可以直接拿到类型化的parameters。演示中天气卡片在结果还没回来时就先从parameters?.location里取出城市名占位显示location{parameters?.location ?? parsed.city ?? }这是参数先行、结果随后的典型用法。render回调接收{ parameters, result, status }这正是 README 所述的核心——渲染器同时拿到入参args、结果result与状态status因此 UI 既能反映进行中in-flight的调用也能反映已完成的调用。const loading status ! complete一行即完成两种态的分支。roll_d20的注册展示了参数可选场景value: z.number().optional()且对结果做了双字段容错const value typeof parsed.value number ? parsed.value : typeof parsed.result number ? parsed.result : undefined;源码注释还透露了一个测试细节每次roll_d20调用都会挂载一张独立的卡片这样 e2e 测试可以精确计数Each tool call mounts its own card so e2e tests can count them。最后useDefaultRenderTool注册通配兜底region[catchall-renderer]区域useDefaultRenderTool( { render: ({ name, parameters, status, result }) ( CustomCatchallRenderer name{name} parameters{parameters} status{status as CatchallToolStatus} result{result} / ), }, [], );任何未被上面四个useRenderTool认领的工具调用例如后端的roll_dice都会落到这张统一的兜底卡片上。三、status生命周期一次工具调用的三个阶段custom-catchall-renderer.tsx 把工具调用状态定义为一个三段式联合类型并给出品牌化的状态徽章export type CatchallToolStatus inProgress | executing | complete;describeStatus将三者映射为 UI 文案inProgress → streaming、executing → running、complete → done。这解释了 README 里UI can reflect both in-flight and completed calls的具体含义工具调用从流式产生、到后端执行、到结果回传是一个可被前端逐步观测的过程渲染器不必等到最终结果才有 UI。兜底卡片的状态机使用方式是done status complete只有完成态才渲染 Result 区块否则显示斜体占位文案 waiting for tool to finish…卡片根元素同时写data-tool-name、data-status属性供自动化测试断言。专属卡片如 weather-card.tsx则简化为loading布尔分支loading ? Fetching weather... : conditions温度、湿度、风速在未完成时显示--占位。两个层级对status的消化方式不同——专属卡片只关心完没完兜底卡片则把三态都展示出来——这是按需取用状态粒度的好示范。四、.NET 后端工具如何定义与挂载后端在 agent/D5ParityAgents.cs 的CreateToolRenderingAgent(bool reasoning)工厂方法中构建 agent通过AIFunctionFactory.Create把 C# 方法包装为命名工具例如AIFunctionFactory.Create(GetStockPrice, options: new() { Name get_stock_price, SerializerOptions _jsonSerializerOptions }), AIFunctionFactory.Create(RollD20, options: new() { Name roll_d20, SerializerOptions _jsonSerializerOptions }), AIFunctionFactory.Create(RollDice, options: new() { Name roll_dice, SerializerOptions _jsonSerializerOptions }),其中RollD20特意做成确定性的参数value的[Description]写着 Deterministic roll value [1..20]; 0 means default.保证演示与测试可复现而RollDice参数为点数面数就是专门用来不被任何 per-tool 渲染器认领、从而流经 catch-all 通配路径的工具。天气与航班工具get_weather/search_flights同样通过AIFunctionFactory.Create定义见 agent/Program.cs 中的GetWeather实现返回结构化的WeatherInfo对象。agent 的暴露走 AG-UI 协议端点在 Program.cs 中一行挂载app.MapAGUI(/tool-rendering, d5ParityFactory.CreateToolRenderingAgent(reasoning: false)); app.MapAGUI(/tool-rendering-reasoning-chain, d5ParityFactory.CreateToolRenderingAgent(reasoning: true));前端runtimeUrl/api/copilotkit经由 Next.js 路由转发到该 .NET agent形成React 前端 → CopilotKit Runtime 代理 → .NET AG-UI 端点的完整链路。五、数据契约细节多层 JSON 字符串的解包工具结果在 .NET 序列化 → AG-UI 传输 → React 渲染这条链路上可能经历多次 JSON 编码。parse-json-result.ts 是各演示共享的解包工具其注释直接点明了原因The .NET AG-UI adapter can wrap JSON string tool results in another JSON string, so parse a few layers.实现上最多尝试 3 层解析任何一层失败或结果不是对象时安全地返回空对象避免渲染器因格式抖动而崩溃export function parseJsonResultT(result: unknown): T { let parsed result; for (let depth 0; depth 3 typeof parsed string; depth 1) { if (!parsed.trim()) return {} as T; try { parsed JSON.parse(parsed); } catch { return {} as T; } } if (!parsed || typeof parsed ! object) return {} as T; return parsed as T; }每个 per-tool 渲染器都用parseJsonResultWeatherResult/parseJsonResultFlightSearchResult等把result强转为本地声明的接口类型。做同类集成的团队可以直接借鉴这个防御式解包模式。六、端到端验证Playwright 确定性 Fixturetests/e2e/tool-rendering.spec.ts 展示了生成式 UI 如何被严谨测试。测试策略有三层建议胶囊驱动页面通过useSuggestions注册 5 个建议胶囊——Weather in SF、Find flights、Stock price、Roll a d20、Chain tools每个胶囊固定触发一条工具调用路径确定性断言Aimock 录制的 fixture 数据把每个胶囊的 prompt 钉死为确定性的工具调用序列测试头注释指向showcase/aimock下的回放数据因此可以断言精确值——例如天气卡片断言城市为 San Francisco、湿度 55%、风速 10航班卡片断言出发地 SFO、目的地 JFK稳定 testid前端所有卡片都带data-testidweather-card、weather-humidity、flights-card、custom-catchall-card等e2e 通过[data-testid...]精确定位而非依赖文案或样式。超时参数也体现了生成式 UI 测试的特点建议加载15s工具调用完成60s。七、如何上手与文件地图本地启动该集成演示可参考 manifest 中cli-start特性给出的克隆命令npx copilotkitlatest init --framework ms-agent-dotnet。仓库内该演示的完整文件地图如下便于按需深入角色路径开发者笔记本文主体文档README.md前端渲染注册入口page.tsx四张专属卡片weather-card.tsx、flight-list-card.tsx、stock-card.tsx、d20-card.tsx通配兜底渲染器custom-catchall-renderer.tsx结果解包工具parse-json-result.ts.NET agent 工厂与工具定义D5ParityAgents.cs、Program.cs演示清单路由/特性/高亮文件manifest.yamle2e 测试tool-rendering.spec.ts实践要点回顾工具名是前后端唯一的硬契约前端useRenderTool({ name })必须与 .NET 端AIFunctionFactory.Create(..., Name ...)一致render回调同时消费parameters / result / statusstatus ! complete即视为 in-flight据此渲染加载态inProgress / executing / complete三态可在兜底 UI 中细粒度呈现结果解析要防御多层 JSON 编码parseJsonResult的最多解 3 层 失败降级空对象是跨 .NET 集成的稳健做法兜底渲染器useDefaultRenderTool不是没做完而是保证任意新工具上线前端不写代码也能有品牌一致的展示生成式 UI 可测试性来自三件套确定性后端 fixture、稳定data-testid、建议胶囊式的固定触发路径。这一套per-tool 专属渲染 通配兜底 状态驱动的模式与具体框架无关可平移到 CopilotKit 的任意后端集成只要后端工具调用事件能到达前端useRenderTool/useDefaultRenderTool的注册方式就是通用答案。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价