CopilotKit 状态流式渲染实战让工具参数逐 Token 实时写入共享 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本文以仓库中的 State Streaming 演示文档 为主线剖析 CopilotKit 如何借助 ADK 的PredictStateMapping与streaming_function_call_arguments两个配置让 Agent 工具调用的参数在生成过程中逐 Token 流式写入共享状态并在前端文档面板中实时渲染。读完本文你将掌握这套工具参数边生成边可见的端到端实现方案并能在自己的 Google ADK CopilotKit 项目中复刻同样的LIVE体验。一、演示概览一个会打字的文档面板该演示的核心效果是工具调用的参数按 Token 逐字流式写入共享的 Agent 状态——当 Agent 仍在执行write_document工具调用时界面中的文档已经随着每一个生成的字符实时增长。整个效果由三个要素构成实时文档面板state.document被渲染在一个文档视图中配有闪烁光标与 LIVE 徽章Token 级增量Agent 的write_document工具参数中每个流式到达的 Token 都被直接转发进document状态键字符计数器面板顶部的实时字符数让逐 Token 流式的过程一目了然。用一句话概括文档的打字过程可见而不仅是写完了才显示。二、如何交互页面打开后点击建议芯片suggestion chip或者直接在侧边聊天中输入例如Write a short poem about autumn leaves.Draft a polite email declining a meeting next Tuesday afternoon.Write a 2-paragraph explanation of quantum computing for a curious teenager.观察文档面板随 Agent 的写作过程实时填充。建议芯片本身由 suggestions.ts 中的useConfigureSuggestions配置available: always保证其始终可用三个芯片分别对应当前可交互界面中展示的三条示例请求。三、技术核心两个开关驱动的状态流式演示文档指出整个魔法本质上是 ADKAgent 中间件上的一个PredictStateMapping条目PredictStateMapping( state_keydocument, toolwrite_document, tool_argumentcontent, stream_tool_callTrue, )配合同一个 ADKAgent 中间件上的streaming_function_call_argumentsTrue让底层 ADK runner 发出增量的TOOL_CALL_ARGS事件。缺少这两个开关中的任何一个state.document都只能在工具调用完成后才更新两者齐备后LLM 为工具参数生成的每一个 Token 都会即时镜像到状态中。前端再通过useAgent({ updates: [OnStateChanged, OnRunStatusChanged] })驱动文本与 LIVE 徽章的重渲染agent.isRunning负责切换光标。3.1 仓库中的真实配置参数名以源码为准需要特别指出的是README 中示例写作tool_argumentcontent而当前仓库的实际实现位于 shared_state_streaming_agent.py参数名与 README 示例并不完全一致SHARED_STATE_STREAMING_PREDICT_STATE [ PredictStateMapping( state_keydocument, toolwrite_document, tool_argumentdocument, # 与 write_document 工具形参同名 emit_confirm_toolFalse, # 不额外发送工具确认消息 stream_tool_callTrue, # 工具调用参数随生成过程流式发出 ), ]从源码注释看write_document工具的形参刻意命名为document以对齐 langgraph-python 侧的write_document签名与共享 D5 fixturetool_argumentdocument。因此在实际落地时tool_argument必须与你定义的工具形参名严格一致否则状态映射不会命中。PredictStateMapping各字段含义字段作用state_key写入共享状态的键名此处为documenttool被监听流式的工具名此处为write_documenttool_argument工具签名中参与流式的参数名必须与工具形参一致stream_tool_call是否在工具调用参数流式到达时即时触发状态增量emit_confirm_tool是否额外发出工具确认消息设为False可减少冗余消息3.2 streaming_function_call_arguments 的作用在 agent_server.py 中每个注册的 Agent 都会挂载一个ADKAgent中间件并将注册表里的predict_state与streaming_function_call_arguments传入middleware ADKAgent( adk_agentspec.llm_agent, user_iddemo_user, session_timeout_seconds3600, use_in_memory_servicesTrue, predict_statespec.predict_state, emit_messages_snapshotspec.emit_messages_snapshot, streaming_function_call_argumentsspec.streaming_function_call_arguments, ) add_adk_fastapi_endpoint(app, middleware, pathf/{agent_name})streaming_function_call_argumentsTrue的作用是让ag_ui_adk订阅底层 ADK runner 的增量TOOL_CALL_ARGS事件。PredictStateMapping(stream_tool_callTrue)则负责把每一份增量参数立即转换为STATE_DELTA推向前端——两处缺一不可。值得注意的版本前提来自 shared_state_streaming_agent.py 与 registry.py 的注释真正的逐 Token 流式要求google-adk 1.24.0 且经由 Vertex AI运行在旧版本或 Gemini Studio 路径下中间件会在启动时发出UserWarning并回退到chunk 级流式STATE_DELTA仍然会产生只是粒度更粗、刷新频率更低两种模式下 UI 的 LIVE 徽章都保持诚实只是回退路径每秒更新次数更少。四、后端 Agent 实现write_document 工具与终止回调State Streaming 的后端 Agent 定义在 shared_state_streaming_agent.py 中完整链路如下4.1 write_document 工具把正文写进共享状态def write_document(tool_context: ToolContext, document: str) - dict: Write a document into shared state. tool_context.state[document] document return {status: ok, length: len(document)}工具函数通过tool_context.state写入共享状态并返回文档长度。Agent 的系统指令明确约束模型行为只要用户要求书写、起草或修改任何文本必须调用write_document工具并一次性传入完整内容禁止直接把正文贴在聊天消息里——文档属于共享状态UI 会在你输入的过程中实时渲染它。这句指令是保证文档走工具、不走聊天消息的关键也是状态流式得以成立的前提。4.2 Agent 装配与模型解析shared_state_streaming_agent LlmAgent( nameSharedStateStreamingAgent, modelget_model(), instruction_INSTRUCTION, tools[write_document, AGUIToolset()], after_model_callbackstop_on_terminal_text, )AGUIToolset()是 CopilotKit 与 ADK 的桥接工具集负责把STATE_DELTA等事件转发到前端详见 state-streaming-setup.mdxget_model()定义于 shared_chat.py在设置了GOOGLE_GEMINI_BASE_URL时返回指向代理端点的Gemini实例否则返回默认模型串gemini-3.1-flash-lite关键点模型本身不需要任何GenerateContentConfig覆盖流式行为完全由 ADKAgent 中间件控制这与 langgraph-python 的StateStreamingMiddleware设计保持一致。4.3 stop_on_terminal_text防止工具被无限重调演示文档的安装指引state-streaming-setup.mdx特意强调第三点Agent 将stop_on_terminal_text注册为after_model_callback。该回调实现在 shared_chat.py跳过所有partialTrue的流式中间块绝不在流式中途终止仅在最终的非增量响应包含文本、且没有挂起的function_call、且finish_reason STOP时才设置_invocation_context.end_invocation True对 Gemini 的FUNCTION_CALLfinish_reason 做了专门守卫避免 thinking 模式下 text-only 块提前终止 Agentic 循环。没有这个回调Gemini 会在一次成功的工具调用后不断重发同一个工具调用形成死循环——这是所有后端/前端工具类 Demo 的通用防护。五、注册与装配AgentSpec 数据类registry.py 中的AgentSpec数据类定义了每个 Demo Agent 的后端接线方式其中与状态流式相关的两个字段有详细注释dataclass class AgentSpec: llm_agent: LlmAgent predict_state: Optional[Sequence[PredictStateMapping]] field(defaultNone) emit_messages_snapshot: bool False # streaming_function_call_argumentsTrue 让 ADKAgent 中间件进入逐 Token # TOOL_CALL_ARGS 事件模式要求 google-adk 1.24.0 经由 Vertex AI # 旧版本/Gemini Studio 路径下中间件发出 UserWarning 并回退到 chunk 级。 # 与 PredictStateMapping(stream_tool_callTrue) 配合UI 能看到 # 工具参数到达过程中文档不断增长。 streaming_function_call_arguments: bool Falseshared-state-streaming在注册表中的条目registry.py同时开启了两项能力shared-state-streaming: AgentSpec( shared_state_streaming_agent, predict_stateSHARED_STATE_STREAMING_PREDICT_STATE, streaming_function_call_argumentsTrue, ),predict_state字段特意声明为Sequence而非Iterable——注释指出这是为了防止误传入一次性生成器generator导致首个请求消费后即被清空。这一细节对自建多 Agent 注册表有直接的参考价值。六、前端实现订阅状态与运行状态6.1 页面入口与 useAgent 订阅page.tsx 中页面用CopilotKit绑定 runtime 与 Agent并在DemoContent内完成关键订阅export default function SharedStateStreamingDemo() { return ( CopilotKit runtimeUrl/api/copilotkit agentshared-state-streaming DemoContent / /CopilotKit ); } function DemoContent() { 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} /; }两个订阅各有分工源码注释明确说明OnStateChanged驱动文档正文的逐 Token 重渲染——每收到一次STATE_DELTAdocument字符串变长组件重新渲染OnRunStatusChangedAgent 启动/停止时切换 LIVE 徽章。UseAgentUpdate枚举定义于 use-agent.tsx共三个取值OnMessagesChanged、OnStateChanged、OnRunStatusChanged。该文件还提供了throttleMs配置use-agent.tsx可用于高频率流式更新时合并重渲染——采用 leading trailing 的节流模式首个更新立即触发窗口内后续更新合并窗口结束后再由尾部定时器补发最新值未设置时继承 Provider 的defaultThrottleMs两者均未设置则等效为 0不节流。6.2 布局与文档视图组件demo-layout.tsx 将DocumentView与CopilotSidebar组合侧边栏绑定同一agentIdshared-state-streaming并自定义输入占位符Ask me to write something...。document-view.tsx 是逐 Token 可见的直接呈现者content为当前文档文本每次流式 Token 到达后由父组件以更长的字符串重新渲染isStreaming为true时显示红色 LIVE 徽章含脉动圆点与闪烁的文本光标右上角的{charCount} chars字符计数提供了一个廉价的Token 感可视化空态提示语引导用户发起写作请求组件暴露了document-view、document-live-badge、document-char-count、document-content等data-testid便于自动化测试断言流式行为。七、安装与运行仓库在 state-streaming-setup.mdx 中给出了三个关键步骤第一步安装 ADK AG-UI 桥接包pip install ag-ui-adk第二步声明预测状态映射使用PredictStateMapping将流式的write_document工具参数映射到state[document]并确保 Agent 挂载了AGUIToolset()CopilotKit 才能把状态增量转发到 UI。完整实现见 shared_state_streaming_agent.py 的state-streaming-middleware代码区段。第三步注册终止回调将stop_on_terminal_text设为 Agent 的after_model_callback防止 Gemini 在最终文本响应后再次发起同样的工具调用。整个后端服务由 agent_server.py 的 uvicorn 启动默认端口 8000开发环境可用UVICORN_RELOAD1开启热重载前端通过/api/copilotkit路由见 route.ts与后端建立连接。八、限制与注意事项逐 Token 精度依赖运行环境streaming_function_call_argumentsTrue的逐 TokenTOOL_CALL_ARGS事件要求 google-adk 1.24.0 且经由 Vertex AIGemini Studio 或旧版本只能获得 chunk 级流式UI 更新粒度变粗但功能不回退。参数名必须对齐PredictStateMapping.tool_argument必须与工具形参名完全一致本仓库为documentREADME 中的content仅为示意照抄会导致状态映射不命中。模型无需额外配置流式行为完全由中间件控制不要试图通过GenerateContentConfig覆盖来实现否则与既有架构设计相悖。工具是唯一写入通道Agent 指令明确禁止把正文直接放进聊天消息保证状态驱动的渲染模型不被破坏。九、相关源码速查演示说明文档README.md后端 Agent 与状态映射shared_state_streaming_agent.pyAgent 注册表与 AgentSpecregistry.py服务装配与中间件挂载agent_server.py共享工具函数与终止回调shared_chat.py前端页面与订阅page.tsx文档视图组件document-view.tsx安装步骤state-streaming-setup.mdxUseAgentUpdate枚举与节流参数use-agent.tsx【免费下载链接】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),仅供参考