
CopilotKit 推理消息零配置渲染实战Google ADK 集成中的 reasoning-default Demo 与 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 与 Google ADKAgent Development Kit集成中的reasoning-defaultDemo讲解如何在不编写任何自定义渲染组件的前提下让 Agent 的推理reasoning/thinking过程以内置可折叠卡片的形式呈现在聊天界面中。读完本文你将掌握 reasoning 消息在前端零配置渲染的完整链路——从 ADK 后端的 Gemini thinking 配置、到 v2 React Core 内置CopilotChatReasoningMessage组件的底层实现、再到该功能的 QA 验证清单与 E2E 自动化断言方法。一、Demo 定位一个用于验证默认推理渲染的 QA 单元在 showcase/integrations/google-adk 中reasoning-default与reasoning-custom是一对刻意设计的对照 Demo其 QA 文档位于 qa/reasoning-default.md。文档开篇明确指出其定位该 Demo 验证内置的CopilotChatReasoningMessage在没有自定义 slot 的情况下也能正常渲染因此无需维护完整的人工检查清单full manual checklist。这意味着该页面承担的是**功能验证单元column**的职责它不追求花哨的定制外观而是为 CI 与人工 QA 提供一个稳定、可重复的基准——证明 reasoning 渲染能力是 CopilotKit 的开箱即用能力而非某个 Demo 手工拼装出来的特性。二、后端支撑Gemini thinking 模式如何产生 reasoning 消息reasoning 渲染的前提是后端真的把推理过程作为独立消息流式输出。在 src/agents/shared_chat.py 中build_thinking_chat_agent工厂函数负责构造带 thinking 能力的 ADKLlmAgentdef build_thinking_chat_agent( *, name: str, instruction: str, model: str DEFAULT_MODEL, ) - LlmAgent: return LlmAgent( namename, modelget_model(model), instructioninstruction, tools[AGUIToolset()], generate_content_configtypes.GenerateContentConfig( thinking_configtypes.ThinkingConfig( include_thoughtsTrue, thinking_budget-1, ), ), after_model_callbackstop_on_terminal_text, )关键参数说明model默认模型为gemini-3.1-flash-lite见 shared_chat.py#L44通过get_model()解析。当设置了GOOGLE_GEMINI_BASE_URL环境变量时会返回一个指向 aimock 代理的Gemini实例用于 Railway 部署的确定性录制回放否则返回普通模型字符串。include_thoughtsTrue让 Gemini 在生成答案的同时以thoughtTrue的 part 输出推理过程。从源码注释可以确认ADK 会把这些 thought parts 通过 ag-ui 协议转发为 reasoning chunk从而被 v2 前端识别。thinking_budget-1-1 表示让模型自行决定推理投入的算力不人为限制。after_model_callbackstop_on_terminal_text这是该包内所有注册 Agent 共享的终止条件回调。它解决 Gemini 3.1 Flash-Lite 在成功工具调用后不会自然结束 agentic 循环的问题——回调检查每个非 partial 的模型响应仅当响应含文本、无待处理function_call且finish_reason为STOP时才设置end_invocation True终止循环否则跳过。同时它守护了 thinking 模式下的双 chunk 结构Gemini 在 thinking 模式下会把一轮 turn 拆成文本 chunk与function_call chunk两个非 partial 响应若不加finish_reason守卫文本 chunk 会触发提前终止导致后续工具链断裂。Agent 注册两个 Demo 共享同一后端在 src/agents/registry.py#L154-L156 中可以看到# ----- Reasoning demos ----- reasoning-custom: AgentSpec(_thinking_chat), reasoning-default: AgentSpec(_thinking_chat),reasoning-default与reasoning-custom都解析到同一个_thinking_chatAgent。也就是说前后端唯一的差异只在前端是否覆盖reasoningMessageslot这为对照实验提供了干净的变量控制后端能力完全相同差的只是前端一行渲染配置。三、前端零配置完整可复现的 Demo 源码src/app/demos/reasoning-default/page.tsx 的完整实现仅 40 行核心代码全部来自copilotkit/react-core/v2use client; import { CopilotKit, CopilotChat } from copilotkit/react-core/v2; import { useReasoningDefaultSuggestions } from ./suggestions; const AGENT_ID reasoning-default; export default function ReasoningDefaultDemo() { return ( CopilotKit runtimeUrl/api/copilotkit agent{AGENT_ID} div classNameflex justify-center items-center h-screen w-full div classNameh-full w-full max-w-4xl Chat / /div /div /CopilotKit ); } function Chat() { useReasoningDefaultSuggestions(); return CopilotChat agentId{AGENT_ID} classNameh-full rounded-2xl /; }逐行解读其零配置含义CopilotKit runtimeUrl/api/copilotkit agent{AGENT_ID}Provider 指向同一个运行时 API 路由与reasoning-custom完全相同agent指定后端 Agent 名。CopilotChat agentId{AGENT_ID} ...直接使用预构建的CopilotChat组件没有传messageView属性即不覆盖任何消息渲染槽位。reasoning 消息由此交给 CopilotKit 内置的CopilotChatReasoningMessage渲染。useReasoningDefaultSuggestions()来自同目录的 suggestions.ts通过useConfigureSuggestions注册一个Show reasoning建议按钮export function useReasoningDefaultSuggestions() { useConfigureSuggestions({ suggestions: [ { title: Show reasoning, message: Explain step by step why the sky appears blue during the day but red at sunset., }, ], available: always, }); }这个建议词不是随意挑选的源码注释说明reasoning 模型只有在遇到真正需要思考的问题时才会输出 reasoning 流类似show your reasoning这样的元提示词往往不会触发推理导致渲染槽位永远不会亮起。而天空为何白天蓝、日落红这类需要分步因果推理的问题能稳定诱发 reasoning 输出——这是保证 QA 与 E2E 稳定可重复的关键细节。四、底层原理内置 CopilotChatReasoningMessage 是怎么工作的要理解默认渲染到底渲染成什么样需要阅读 React Core 的组件实现packages/react-core/src/v2/components/chat/CopilotChatReasoningMessage.tsx。消息分派reasoning 是一等消息类型在 CopilotChatMessageView.tsx#L16 中CopilotChatReasoningMessage被直接导入并根据message.role reasoning对消息进行判别分派custom 变体页面的源码注释也印证了这一点。因此 reasoning 消息在 v2 中是独立的一等消息类型与 user / assistant / tool 消息平级。渲染形态可折叠卡片CopilotChatReasoningMessage组件按三段式结构组织源码中以 namespace 形式导出子组件支持 slot 覆盖Header头部显示状态标签。流式进行中显示Thinking…并带一个脉动动画圆点完成后显示Thought for X如Thought for 12 seconds时长由内部计时器计算见 CopilotChatReasoningMessage.tsx#L25-L32 的formatDuration与每秒 tick 的计时逻辑。有内容时头部右侧会出现一个旋转 90° 的 chevron 图标提示可展开。Content内容区通过Streamdown组件流式渲染 reasoning 文本markdown 风格流式解析流式中带一个脉动光标指示符无内容且未流式时不渲染避免空卡片。Toggle折叠容器基于grid-template-rows: 1fr/0fr的过渡动画实现平滑展开/收起。交互细节自动展开与用户意图保护源码实现了两条容易被忽略的交互规则默认展开、完成后自动收起流式开始时isOpen初始为true让用户实时看到思考过程流式结束后自动折叠为头部摘要。用户手动操作优先组件用userToggledRef记录用户是否手动切换过。一旦用户手动点开/收起自动收起逻辑不再覆盖用户意图源码注释说明这是为了避免 CI 上异步 forceUpdate 与点击事件的竞态导致测试抖动。组件 Props 类型CopilotChatReasoningMessageProps同时暴露了header、contentView、toggle三个子 slot这意味着即便默认渲染零配置可用开发者仍可通过这三个子槽位做精细化的局部定制而不必重写整个 reasoning 渲染。五、QA 验证清单继承自官方文档的测试步骤根据 qa/reasoning-default.md该 Demo 的验证包含前置条件、测试步骤与预期结果三个部分下面完整保留并补充实操说明。前置条件PrerequisitesDemo 已部署且可访问即reasoning-default页面已通过 Next.js 应用提供本地npm run dev或已部署环境均可。Agent 后端健康确认/api/copilotkit路由可达且_thinking_chatADK Agent挂载于对应后端路径能正常返回 Gemini 响应。若使用 aimock 录制回放还需确认GOOGLE_GEMINI_BASE_URL指向的代理正常。测试步骤Test Steps导航到/demos/reasoning-default确认页面正常加载、聊天输入框可见。发送任意能诱发 reasoning 的提示词验证内置CopilotChatReasoningMessage可折叠卡片正确渲染推理 token。实操建议直接点击聊天输入区上方的Show reasoning建议按钮其消息词固定为逐步解释天空白天为何是蓝色、日落为何变红这样能稳定触发 reasoning 流避免自由输入不触发思考。验证没有自定义 reasoning slot 被接线检查页面只使用默认样式——不存在ReasoningBlock或任何定制容器。对照检查方法访问/demos/reasoning-custom可以看到带琥珀色标签横幅的自定义渲染而本页面应保持最朴素的默认卡片形态。预期结果Expected Results页面无错误加载。Reasoning 通过 CopilotKit 默认的CopilotChatReasoningMessage组件渲染前端零配置即不写任何 slot override。六、自动化验证E2E 测试如何断言默认渲染该 QA 文档对应的自动化测试位于 tests/e2e/reasoning-default.spec.ts它把人工清单翻译成了两条可重复的 Playwright 断言test.describe(Reasoning: Default, () { test.setTimeout(120_000); test.beforeEach(async ({ page }) { await page.goto(/demos/reasoning-default); }); test(page renders without errors, async ({ page }) { await expect( page.locator([data-testidcopilot-chat-input]), ).toBeVisible(); }); test(Show reasoning pill renders a reasoning-role message, async ({ page, }) { const pill page.getByRole(button, { name: /Show reasoning/i }).first(); await expect(pill).toBeVisible({ timeout: 30_000 }); await pill.click(); await expect(page.getByText(/Thinking…|Thought for/i).first()).toBeVisible({ timeout: 60_000, }); }); });值得注意的测试设计可见信号选择默认的CopilotChatReasoningMessage不发射任何testid所以测试用其流式中/完成后的头部标签Thinking…或Thought for …作为可折叠卡片已挂载的判定信号——这与组件源码中label的取值逻辑CopilotChatReasoningMessage.tsx#L100-L102完全一致实现了测试与实现的语义对齐。确定性流式测试注释说明Show reasoning 建议词对应的消息与 aimock fixtureshowcase/aimock下的录制数据匹配因此 CI 中的流式响应是确定性的不会因模型输出的随机性导致断言失败。超时配置单个用例最长 120 秒其中 reasoning 标签等待 60 秒为较慢的流式响应留足余量。七、与 reasoning-custom 的对照何时用默认、何时自定义src/app/demos/reasoning-custom/page.tsx 与默认版唯一的结构差异是给CopilotChat传入了messageView.reasoningMessage槽位CopilotChat agentId{AGENT_ID} classNameh-full rounded-2xl messageView{{ reasoningMessage: ReasoningBlock as unknown as typeof CopilotChatReasoningMessage, }} /这从对照角度回答了何时选默认、何时自定义场景推荐方式理由快速集成、验证 reasoning 能力、保持 UI 一致默认CopilotChatReasoningMessage零配置自带流式/完成状态标签、自动展开与折叠动画、Streamdown 流式文本渲染需要品牌化视觉强调如琥珀色横幅、定制标签覆盖messageView.reasoningMessage槽位槽位是 v2 公开、稳定的定制入口也可以只覆盖header/contentView/toggle子槽位做局部微调无头headless场景自建聊天界面使用message.role reasoning判别 useRenderReasoning见 headless-complete 等 Demo 的源码模式八、如何自行运行与复现验证克隆仓库git clone https://gitcode.com/GitHub_Trending/co/CopilotKit.git进入showcase/integrations/google-adk目录。配置环境按 showcase/integrations/google-adk 目录下的 README 配置 Google AI Studio 凭据若在 Railway 等托管环境设置GOOGLE_GEMINI_BASE_URL指向 aimock 代理以保证流式响应确定性。启动前后端启动 Next.js 应用/api/copilotkit路由代理到挂载的 ADK Agent 后端路径。人工验证按上文第五节清单逐项勾选。自动化验证在配置好 Playwright 的环境执行tests/e2e/reasoning-default.spec.ts观察两条断言是否全部通过。结语reasoning-default这个看似简单的 QA 单元实际上贯穿了 CopilotKit reasoning 能力的完整链路ADK 后端通过include_thoughtsTrue让 Gemini 输出 thought partsag-ui 协议将其转换为 reasoning 消息React Core 的CopilotChatMessageView按message.role分派给内置CopilotChatReasoningMessage最终以带流式状态标签、自动折叠动画的可展开卡片呈现。理解这条链路后你既能开箱即用地获得推理可视化也能在需要品牌化定制时准确找到messageView.reasoningMessage这个扩展点。【免费下载链接】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),仅供参考