ARTICLE DETAIL

资讯详情

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

CopilotKit 状态流式更新(State Streaming):把工具参数逐 Token 推入共享状态的前后端全链路解析

CopilotKit 状态流式更新(State Streaming):把工具参数逐 Token 推入共享状态的前后端全链路解析 CopilotKit 状态流式更新State Streaming把工具参数逐 Token 推入共享状态的前后端全链路解析【免费下载链接】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 仓库中 Mastra 集成演示shared-state-streaming的官方说明文档与配套源码详解“状态流式更新”这一共享状态Shared State的高级形态当 Agent 正在执行一个长耗时工具调用写作、起草邮件、生成长文档时如何把该工具某个参数的每一个流式 Token直接映射进 Agent 共享状态的一个键让前端在工具调用尚未结束时就能逐字符看到内容“长”出来。读完后你将掌握该模式的后端声明式映射写法、Mastra 框架下的等价实现机制、前端useAgent订阅细节以及配套实时文档面板的完整实现思路。一、要解决的问题长工具调用期间的“状态黑屏”默认的 Agent 运行模型下共享状态只在后端检查点checkpoint之间更新。这意味着一次长时间运行的工具调用——比如让模型写一整首诗、起草一封邮件——在 UI 侧会表现为中间全程空白或转圈等工具调用结束时完整内容“砰”地一下整体出现。对于 agent 原生的应用形态这种体验是明显不合理的用户期望的是看着答案逐 Token 生成出来。这正是官方文档 State Streaming 文档中描述的核心痛点By default, agent state only updatesbetweenbackend checkpoints, so a long-running tool call (writing a full document, drafting an email) appears to the UI as one big burst at the end.状态流式更新State Streaming的做法是在工具参数正在被 LLM 生成的过程中就把该参数的值持续转发写入指定的 Agent 状态键。前端通过useAgent订阅状态变化每个 Token 到达都会触发一次重渲染。官方文档给出的适用场景与演示 README 完全对应包括协作写作 Agent 输出整篇文档研究 Agent 不断累积发现列表list of findings规划 Agent 逐步搭建步骤计划step-by-step plan。一句话概括没有流式更新时用户盯着转圈有流式更新时用户看着答案逐 Token 长大。二、演示效果一个“边写边长”的实时文档面板shared-state-streaming演示位于 showcase 的 Mastra 集成目录其 README 概括了演示的三大视觉要素全部可以在源码中找到对应实现实时文档面板state.document被渲染进一个文档视图伴随闪烁光标与 “LIVE” 徽标Token 级增量Agentwrite_document工具参数中流式的每一个 Token 都被原样转发进document状态键字符计数器面板右上角持续更新的字符数让“逐 Token 流入”这一事实肉眼可见。三个要素在 document-view.tsx 中的实现如下节选export function DocumentView({ content, isStreaming }: DocumentViewProps) { const charCount content.length; // ... {isStreaming ( span>useConfigureSuggestions({ suggestions: [ { title: Write a short poem, message: Write a short poem about autumn leaves. }, { title: Draft an email, message: Draft a polite email declining a meeting next Tuesday afternoon. }, { title: Explain quantum computing, message: Write a 2-paragraph explanation of quantum computing for a curious teenager. }, ], available: always, });点击任一条就能看着文档面板被 Agent 实时“填”满。三、后端模式一条声明式的流式状态映射演示 README 的“Technical Details”一节点出了该模式的精髓——一条中间件配置StateStreamingMiddleware( StateItem( state_keydocument, toolwrite_document, tool_argumentcontent, ) )对应 LangGraph Python 路径文档中的完整说明见 predictive-state-updates 文档。这段声明的语义是三元组映射state_key目标状态键documenttool被监控的工具write_documenttool_argument被流式转发的参数content。当 LLM 为content参数流式生成 Token 时CopilotKit 在工具执行完成之前就把每个部分值partial value写入共享状态——这就是 README 所说的 “Without it,state.documentwould only update when the tool call finishes. With it, every token … is mirrored into state immediately.”结合官方文档 streaming.mdx 的进一步说明这条映射有三条必须遵守的规则状态键必须真实存在于 Agent 状态 schema 中本演示即document工具名与参数名必须与 LLM 实际看到的工具调用签名完全一致本演示即write_document的content参数写错名字则映射不生效工具调用完成后其最终返回值会写回同一个键因此流式写入的部分值最终会被权威终值覆盖收敛中间过程不会污染最终状态。不同框架对这一模式的落地形态不同文档中概括为中间件类框架如 LangGraph Python以StateStreamingMiddlewareStateItem这样的声明式映射暴露LangGraph TypeScript可用copilotkitCustomizeConfig的emitIntermediateState做同样的映射直连 SDK 适配器在自身的流式循环中解析部分工具参数每当映射值变化就发出STATE_SNAPSHOT。共同点只有一个把“一个流式工具参数”映射到“一个共享状态键”其余交给框架的 AG-UI 事件通道。四、Mastra 框架下的等价实现updateWorkingMemory与 AG-UI 事件流本演示位于 Mastra 集成中showcase/integrations/mastra。Mastra 没有提供StateStreamingMiddleware这样的类而是用一条内置工具 适配器拦截的路径实现同等效果。阅读 agents/index.ts 中该演示对应的状态 schema 定义及其注释可以完整还原这条链路// region[shared-state-streaming-state-schema] export const SharedStateStreamingAgentState z.object({ document: z.string().default(), }); // endregion[shared-state-streaming-state-schema]注释中说明了 Mastra 对 LangGraph “StateStreamingMiddleware/ predictive-state” 模式的 parity对等做法Agent 不定义自定义write_document工具而是调用 Mastra内置的updateWorkingMemory工具把持续增长的完整文档写入document键AG-UI 的 Mastra 适配器会拦截该工具调用的流式参数注释中标注为 OSS-414先发出一个STATE_SNAPSHOT随后在document键上持续发出增量的STATE_DELTA前端useAgent({ updates: [OnStateChanged] })因此能观察到state.document逐 Token 增长。Agent 定义本身见 agents/index.tsexport const sharedStateStreamingAgent new Agent({ id: shared-state-streaming, name: Shared State Streaming Agent, tools: {}, // 不挂任何自定义工具 model: openai(gpt-4o), instructions: You are a collaborative writing assistant wired to a live Document panel. Whenever the user asks you to write, draft, revise, or explain anything of any length (...), you MUST call the updateWorkingMemory tool with the FULL content as a single string under the document field, e.g. { document: the full text }. Rules: - NEVER paste the document body into a chat message. ... - Always send the ENTIRE document in one updateWorkingMemory call (not a diff, not chunks across multiple calls). - After the document is written, reply with ONE short chat sentence confirming what you wrote ..., memory: new Memory({ storage: new LibSQLStore({ id: shared-state-streaming-agent-memory, url: WORKING_MEMORY_DB_URL, }), options: { workingMemory: { enabled: true, schema: SharedStateStreamingAgentState, // 声明 document 键 }, }, }), });其中两个设计要点值得注意Prompt 即协议由于走的是内置工具路径提示词承担了“约束模型行为”的职责——文档正文绝不允许出现在聊天消息里必须以“全文、单次调用”的形式写入 working memory 的document键写完后再用一句简短确认语收尾。流式增量而非运行结束的一次性快照源码注释明确对比了同仓库其他共享状态演示如sharedStateReadWriteAgent/genUiAgent它们用自定义set_*工具、只在运行结束时发一次STATE_SNAPSHOT——本演示刻意选择内置updateWorkingMemory路径因为这是**唯一能产生逐 Token 渐进 delta而非运行末尾一个整体 blob**的路径。从源码结构看Mastra 将该工具调用的参数以tool-call-delta帧流式下发AG-UI Mastra 适配器累积这些 delta、对不断变长的 JSON 前缀做增量解析再转译为STATE_SNAPSHOTSTATE_DELTA序列。提示README 中展示的StateStreamingMiddleware/StateItem是 LangGraph 路径的写法在本 Mastra 演示中其职责由 “updateWorkingMemory工具 AG-UI 适配器拦截流式参数” 等价承担。二者对外呈现给前端的语义完全一致state.document在工具调用过程中持续增长。五、前端订阅useAgent的两个更新维度前端部分没有任何特殊逻辑与任意共享状态订阅一致——这正是该模式“声明式、低侵入”的体现。完整实现见 page.tsx// 同时订阅“状态变更”与“运行状态变更”。 // 前者驱动文档的逐 Token 重渲染后者驱动 LIVE 徽标的亮/灭。 const { agent } useAgent({ agentId: shared-state-streaming, updates: [UseAgentUpdate.OnStateChanged, UseAgentUpdate.OnRunStatusChanged], }); const agentState agent.state as StreamingAgentState | undefined; const document agentState?.document ?? ; const isRunning agent.isRunning; return DemoLayout document{document} isStreaming{isRunning} /;这里两个updates的分工与 README 的描述一一对应OnStateChanged每次STATE_DELTA让state.document变化时触发组件重渲染文档文本因此逐 Token 变长OnRunStatusChangedAgent 开始/停止运行时触发前端用agent.isRunning切换 “LIVE” 徽标与闪烁光标的显隐。页面入口则是标准的 CopilotKit 包装page.tsxexport default function SharedStateStreamingDemo() { return ( CopilotKit runtimeUrl/api/copilotkit agentshared-state-streaming DemoContent / /CopilotKit ); }聊天侧边栏通过 demo-layout.tsx 中的CopilotSidebar agentIdshared-state-streaming defaultOpen{true} /挂载左侧文档面板、右侧聊天面板共同构成演示界面。六、小结一个参数到一个状态键的映射把全文收敛为一个心智模型环节承担者作用流式源LLM 生成content/document参数的 Token 流产生部分值后端映射StateStreamingMiddlewareStateItemLangGraph或updateWorkingMemory AG-UI 适配器Mastra把每个部分值写入共享状态键document并以STATE_SNAPSHOT/STATE_DELTA下发前端订阅useAgent({ updates: [OnStateChanged, OnRunStatusChanged] })逐 Token 重渲染文档agent.isRunning控制 LIVE 指示UI 呈现DocumentView文本 闪烁光标 LIVE 徽标 字符计数这套机制的通用约束状态键须存在于 schema、工具/参数名须与 LLM 侧签名精确匹配、工具最终返回值会收敛覆盖流式部分值在官方文档 streaming.mdx 中均有明确说明是跨框架复用时最需要核对的三点。围绕该模式的更多上下文可参阅文档中的 Shared State 总览 关联章节以及 LangGraph 预测式状态更新、DeepAgents 状态渲染 等文档仓库侧的完整实现则可沿 Mastra 集成演示 与 前端源码 继续深入。【免费下载链接】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),仅供参考
返回列表