AG-UI 项目理解:协议、生成式 UI、A2UI 与 CopilotKit
本文基于本地仓库 /Users/sunven/opensource/ag-ui 的源码梳理。核心问题是:
- AG-UI 是什么?
- 这个项目里的生成式 UI 是怎么实现的?
- 是否使用 Google A2UI?
- CopilotKit 在这个项目里起什么作用?
结论先行:
AG-UI 不是生成式 UI 规范,而是 Agent 与用户界面之间的事件协议。
项目里的生成式 UI 有多条实现路径:部分新示例使用 A2UI;旧的
tool_based_generative_ui和agentic_generative_ui不是 A2UI,而是 CopilotKit frontend tool / agent state 驱动。CopilotKit 在这里是非常核心的 React 前端和 Runtime 桥接层:负责聊天 UI、前端工具、状态订阅、A2UI renderer,以及把前端请求接到 AG-UI agent adapter。
1. AG-UI 是什么
AG-UI 全称是 Agent-User Interaction Protocol。
它解决的问题不是“Agent 如何调用工具”,也不是“Agent 如何彼此通信”,而是:
Agent 后端和用户界面之间,如何用统一事件流传递消息、状态、工具调用、UI 渲染和用户交互。
可以把它放在三个协议层中理解:
| 层级 | 代表协议 | 解决问题 |
|---|---|---|
| Agent ↔ User | AG-UI | Agent 和前端用户界面的双向交互 |
| Agent ↔ Tools/Data | MCP | Agent 访问工具、数据、外部系统 |
| Agent ↔ Agent | A2A | 多 Agent 协作和任务传递 |
AG-UI 的核心抽象是 事件流。Agent 不直接“渲染 React”,而是输出标准事件,例如:
- run 开始 / 结束
- message 开始 / delta / 结束
- tool call 开始 / 参数流 / 结束 / 结果
- state snapshot / state delta
- activity snapshot / activity delta
前端收到这些事件后,再决定如何展示聊天、工具调用、状态变化或生成式 UI。
简化数据流:
用户输入
-> 前端应用
-> AG-UI Runtime endpoint
-> Agent adapter
-> LangGraph / Mastra / ADK / CrewAI / LlamaIndex 等后端
-> AG-UI event stream
-> 前端根据事件渲染 UI
2. 这个仓库的整体结构
ag-ui 是一个 monorepo,包含:
- 协议核心类型和客户端
- 多语言 SDK
- 多个 Agent 框架集成
- 中间件
- Dojo 示例应用
- 文档
本次关注的关键路径:
| 路径 | 作用 |
|---|---|
apps/dojo | React / Next.js 示例应用,展示各种 AG-UI 能力 |
apps/dojo/src/app/api/copilotkit/... | CopilotKit Runtime endpoint,把前端接到 AG-UI agents |
apps/dojo/src/agents.ts | 不同 integration 到 agent adapter 的映射 |
middlewares/a2ui-middleware | A2UI 到 AG-UI activity event 的转换中间件 |
integrations/langgraph/python/examples/agents | LangGraph Python 示例 agents |
integrations/* | Mastra、ADK、CrewAI、LlamaIndex、LangGraph 等集成 |
docs | 协议和概念文档 |
3. 生成式 UI 不是只有一种实现
这个项目里“生成式 UI”至少有三条路径。
路径一:Tool-based Generative UI
对应 feature:
tool_based_generative_ui
这不是 A2UI。
它的核心是 前端注册工具,Agent 调用工具,前端根据工具参数渲染 React UI。
前端页面里使用 CopilotKit 的 useFrontendTool:
useFrontendTool({
agentId: "tool_based_generative_ui",
name: "generate_haiku",
parameters: z.object({
japanese: z.array(z.string()),
english: z.array(z.string()),
image_name: z.string(),
gradient: z.string(),
}),
handler: async (args) => {
// 更新本地 React state
return "Haiku generated!";
},
render: ({ args }) => {
return <HaikuCard haiku={args as Haiku} />;
},
});
数据流:
用户:"写一首俳句"
-> CopilotKit Chat
-> CopilotRuntime
-> Agent
-> Agent 决定调用 generate_haiku
-> AG-UI tool call events
-> 前端 useFrontendTool 收到参数
-> handler 更新 React state
-> render 渲染 HaikuCard
这种模式的特点:
- UI 组件由开发者预先写好
- Agent 只能选择工具并填参数
- 安全性高,可控性强
- 适合业务 UI、审批卡片、搜索结果、表单等
路径二:Agentic Generative UI
对应 feature:
agentic_generative_ui
这也不是 A2UI。
它的核心是 Agent 更新共享状态,前端订阅 agent state 并渲染 UI。
前端使用 CopilotKit 的 useAgent:
const { agent } = useAgent({
agentId: "agentic_generative_ui",
updates: [UseAgentUpdate.OnStateChanged],
});
const steps = agent.state?.steps;
Agent 侧会生成任务步骤,并逐步更新状态:
steps: [
{ description: "...", status: "pending" },
{ description: "...", status: "completed" }
]
前端根据 steps 渲染进度条和任务列表。
数据流:
用户:"给我制定一个任务计划"
-> CopilotKit Chat
-> Agent
-> Agent 生成 steps
-> AG-UI state snapshot / delta
-> 前端 useAgent 收到状态变化
-> React 渲染 TaskProgress
这种模式的特点:
- UI 不是由 Agent 直接声明组件树
- Agent 只维护结构化业务状态
- 前端完全控制视觉呈现
- 适合任务进度、工作流、仪表盘状态、协作状态
路径三:A2UI Declarative Generative UI
对应 features:
a2ui_fixed_schema
a2ui_dynamic_schema
a2ui_advanced
这部分才是 A2UI。
A2UI 是一种生成式 UI specification。它让 Agent 输出声明式 UI operations,例如:
- create surface
- update components
- update data model
- delete surface
前端根据 catalog 把这些声明式组件渲染成真实 UI。
简化数据流:
用户输入
-> CopilotKit React UI
-> /api/copilotkit/[integrationId]
-> CopilotRuntime
-> AG-UI LangGraph agent
-> agent 生成 a2ui_operations
-> A2UIMiddleware 识别 A2UI operations
-> 转成 AG-UI ACTIVITY_SNAPSHOT
-> CopilotKit A2UI renderer
-> React catalog components
固定 schema 示例:
return a2ui.render(
operations=[
a2ui.create_surface(FLIGHT_SURFACE_ID, catalog_id=CUSTOM_CATALOG_ID),
a2ui.update_components(FLIGHT_SURFACE_ID, FLIGHT_SCHEMA),
a2ui.update_data_model(FLIGHT_SURFACE_ID, {"flights": flights}),
]
)
动态 schema 示例:
ops = [
a2ui.create_surface(surface_id, catalog_id=catalog_id),
a2ui.update_components(surface_id, components),
]
if data:
ops.append(a2ui.update_data_model(surface_id, data))
result = a2ui.render(operations=ops)
前端页面通过 CopilotKit 传入 A2UI catalog:
<CopilotKit
runtimeUrl={`/api/copilotkit/${integrationId}`}
agent="a2ui_dynamic_schema"
a2ui={{ catalog: dynamicSchemaCatalog }}
>
<CopilotChat agentId="a2ui_dynamic_schema" />
</CopilotKit>
这种模式的特点:
- Agent 输出声明式 UI 数据
- 前端通过 catalog 控制可用组件
- 比 tool-based UI 更灵活
- 比生成 HTML/JS 更安全
- 适合动态卡片、比较表、搜索结果、表单、dashboard surface
4. A2UI 与 AG-UI 的关系
AG-UI 和 A2UI 名字接近,但不是一类东西。
| 名称 | 类型 | 作用 |
|---|---|---|
| AG-UI | Agent ↔ User 交互协议 | 传输消息、状态、工具调用、activity |
| A2UI | 生成式 UI specification | 描述 UI surface、组件树和数据模型 |
可以这样理解:
A2UI 负责描述 "要渲染什么 UI"
AG-UI 负责传输 "这个 UI 描述如何从 agent 到前端"
CopilotKit 负责在 React 应用里 "接收并渲染"
在这个项目里,A2UI 并不是替代 AG-UI,而是跑在 AG-UI 的 activity event 之上。
A2UI middleware 做的事情是:
- 给 agent 注入 A2UI component schema context
- 可选注入
render_a2uitool - 监听 tool call / tool result 里的 A2UI JSON
- 解析
a2ui_operations - 按 surfaceId 聚合 operations
- 转成 AG-UI
ACTIVITY_SNAPSHOT - 前端 A2UI renderer 根据 activity 渲染 surface
关键事件形态:
a2ui_operations
-> A2UIMiddleware
-> EventType.ACTIVITY_SNAPSHOT
-> activityType: "a2ui-surface"
所以,“这个项目里的生成式 UI 是不是用 Google A2UI 实现的?”准确答案是:
部分是。
a2ui_fixed_schema、a2ui_dynamic_schema、a2ui_advanced这几条路径使用 A2UI。但
tool_based_generative_ui和agentic_generative_ui不是 A2UI,它们是 CopilotKit frontend tool 和 agent state 驱动的生成式 UI。
另外,项目文档里把 A2UI 归为 Google 的 generative UI spec;但 middleware 源码注释中也出现过 anthropics/A2UI 的来源链接。因此更稳妥的说法是:
这个项目支持并集成 A2UI 作为生成式 UI specification;在具体实现中,它通过
@ag-ui/a2ui-middleware和@copilotkit/a2ui-renderer接入 AG-UI/CopilotKit 链路。
5. CopilotKit 在这里的作用
CopilotKit 也是开源项目。这个仓库不只是“提到” CopilotKit,而是大量使用了 CopilotKit。
Dojo app 的依赖包括:
{
"@copilotkit/a2ui-renderer": "1.55.1",
"@copilotkit/react-core": "1.55.1",
"@copilotkit/react-ui": "1.55.1",
"@copilotkit/runtime": "1.55.1",
"@copilotkit/runtime-client-gql": "1.55.1",
"@copilotkit/shared": "1.55.1"
}
CopilotKit 在这里主要有三层作用。
5.1 前端 Provider 和聊天 UI
每个 Dojo feature 页面基本都包在 CopilotKit 里:
<CopilotKit
runtimeUrl={`/api/copilotkit/${integrationId}`}
showDevConsole={false}
agent="agentic_chat"
>
<CopilotChat agentId="agentic_chat" />
</CopilotKit>
它提供:
CopilotKitProviderCopilotChatCopilotSidebaruseFrontendTooluseAgentuseConfigureSuggestionsuseCopilotKit- A2UI renderer 接入
换句话说,CopilotKit 是这个 demo app 的主要 React agent UI 框架。
5.2 Runtime endpoint
Next.js API route 中创建 CopilotRuntime:
const runtime = new CopilotRuntime({
agents: agents as Record<string, AbstractAgent>,
runner: new InMemoryAgentRunner(),
a2ui: {
agents: ["a2ui_fixed_schema", "a2ui_dynamic_schema", "a2ui_advanced"],
},
});
然后创建 endpoint:
const app = createCopilotEndpointSingleRoute({
runtime,
basePath: `/api/copilotkit/${integrationId}`,
});
这一层负责把前端请求接到具体 AG-UI agent:
CopilotKit React
-> /api/copilotkit/[integrationId]
-> CopilotRuntime
-> agentsIntegrations[integrationId]
-> AG-UI agent adapter
5.3 Agent adapter 的统一入口
apps/dojo/src/agents.ts 把不同后端统一成 AG-UI agents:
LangGraphAgentLangGraphHttpAgentMastraAgentADKAgentCrewAIAgentLlamaIndexAgentAgnoAgentSpringAiAgentWatsonxAgentA2AAgentHttpAgent
CopilotRuntime 不直接关心后端是哪种框架,只要它们实现 AG-UI agent 接口即可。
6. 三者的关系图
可以用一张图概括:
React App / Dojo
|
| CopilotKit Provider, Chat, Sidebar, hooks
v
CopilotKit Runtime endpoint
|
| AG-UI event stream
v
AG-UI Agent Adapter
|
+-- LangGraph
+-- Mastra
+-- ADK
+-- CrewAI
+-- LlamaIndex
+-- A2A
+-- custom HTTP agent
|
v
Agent / LLM
如果是 A2UI:
Agent 生成 A2UI operations
-> A2UIMiddleware
-> AG-UI ACTIVITY_SNAPSHOT(activityType="a2ui-surface")
-> CopilotKit A2UI renderer
-> React catalog components
如果是 tool-based generative UI:
Agent 调用 frontend tool
-> AG-UI TOOL_CALL_* events
-> CopilotKit useFrontendTool
-> React render(args)
如果是 agentic state UI:
Agent 更新 state
-> AG-UI state snapshot / delta
-> CopilotKit useAgent
-> React 根据 state 渲染
7. 关键判断
AG-UI 是不是 CopilotKit?
不是。
AG-UI 是协议;CopilotKit 是使用这个协议构建 agent UI 的框架和 runtime。
在这个仓库里,CopilotKit 是 AG-UI 的重要参考实现和 demo 承载层。
AG-UI 是不是 A2UI?
不是。
AG-UI 负责连接 Agent 和前端;A2UI 负责声明式生成 UI surface。
AG-UI 可以承载 A2UI,也可以承载 MCP-UI、Open JSON UI、frontend tools、自定义 activity。
这个项目里的生成式 UI 是不是都靠 A2UI?
不是。
| 示例 | 是否 A2UI | 实现方式 |
|---|---|---|
tool_based_generative_ui | 否 | CopilotKit useFrontendTool |
agentic_generative_ui | 否 | CopilotKit useAgent + AG-UI state |
a2ui_fixed_schema | 是 | 固定 components schema + A2UI operations |
a2ui_dynamic_schema | 是 | LLM 生成 components + A2UI operations |
a2ui_advanced | 是 | A2UI + 自定义 progress renderer / action handler |
CopilotKit 在这里可替换吗?
理论上可以,因为 AG-UI 是协议。
但在这个 Dojo app 中,CopilotKit 承担了很多现成能力:
- 聊天 UI
- sidebar UI
- frontend tools
- agent state hooks
- suggestions
- runtime endpoint
- A2UI renderer
- v1/v2 API 兼容 demo
如果不用 CopilotKit,就需要自己实现这些前端和 runtime 层能力。
8. 最终理解
这个项目可以看成三个层次叠在一起:
最底层:AG-UI Protocol
定义 Agent 与 UI 如何通过事件流通信
中间层:Agent integrations / middleware
把 LangGraph、Mastra、ADK、CrewAI、A2A、A2UI 等接入 AG-UI
最上层:CopilotKit + Dojo
用 React 组件、hooks、Runtime endpoint 展示协议能力
因此,AG-UI 项目的重点不是“提供一个生成式 UI 组件库”,而是:
提供一个统一交互协议,让不同 Agent 后端、不同 UI 生成方式、不同前端渲染策略可以接在一起。
A2UI 是其中一种声明式生成 UI 的方式。
CopilotKit 是这个仓库里最重要的前端和 runtime 集成方式。
Tool-based UI、agent state UI、A2UI surface 都可以通过 AG-UI 事件流进入前端。