CopilotKit 共享状态流式渲染实战:基于 CrewAI Flows 的逐 Token 文档流(QA 验证指南)

发布时间:2026/9/13 4:08:25
CopilotKit 共享状态流式渲染实战:基于 CrewAI Flows 的逐 Token 文档流(QA 验证指南) CopilotKit 共享状态流式渲染实战基于 CrewAI Flows 的逐 Token 文档流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导读本文以仓库中showcase/integrations/crewai-crews/qa/shared-state-streaming.md这份 QA 文档为核心系统拆解 CopilotKit 生态中共享状态流式渲染Shared State Streaming这一经典范式后端 AgentCrewAI Flows将write_document工具的参数作为可预测状态逐 Token 推送至前端前端只读文档面板随之渐进增长并实时展示 LIVE 徽标与字符计数。读完本文你将掌握该 Demo 的完整端到端调用链CrewAI Flow → AG-UI → CopilotKit Runtime → React 前端、可复现的 Playwright E2E 断言清单以及错误处理与验收标准可直接将其迁移到自己的 QA 与交付流程中。背景为什么需要状态流式渲染传统 Agent 应用的输出只有一条路径——LLM 的文本回复流入聊天框。但当输出对象是一篇文章、一封邮件、一份报告这类结构化文档时用户的体感诉求截然不同实时可见希望看到文档像编辑器打字一样逐 Token 生长而不是最后一次性蹦出全文与聊天解耦文档是产物聊天是对话两者不应挤在同一条消息流里可替换新一轮写作应干净地替换旧文档而不是像聊天记录一样无限追加。CopilotKit 的共享状态shared state机制正是为此设计Agent 把状态字段这里是document通过 AG-UI 协议流式下发前端订阅该状态并驱动独立 UI 组件渲染。仓库中showcase/integrations/crewai-crews下的shared-state-streamingDemo 即是最小可复现的完整样例相关 QA 文档 shared-state-streaming.md 给出了可执行的验收清单本文接下来逐一展开。端到端架构一次写作请求的完整链路从源码可以梳理出该 Demo 的完整数据流一次点击Write a short poem背后发生的全过程前端 React (page.tsx demo-layout.tsx) │ useAgent 订阅 state run status ▼ CopilotKit Runtime (src/app/api/copilotkit/route.ts) │ AG-UI 协议代理 ▼ FastAPI Agent 后端 (src/agent_server.py, 端口 8000) │ /shared-state-streaming 端点 ▼ CrewAI Flow (src/agents/shared_state_streaming.py) │ copilotkit_predict_state copilotkit_stream ▼ LLM (openai/gpt-5.4) → write_document 工具调用参数逐 Token 回流 → 前端 document 状态更新几个关键节点在源码中的落点前端订阅page.tsx 通过useAgent同时订阅UseAgentUpdate.OnStateChanged驱动文档逐 Token 重渲染与UseAgentUpdate.OnRunStatusChanged驱动 LIVE 徽标的显隐并将agent.state.document与agent.isRunning传给DemoLayout。Runtime 代理route.ts 将名为shared-state-streaming的 Agent 显式映射到后端/shared-state-streaming端点见agents[shared-state-streaming] createAgent(/shared-state-streaming)并通过HttpAgent以 AG-UI 协议与 FastAPI 后端通信。注释明确指出默认端点刻意不是 CrewAI crew 端点因为 crew 的系统消息模板会干扰此 Demo 想要证明的状态流式事件。后端注册agent_server.py 中add_crewai_flow_fastapi_endpoint(app, shared_state_streaming_flow, /shared-state-streaming)将该 Flow 挂载为独立端点。Flow 核心逻辑shared_state_streaming.py 完整实现了预测状态 → 流式生成 → 持久化 → 确认回复四段式流程详见下文。后端实现CrewAI Flow 如何把文档状态流给前端系统提示词约定优先SYSTEM_PROMPT是行为契约的核心它约束了 LLM 的输出方式SYSTEM_PROMPT ( You are a collaborative writing assistant. Whenever the user asks you to write, draft, or revise text, always call write_document with the complete document. Do not paste the document into chat; the UI renders the tool argument live from shared state. After the tool result, reply with one short confirmation. )关键约定有三条文档一律经write_document工具参数输出、禁止把文档粘贴进聊天消息否则状态流就退化为普通聊天、工具结果后仅回一句简短确认。工具 Schemawrite_document是单参数工具语义是整体替换共享文档WRITE_DOCUMENT_TOOL { type: function, function: { name: write_document, description: Replace the shared document with complete new content., parameters: { type: object, properties: {document: {type: string}}, required: [document], }, }, }注意required: [document]与Replace ... complete new content的描述正是后续新请求干净替换旧文档验收项的根源。状态定义与预测SharedStateStreamingState继承CopilotKitState并声明共享字段class SharedStateStreamingState(CopilotKitState): document: str Flow 的write()方法首先调用copilotkit_predict_state将工具参数 → 状态字段的映射声明给 AG-UI 桥await copilotkit_predict_state( [ StateItem( state_keydocument, toolwrite_document, tool_argumentdocument, ) ] )这是整个流式渲染的枢纽StateItem告诉协议层write_document工具的document参数应当被映射为共享状态字段document并实时推送。因此LLM 还在生成参数 JSON 时前端就已经拿到部分内容实现逐 Token 效果。流式生成与状态持久化response await copilotkit_stream( await acompletion( modelopenai/gpt-5.4, messages[{role: system, content: SYSTEM_PROMPT}, *self.state.messages], toolstools, parallel_tool_callsFalse, streamTrue, ) ) message response.choices[0].message self.state.messages.append(message)acompletion(..., streamTrue)以流式方式调用 LLMcopilotkit_stream将 token 流转换为 AG-UI 事件流并转发前端。parallel_tool_callsFalse确保单次只处理一个工具调用避免多路write_document竞争同一文档。生成结束后Flow 从工具调用中提取document参数并写入共享状态document arguments.get(document) self.state.document document if isinstance(document, str) else 随后追加 tool 消息、通过copilotkit_emit_tool_result将工具结果发回前端并再发起一次流式调用生成简短的确认回复。第二次调用正是 QA 文档中assistant sends a short confirmation这一验收项的后端来源。防御性细节非法 JSON 兜底try: arguments json.loads(write_call.get(function, {}).get(arguments) or {}) except (TypeError, json.JSONDecodeError): arguments {} document arguments.get(document) self.state.document document if isinstance(document, str) else 若模型返回的参数不是合法 JSON或document缺失/非字符串状态会被安全置为空字符串——这正是非写作提问不破坏当前文档验收项的底层保障。前端实现DocumentView 面板的三个可观测信号前端 UI 由 document-view.tsx 承载它消费content文档状态与isStreaming运行状态两个 prop暴露三个 QA 可观测点document-view/ 空状态根节点带data-testiddocument-view。当content为空且未在运行时渲染斜体占位文案Ask the agent to write something — its output will stream here token by token.对应 QA 第 1 步验证空状态说明输出将逐 Token 流入文档。document-live-badgeLIVE 徽标仅当isStreaming为真时渲染红底白字、带脉冲动画圆点与data-testiddocument-live-badge绑定。它是Agent 正在运行的实时指示器。document-char-count与document-content右上角data-testiddocument-char-count显示content.length0 chars起步正文区data-testiddocument-content以whitespace-pre-wrap渲染文档全文流式期间末尾追加一个闪烁的块状光标。DemoLayoutdemo-layout.tsx将文档面板与CopilotSidebar占位符 Ask me to write something...并排组合suggestions.ts 通过useConfigureSuggestions注册三个起始建议建议标题实际发送的消息Write a short poemWrite a short poem about autumn leaves.Draft an emailDraft a polite email declining a meeting next Tuesday afternoon.Explain quantum computingWrite a 2-paragraph explanation of quantum computing for a curious teenager.自动化验证Playwright E2E 断言清单QA 文档的全部手工步骤在仓库中都有对应的自动化版本 shared-state-streaming.spec.ts。两者可对照使用——手工步骤适合冒烟验收E2E 适合接入 CI。基础功能对应 QA 第 1 节// page loads with document panel and chat sidebar await expect(page.locator([data-testiddocument-view])).toBeVisible({ timeout: 15000 }); await expect(page.getByText(Document)).toBeVisible({ timeout: 10000 }); await expect(page.locator([data-testiddocument-char-count])).toHaveText(0 chars, { timeout: 10000 }); await expect(page.getByPlaceholder(Ask me to write something...)).toBeVisible({ timeout: 10000 });面板挂载、标题 Document 可见、字符计数初始为0 chars、聊天输入占位符正确空状态下document-content不应可见not.toBeVisible()三个建议按钮均以 rolebutton 断言存在。流式行为对应 QA 第 2 节const input page.getByPlaceholder(Ask me to write something...); await input.fill(Write a short poem about autumn leaves.); await input.press(Enter); // document-content 出现60s 超时覆盖完整流式周期 await expect(page.locator([data-testiddocument-content])).toBeVisible({ timeout: 60000 }); // 字符数超过 0 await expect(async () { const text await charCount.textContent(); expect(parseInt(text!.replace(/\D/g, ), 10)).toBeGreaterThan(0); }).toPass({ timeout: 60000 }); // LIVE 徽标在运行期出现且发送前不可见 await expect(page.locator([data-testiddocument-live-badge])).toBeVisible({ timeout: 60000 }); // 侧边栏出现 assistant 消息 await expect(page.locator([data-testidcopilot-assistant-message]).first()).toBeVisible({ timeout: 60000 });关键点流式断言统一使用60 秒超时因为一次完整的生成 确认回复可能持续较久char-count解析使用replace(/\D/g, )剔除 chars 字样提取数字。错误处理与验收标准对应 QA 第 3 节与 Expected ResultsQA 文档列出的三类异常场景逐一对应源码中的防御逻辑空消息是 no-opCopilotSidebar与前端层面对空输入直接忽略不产生请求因此不会触发状态变更。非写作提问不破坏文档即使 LLM 未调用write_documentFlow 中write_call is None分支会提前returnself.state.document保持原值见 shared_state_streaming.py。配合copilotkit_emit_tool_result只在实际写入后触发聊天中多问一句你好吗不会污染文档面板。无未捕获错误E2E 中 Playwright 默认会捕获页面 console 异常后端 route.ts 的 POST 处理同样做了兜底——错误 ID 落服务端日志客户端只收到脱敏的{ error, errorId }不泄露内部路径与堆栈。最终验收标准QA 文档 Expected Results 的源码级归因验收项源码依据文档随write_document参数流式渐进增长copilotkit_predict_stateStateItem声明映射streamTrue流式生成最终文档持久化在共享状态中self.state.document document写入 Flow 状态后续写作请求干净替换旧文档WRITE_DOCUMENT_TOOL语义为 Replace ... with complete new content每次直接覆盖state.document无 UI 错误或布局破损E2E 全流程断言 document-content的whitespace-pre-wrap渲染运行前提与复现步骤按 QA 文档 Prerequisites 与被route.ts源码印证的环境要求复现此 Demo 需要后端 Agent 已部署且健康FastAPI 服务监听 8000 端口/api/health返回 ok前端 route.ts 的 GET 健康探针会校验AGENT_URL指向的/health默认http://localhost:8000可用环境变量AGENT_URL覆盖。Demo 页面可访问启动 Next.js 前端后访问/demos/shared-state-streaming。LLM 密钥就绪后端依赖OPENAI_API_KEY调用openai/gpt-5.4健康探针会返回其是否已配置。可选开启SHOWCASE_ROUTE_DEBUG1查看逐请求日志默认关闭以规避高频日志限流。手动验证时只需逐条勾选 QA 文档 的清单自动化验证则直接运行对应 Playwright 用例。小结shared-state-streaming是 CopilotKit 共享状态能力的最小完整示范后端用copilotkit_predict_state声明工具参数即状态用copilotkit_stream把参数逐 Token 推送前端用useAgent订阅状态与运行态驱动只读文档面板渐进渲染。QA 文档提供可勾选的验收清单Playwright 用例提供可自动化的等价断言。理解这条链路后你可以把它复用到报告生成、邮件草稿、代码补全等一切需要把 Agent 产出实时呈现给用户的场景。【免费下载链接】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),仅供参考