
CopilotKit 集成 Google ADK 构建 Angular 全栈 AI Agent架构、共享状态与生成式 UI 实战指南【免费下载链接】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本指南以仓库中的 adk-angular 示例 为蓝本完整拆解如何在 Angular 前端接入 Google ADK Agent一个 Angular SPA 独立 Node Copilot Runtime Python ADK Agent 的三进程架构涵盖共享 Agent 状态Shared State、生成式 UIGenerative UI、前端工具Frontend Tools、建议提示Suggestions以及可选的 Threads 持久化会话抽屉。读完本文你将掌握这套 Starter 的端口分工、启动流程、每个文件的职责并能对照源码看懂 runtime 代理与 ADK 回调机制最终在此基础上改造出自己的 CopilotKit ADK 应用。架构总览三个进程一个npm run devadk-angular Starter 的核心设计是前后端解耦、进程隔离Angular 界面、Copilot Runtime、Python ADK Agent 各自独立运行通过 HTTP 通信。这与 React 版 ADK 示例架构一致只是把前端换成了 Angular组件均使用 Standalone Zoneless Change Detection 编写。三个进程由concurrently编排仅需一条npm run dev即可同时拉起见 package.json进程端口是什么ui4200Angular 应用ng serveruntime8200独立 Copilot Runtimetsx server.ts挂载在/api/copilotkitagent8000Python ADK Agent由uv驱动三者间的数据流是一条清晰的两段式链路前端 → RuntimeAngular 应用通过http://localhost:8200/api/copilotkit与 Copilot Runtime 通信该 URL 硬编码在 app.config.ts 的provideCopilotKit配置中。Runtime → AgentRuntime 通过HttpAgent把请求代理给 ADK Agent默认目标地址为http://localhost:8000/可用环境变量AGENT_URL覆盖见 server.ts。也就是说Runtime 在这里扮演胶水层对前端暴露统一的 CopilotKit 协议端点对后端代理 AG-UI 协议的 ADK Agent。关于 Runtime 端口的一个设计细节server.ts将端口固定为 8200而不是读取process.env.PORT。原因是同一个npm run dev启动的 Python ADK Agent 会读取.env中的PORT默认 8000并绑定该端口若 Runtime 也去读PORT两个进程会争抢同一端口发生冲突server.ts 中有注释说明。这个注释本身就是踩坑后的经验总结值得在改造时留意。环境准备在开始之前请确认以下前提条件Node.js 20.19这是 Angular 21 工具链的最低要求如果还要启用 managed IntelligenceThreads 记忆则需要Node.js ≥ 22Python 3.12ADK Agent 的运行环境uvPython 包管理器用于安装 Agent 依赖并创建虚拟环境Google Makersuite API KeyADK Agent 调用 Gemini 模型所需可在 Google AI Studio 的 API Key 页面申请之后填入.env的GOOGLE_API_KEY。依赖版本方面前端使用copilotkit/angular 0.3.1与copilotkit/core、copilotkit/runtime、copilotkit/shared1.70.0Agent 侧使用ag-ui-adk0.7.0、ag-ui-protocol0.1.18以及google-adk、google-genai见 agent/pyproject.toml。仓库通过overrides统一锁定了 AG-UI 与 CopilotKit 相关包的版本避免依赖树出现版本漂移。快速开始按以下三步即可把整套环境跑起来1. 安装依赖会顺带准备 Python 环境npm installpackage.json中定义了一个postinstall钩子它会在 npm 安装完成后自动执行npm run install:agent进而通过uv在agent目录下创建虚拟环境并安装 ADK Agent 的全部依赖。也就是说一次npm install同时完成了前端与后端的依赖安装。该流程会在agent目录下创建一个.venv。如果你想手动进入该环境可执行source agent/.venv/bin/activate2. 配置环境变量cp .env.example .env # 然后编辑 .env设置 GOOGLE_API_KEY....env中最核心的变量是GOOGLE_API_KEY其余变量AGENT_URL、Intelligence 相关配置都有默认值或为可选详见下文。3. 启动完整开发栈npm run dev然后打开 http://localhost:4200 即可看到三栏布局的界面。启动后你可以在日志中确认 Runtime 是否就绪——server.ts会在监听成功后打印Copilot Runtime listening at http://localhost:8200/api/copilotkitnpm scripts 全解析package.json 中提供的脚本分工明确开发与运维都很顺手脚本作用dev用concurrently同时启动 UI、Runtime、Agent 三个进程任一进程退出即终止其他进程--kill-others并以不同颜色区分三者的日志dev:debug等价于LOG_LEVELdebug npm run dev以调试级别输出 Runtime 日志dev:ui只启动 Angular UIng servedev:runtime只启动 Copilot Runtimetsx server.tsdev:agent只启动 Python ADK Agentbuild生产构建 Angular 应用ng buildstart运行 Angular 开发服务器ng serveinstall:agent单独通过uv安装 Python Agent 依赖注意dev:agent与install:agent都使用了./scripts/run-agent.sh || scripts\\run-agent.bat这种先试 Shell 脚本、失败回退到 Windows 批处理的写法保证跨平台可用。run-agent.sh的实质就是进入agent目录 → 激活.venv→ 执行uv run main.py见 scripts/run-agent.sh。仓库内文件地图每个文件的职责对照 README 的说明与源码项目结构如下src/app/app.ts —— 根组件三栏布局Threads 抽屉 / 主题主面板 / 可折叠聊天面板以及setThemeColor前端工具的注册src/app/app.config.ts ——provideCopilotKit装配Runtime URL、get_weather生成式 UI 渲染器、静态建议列表、聊天配置 Providersrc/app/proverbs.ts —— 共享 Agent 状态injectAgentStore的读取与写入示例src/app/main-content.ts —— 主题化的中央面板承载谚语卡片src/app/agent-state.ts —— 共享状态AgentState的类型定义src/app/weather-card.ts —— Agent 调用get_weather时渲染的生成式 UI 卡片server.ts —— 独立 Copilot Runtime注册defaultAgent内含按环境变量门控的 managed Intelligencescripts/ ——dev/installnpm 脚本调用的跨平台启动器agent/ —— Python ADK Agent 源码与 React ADK 示例保持同一套实现.env.example —— 环境变量模板。源码级拆解Runtime 如何代理 ADK Agentserver.ts 只有约 55 行却完整展示了 Copilot Runtime 的三种关键能力。1. 通过HttpAgent代理远程 Agentconst runtime new CopilotRuntime({ agents: { default: new HttpAgent({ url: process.env.AGENT_URL || http://localhost:8000/, }), }, ... });这里注册了一个名为default的 Agentapp.config.ts中导出的AGENT_ID default与之对应是前端copilot-chat、Threads 抽屉、injectAgentStore等所有 API 的公共标识。HttpAgent来自ag-ui/client它让 Runtime 不必内嵌推理逻辑而是把 AG-UI 会话转发给任意实现了 AG-UI 协议的远端服务——这正是本示例中 Python ADK Agent 所扮演的角色。2. 挂载到 Node HTTP 服务的协议端点createServer( createCopilotNodeListener({ runtime, basePath: /api/copilotkit, cors: true, }), ).listen(port, ...);createCopilotNodeListener把 Runtime 接入原生node:http在/api/copilotkit路径下暴露协议端点并开启 CORSAngular 前端在 4200 端口跨域访问 8200 需要此项。3. 按环境变量门控的 Intelligence 与内存兜底当设置了CPK_INTELLIGENCE_API_KEY时Runtime 会挂载CopilotKitIntelligence提供 Threads 持久化 会话记忆否则回退到InMemoryAgentRunner内存运行器无持久化。这一开箱即用、可选增强的设计让你可以先跑通基础对话再决定是否接入持久化后端。源码级拆解Python ADK Agent 的共享状态与工具Agent 侧的核心实现在 agent/main.py它演示了 AG-UI ADK 集成的三个要点。1. 用 Pydantic 模型描述共享状态class ProverbsState(BaseModel): proverbs: list[str] Field( default_factorylist, descriptionThe list of already written proverbs, )共享状态是一个谚语列表proverbs。为了让 LLM 始终感知当前状态示例通过 ADK 的回调机制做了两件重要的事before_agent_callbackon_before_agent每次 Agent 运行前检查callback_context.state中是否存在proverbs不存在则初始化为空列表before_model_callbackbefore_model_modifier在每次调用模型前把当前谚语列表的 JSON 序列化结果以前缀方式注入到 system instruction 中main.py。这样一来模型每一次决策都看得见最新的共享状态从而正确判断该增、删还是改哪些谚语。2. 服务端工具更新状态与查询天气def set_proverbs(tool_context: ToolContext, new_proverbs: list[str]) - Dict[str, str]: tool_context.state[proverbs] new_proverbs[proverbs] return {status: success, message: Proverbs updated successfully} def get_weather(tool_context: ToolContext, location: str) - Dict[str, str]: return {status: success, message: fThe weather in {location} is sunny.}set_proverbs通过tool_context.state直接改写共享状态get_weather则是演示用的假天气工具永远返回 sunny供生成式 UI 演示使用。Agent 的 system prompt 中对这两个工具的使用规则约束得非常细致修改谚语时必须把完整列表传给set_proverbs而非只传增量并给出了加一条关于肥皂的谚语删除第一条把关于猫的谚语改成 18 条命等具体正反例main.py这对指导模型正确调用工具至关重要。3. 关键AGUIToolset()暴露前端工具tools[set_proverbs, get_weather, AGUIToolset()],注释说明main.pyAGUIToolset会把前端注册的工具例如setThemeColor暴露给 LLM——ag_ui_adk会把它替换成一个连接到当前会话所转发客户端工具的ClientProxyToolset。如果没有它LLM 只能看到服务端工具将无法调用前端工具这是前端工具这条链路能否打通的关键一行。此外simple_after_model_callback演示了如何在模型返回文本后立即结束本轮调用callback_context._invocation_context.end_invocation True避免模型连续追加工具调用。最后Agent 通过ADKAgent(adk_agentproverbs_agent, user_iddemo_user, session_timeout_seconds3600, use_in_memory_servicesTrue)包装为 AG-UI 兼容的中间件并借助add_adk_fastapi_endpoint(app, adk_proverbs_agent, path/)挂载到 FastAPI 应用上同时暴露/health健康检查端点main.py。源码级拆解Angular 前端的四大能力1.provideCopilotKitRuntime 连接、生成式 UI 与建议app.config.ts 中的配置集中展示了前端接入 CopilotKit 的方式provideCopilotKit({ runtimeUrl: http://localhost:8200/api/copilotkit, renderToolCalls: [ { name: get_weather, args: weatherArgs, component: WeatherCard }, ], suggestionsConfig: [ { available: always, suggestions: [ { title: Generative UI, message: Get the weather in San Francisco. }, { title: Frontend Tools, message: Set the theme to green. }, { title: Write Agent State, message: Add a proverb about AI. }, { title: Update Agent State, message: Please remove 1 random proverb from the list if there are any. }, { title: Read Agent State, message: What are the proverbs? }, ], }, ], }), provideCopilotChatConfiguration({ agentId: AGENT_ID }),runtimeUrl指向 Copilot RuntimerenderToolCalls把 Agent 的get_weather工具调用映射到 Angular 组件WeatherCard参数 schema 用 zod 的weatherArgs声明这就是生成式 UI 的声明式注册方式suggestionsConfig提供输入框上方的静态建议药丸五条建议分别覆盖生成式 UI、前端工具、写入/更新/读取共享状态五个演示场景provideCopilotChatConfiguration是 SDK 中当前活动线程的所有者相当于 React 版的CopilotChatConfigurationProvider这里故意不传threadId不受控让抽屉的 New可以重置出全新线程。值得强调的是该应用还启用了provideZonelessChangeDetection()即 Angular 21 的无 Zone 变更检测模式。2. 前端工具registerFrontendToolapp.ts 的构造函数里注册了setThemeColor前端工具registerFrontendTool({ name: setThemeColor, description: Set the theme color of the page., parameters: z.object({ themeColor: z.string().describe(The theme color to set. Make sure to pick nice colors.), }), handler: async ({ themeColor }) { this.themeColor.set(themeColor); return Changing theme color to ${themeColor}; }, agentId: AGENT_ID, });该工具的handler更新一个signal进而实时改变中央面板的背景色。由于前端工具参数用 zod schema 声明LLM 可以依据描述生成合法参数。主题色通过宿主元素上的--app-theme-color自定义属性向整棵组件树传播包括聊天浮层内的生成式 UI 卡片并且刻意不复用--copilot-kit-primary-color——因为聊天子树会在[data-copilotkit]宿主上重新声明该 token从而遮蔽外层设置的值app.ts 的注释说明了这一点。这个细节是主题贯穿生成式 UI 的正确做法。3. 共享 Agent 状态injectAgentStoreproverbs.ts 演示了双向读写共享状态readonly #store injectAgentStore(AGENT_ID); protected readonly proverbs computedstring[]( () (this.#store().state() as AgentState | undefined)?.proverbs ?? [], );injectAgentStore返回的 store 暴露state()只读状态与agent.setState(...)全量替换式写入。组件通过computed把共享状态映射为响应式列表删除一条谚语时先展开现有状态再写回protected remove(index: number): void { const state (this.#store().state() as AgentState | undefined) ?? {}; const next this.proverbs().filter((_, i) i ! index); this.#store().agent.setState({ ...state, proverbs: next } satisfies AgentState); }注释特别强调setState是全量替换不展开直接写回会丢掉 Agent 携带的其他状态字段。此外组件用effect实现每个 Agent 实例只播种一次的逻辑——以store.agent为键做一次性标记避免线程持久化状态加载期间出现的瞬时undefined触发重复播种、与 Agent 正在写入的状态互相打架。这些注释本身就是对injectAgentStore语义全量替换、按 Agent 实例隔离的最佳注解。4. 生成式 UI 卡片WeatherCardweather-card.ts 实现了ToolRendererWeatherArgs接口通过input.requiredAngularToolCallWeatherArgs()接收工具调用。模板展示了标题地点、温度、湿度/风速/体感三项指标等天气卡片样式。由于工具调用参数在流式过程中是 Partial 的status 为in-progress组件用computed对toolCall().args?.location做空值兜底避免标题空白weather-card.ts。5. 自研聊天抽屉与三栏布局Angular 生态没有 React 版的CopilotSidebar因此 app.ts 手写了一个可折叠聊天面板宽屏≥1200px打开时DOCK.layout--pushed增加右外边距把内容推开窄屏时OVERLAY覆盖内容并提供右下角 FAB 与面板头部关闭按钮面板关闭时通过attr.inert移出 Tab 顺序与读屏树。布局使用var(--cpk-drawer-reserved-width, 320px)让 SDK 的 Threads 抽屉自主决定宽度。这些注释丰富的实现细节是学习如何在 Angular 中复刻 React 版聊天组件行为的绝佳参考。可选Threads 抽屉与 managed IntelligenceThreads 抽屉与持久化会话记忆由CopilotKit Intelligence提供默认关闭——未启用时抽屉渲染的是加锁的 Upgrade 状态。启用方式是在.env中设置CPK_INTELLIGENCE_API_KEYCOPILOTKIT_LICENSE_TOKEN # self-hosted/offline only INTELLIGENCE_API_URLhttp://localhost:4201 INTELLIGENCE_GATEWAY_WS_URLws://localhost:4401 CPK_INTELLIGENCE_API_KEY各变量的语义见 .env.example 与 server.tsCPK_INTELLIGENCE_API_KEY启用 managed Intelligence 的总开关同时作为CopilotKitIntelligence的apiKeyINTELLIGENCE_API_URL/INTELLIGENCE_GATEWAY_WS_URL仅在面向自托管或离线 Intelligence 部署时设置分别映射到apiUrl与wsUrlCOPILOTKIT_LICENSE_TOKEN仅自托管/离线许可使用managed 路径下不需要。启用后server.ts中的条件展开代码会生效...(process.env.CPK_INTELLIGENCE_API_KEY ? { intelligence: new CopilotKitIntelligence({...}), identifyUser: () ({ id: demo-user, name: Demo User }) } : { runner: new InMemoryAgentRunner() })。启用 Intelligence 时有三条必须遵守的注意事项需要 Node.js ≥ 22基础 UI Runtime 在 Node 20 即可server.ts中的identifyUser是一个返回demo-user的演示桩函数。CopilotKit Intelligence 要求被识别的用户真实存在因此线程持久化需要一个真实、已预置的用户 ID——请务必用你实际认证流程得到的身份替换该桩函数copilotkitCLI 在脚手架生成项目时会预置一个。保留demo-user可能导致线程操作失败Runtime 以CPK_INTELLIGENCE_API_KEY作为 managed Intelligence 的选择依据COPILOTKIT_LICENSE_TOKEN只用于自托管/离线许可。故障排查Agent 连接问题如果聊天界面报告无法连接依次检查ADK Agent 是否运行在 8000 端口dev:agent进程是否存活.env中的GOOGLE_API_KEY是否设置正确Runtime 是否监听在 8200 端口——查找日志中的Copilot Runtime listening at ...输出见 server.ts。Python 依赖问题如果 Agent 无法启动重新配置它的运行环境npm run install:agent该命令会重新通过uv在agent/.venv中安装依赖。此外main.py在__main__入口处还内置了缺失GOOGLE_API_KEY时的警告提示与获取指引agent/main.py启动 Agent 时留意终端输出即可。延伸阅读若想对比同一套 ADK 集成在 React 前端下的写法可查看 examples/integrations 目录 下的其他 ADK 示例含 langgraph、llamaindex、mastra 等更多集成若需深入 Copilot Runtime 的 Agent 注册与 Intelligence 装配机制参考 packages/runtime 与 packages/channels-core 的源码与测试Angular 包的公共 API 与变更记录见 packages/angular/README.md 与 packages/angular/CHANGELOG.md本示例基于 MIT 许可开源LICENSE 文件位于 examples/integrations/adk-angular/LICENSE。将本 Starter 中的get_weather替换为你自己的业务工具、把ProverbsState换成真实业务状态即可快速复刻出一套Angular ADK CopilotKit的完整 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),仅供参考