一、为什么需要 AG-UI:Agent 的"最后一公里"问题
过去两年 Agent 基础设施的标准化集中在两个方向:MCP(Model Context Protocol)解决了 Agent 如何调用工具和获取上下文,A2A(Agent-to-Agent)解决了 Agent 之间如何互相委托任务。但协议栈上始终存在一个空洞:Agent 如何与人交互。
在没有标准之前,每个团队都在重复造轮子:
- 后端用 LangGraph/CrewAI 写好了 Agent,前端只能拿到一个"请求进、完整结果出"的黑盒 API,中间过程(思考、工具调用、状态变化)全部不可见;
- 想做 token 级流式输出,就得自己定义 SSE 事件格式;想做人机协同审批(human-in-the-loop),就得自己设计中断/恢复语义;想让前端实时展示 Agent 内部状态,就得手写一套状态同步;
- 换一个 Agent 框架,以上全部重写。
AG-UI(Agent--User Interaction Protocol)就是针对这一层的开放协议:用一套标准化、类型化的事件流,规约 Agent 后端与用户界面之间的双向实时通信 。它由 CopilotKit 团队于 2025 年 5 月发起,脱胎于 CopilotKit 与 LangGraph、CrewAI 合作的生产实践,随后捐为独立开源协议(GitHub: ag-ui-protocol/ag-ui)。
CopilotKit 并非大厂,而是一家西雅图创业公司,由 Atai Barkai(CEO,曾在 Meta 负责媒体基础设施)与 Uli Barkai 兄弟创立。它先做开源 Agent 前端框架,再把交互层沉淀为协议,走的是"开源产品反推标准"的路线。
一句话定位:MCP 给 Agent 装上了手(工具),A2A 给了 Agent 同事(协作),AG-UI 给了 Agent 一张脸(界面)。
二、在 Agent 协议栈中的位置
| 协议 | 连接对象 | 解决的问题 | 主导方/治理 |
|---|---|---|---|
| MCP | Agent ↔ 工具/数据 | 上下文与工具调用的标准化 | Anthropic 发起,生态最成熟 |
| A2A | Agent ↔ Agent | 跨框架、跨厂商的 Agent 互操作 | Google 发起,已入 Linux Foundation |
| AG-UI | Agent ↔ 用户/前端 | 交互层:流式输出、状态同步、人机协同 | CopilotKit 发起,开源社区驱动 |
| A2UI | Agent → UI 描述 | 生成式 UI 的声明式组件规范 | Google,2026 年开源(v0.9) |
三个核心协议是互补关系而非竞争关系,分别占据 Agent 架构的不同层。一个典型的 2026 年生产级 Agent 应用会同时用到三者:MCP 接数据源,A2A 编排多 Agent,AG-UI 面向用户呈现。
值得单独说明的是 A2UI。它常被误认为 AG-UI 的竞品,实际二者是上下层关系:A2UI 定义"UI 长什么样"(一份可移植的声明式组件树,类似 Agent 界的 JSON Schema for UI),AG-UI 定义"UI 内容如何在 Agent 与客户端之间流动"。实践中 Agent 可以用 A2UI 描述界面意图,再通过 AG-UI 的事件流把它推送到客户端、并把用户的结构化响应带回来。
三、协议设计:架构与核心抽象
3.1 运行模型
AG-UI 采用客户端-服务器架构,交互模型极简:
- 前端向 Agent 端点发送一个 HTTP POST,携带
RunAgentInput; - Agent 在执行过程中持续向客户端流式发射类型化事件 (默认 SSE,即
text/event-stream); - 前端消费事件流,实时更新 UI;用户的下一次输入开启新的 run,形成双向循环。
RunAgentInput 是整个协议的输入契约:
typescript
interface RunAgentInput {
threadId: string // 会话线程 ID,同一会话内所有 run 共享
runId: string // 本次运行 ID,每次触发生成一个新的
messages: Message[] // 完整对话历史(user/assistant/tool 消息)
tools: Tool[] // 前端注册的工具定义(名称 + JSON Schema 参数)
context: Context[] // 附加上下文(如当前页面信息、用户资料)
state: any // 共享状态对象,可携带用户在 UI 上的修改
forwardedProps: any // 自定义透传字段,协议不解释其内容
}
注意 state 字段是双向的:Agent 通过状态事件把状态推给前端,前端把(可能被用户修改过的)状态随下一次 run 传回------这是后文"共享状态"能力的闭环入口。
协议的核心抽象只有一个接口:
typescript
// 运行一个 Agent = 输入 RunAgentInput,返回一个事件可观察流
run(input: RunAgentInput) -> Observable<BaseEvent>
所有事件继承自统一基类:
typescript
interface BaseEvent {
type: EventType // 事件类型(强类型枚举)
timestamp?: number
rawEvent?: any // 保留框架原生事件,便于调试与扩展
}
3.2 事件模型:协议的全部词汇表
AG-UI 的最初规范定义了 16 个标准事件,分五类;随规范演进又补充了推理(thinking/reasoning)、活动(activity)等扩展事件。这套事件覆盖了 Agent 生命周期中"值得让用户看到的一切":
| 类别 | 事件 | 语义 |
|---|---|---|
| 生命周期 | RUN_STARTED / RUN_FINISHED / RUN_ERROR |
一次运行的起止与失败 |
STEP_STARTED / STEP_FINISHED |
内部步骤/节点粒度的进度 | |
| 文本消息 | TEXT_MESSAGE_START → TEXT_MESSAGE_CONTENT(×N) → TEXT_MESSAGE_END |
token 级流式文本,三段式包裹 |
| 工具调用 | TOOL_CALL_START → TOOL_CALL_ARGS(×N) → TOOL_CALL_END,以及 TOOL_CALL_RESULT |
工具调用的参数流与结果回传 |
| 状态管理 | STATE_SNAPSHOT / STATE_DELTA / MESSAGES_SNAPSHOT |
全量快照 / 增量补丁 / 对话历史快照 |
| 特殊 | RAW / CUSTOM |
透传原生事件 / 应用自定义扩展 |
| 扩展:推理 | THINKING_* 系列 |
向前端暴露模型的思考过程 |
| 扩展:活动 | ACTIVITY_SNAPSHOT / ACTIVITY_DELTA |
仅前端消费的结构化 UI(进度条、检索状态等),不回传给 LLM |
其中几组事件的设计意图值得展开。
状态管理三事件:锚点 + 增量。 Agent 内部通常维护一个结构化工作状态(一份研究大纲、一个旅行计划对象),前端需要实时渲染它,而逐 token 的文本事件表达不了结构化数据。协议的方案是:run 开始时用 STATE_SNAPSHOT 发一次全量建立基线,之后全部走 STATE_DELTA------内容是 JSON Patch 操作数组(RFC 6902),前端逐条 apply 即可保持同步。大状态对象每步只耗几十字节带宽;快照则永远是可信的重同步锚点,patch 应用出错或断线重连时重新拉一次即可恢复。MESSAGES_SNAPSHOT 单独存在,是因为消息历史与业务状态生命周期不同------当后端改写了对话历史(插入工具结果、HITL 修正后重放),用它把前端消息列表整体对齐。
ACTIVITY 事件:只给人看、不进模型上下文。 进度条、"正在检索第 12/40 个网页"、步骤清单这类瞬态展示信息,与 STATE 事件的本质区别在数据归属:state 是 Agent 的工作记忆,会随 RunAgentInput 回传、进入 LLM 上下文参与推理;activity 是纯展示层数据,不回传、不占用上下文窗口。协议未区分二者时,开发者只能滥用 STATE_DELTA 或 CUSTOM 推送进度信息,让展示噪声污染共享状态。ACTIVITY 事件在协议层完成了分离,机制同样是 snapshot 全量 + delta 增量。
三段式流(START/CONTENT/END)而非单事件。 文本和工具参数都拆成开始、增量、结束三种事件。这使前端可以在 START 时就创建 UI 占位(消息气泡、工具卡片),随 CONTENT 渐进填充,END 时落定------流式体验由协议结构保证,而非前端 hack。
3.3 传输无关 + 中间件层:低采纳成本的关键
AG-UI 刻意做得"轻",两条设计原则决定了它的扩散速度:
- 传输无关(transport agnostic):协议只规定事件的类型与语义,不绑定传输方式。SSE 是默认选择(文本、可调试、兼容性好),也支持 WebSocket、webhook,以及官方提供的高性能二进制序列化通道(protobuf)用于生产环境。
- 中间件层(middleware layer):事件不必与 AG-UI 格式完全一致,只需"AG-UI 兼容"。各框架通过适配器把原生事件(LangGraph 的 graph event、CrewAI 的 task output 等)翻译为 AG-UI 事件即可接入,无需改造框架内核。这是它能在发布数周内被十余个框架集成的直接原因。
四、AG-UI 解锁的五类交互能力
协议本身只是事件词汇表,但组合起来支撑了 Agent 原生应用的五种核心交互范式:
- 代理式聊天(Agentic Chat):token 级流式输出 + 工具调用过程可视化。用户看到的不再是转圈的 loading,而是 Agent 正在做什么。
- 生成式 UI(Generative UI):工具调用事件携带结构化参数,前端据此渲染专属组件(表单、图表、卡片)而非纯文本。配合 A2UI 可进一步做到声明式界面生成。
- 共享状态(Shared State):Agent 与前端读写同一份状态对象,双向同步。典型场景:Agent 生成旅行计划,用户直接在 UI 上拖拽修改,Agent 感知修改并继续推理。
- 人机协同(Human-in-the-Loop):Agent 在关键节点中断、等待用户审批/修正后继续。审批流由标准事件承载,不再依赖框架私有机制。
- 前端工具(Frontend Tools) :
RunAgentInput.tools允许前端向 Agent 注册"运行在浏览器里的工具"------Agent 可以反过来调用前端能力(操作页面、读取本地上下文),代理与界面的边界被打通。
五、生态与现状(2026 年中)
AG-UI 发布约 14 个月,已从"CopilotKit 的配套协议"演化为交互层的事实标准候选:
框架侧集成 (官方仓库列为 supported):LangGraph、CrewAI、Mastra、Pydantic AI、Agno、LlamaIndex、AG2、Microsoft Agent Framework、Google ADK、AWS Strands Agents 等。其中 Pydantic AI 做到了原生支持(agent.to_ag_ui() 一行导出 ASGI 应用),Microsoft Learn 上有 Agent Framework 的官方 AG-UI 集成文档。
云厂商侧:AWS Bedrock AgentCore Runtime 于 2026 年 3 月加入 AG-UI 支持,与 MCP、A2A 工作负载同等对待(托管、鉴权、扩缩容)。这是协议进入企业级 runtime 的标志性节点。
SDK :官方维护 TypeScript(@ag-ui/core、@ag-ui/client)与 Python(ag-ui-protocol)SDK;社区贡献了 Go、Kotlin、.NET 等实现。
客户端侧 :CopilotKit 仍是最完整的参考实现(React 组件族),另有 agui-hooks 等社区轻量库。官方的 AG-UI Dojo 提供了各能力的可运行示例(building blocks)。
协议背后的公司:CopilotKit 于 2026 年 5 月完成 2050 万美元 A 轮(累计融资 2700 万美元,Glilot Capital 领投,NFX、SignalFire 跟投),融资叙事正是 AG-UI 被 Google、Microsoft、Amazon 的 Agent 产品线采纳------小团队定义标准、大厂接入的少见案例。
竞争与变数:Google 的 A2UI 在 2026 年 7 月发布 v0.9 并全面开源,虽定位互补,但 Google 显然想把"UI 描述层"的标准握在手里;MCP Apps、Vercel json-renderer 等也在生成式 UI 方向发力。交互层的标准之争没有终局,但 AG-UI 目前在"传输/交互协议"这个细分位置上没有对等竞品。
客观短板:相较 MCP 的治理成熟度(以及 A2A 进入 Linux Foundation),AG-UI 仍由 CopilotKit 主导治理,中立性弱一档;规范仍在快速演进(事件类型持续增补),版本间存在迁移成本;此外协议只管交互语义,鉴权、多租户、会话持久化等生产问题需自行解决或依赖 runtime。
六、落地指南
路径 A:已有框架,挂载集成(推荐)
若使用 LangGraph、CrewAI、Pydantic AI 等已集成框架,落地成本约等于"加一个端点"。以 Pydantic AI 为例:
python
from pydantic_ai import Agent
agent = Agent("openai:gpt-5", instructions="Be helpful.")
app = agent.to_ag_ui() # 直接得到一个 ASGI 应用(AG-UI 端点)
# uvicorn main:app
LangGraph 则通过 ag-ui-langgraph 包(PyPI)把 graph 包装为 FastAPI 端点,事件自动翻译。
路径 B:自研 Agent,直接实现协议
裸协议实现同样简单------本质上就是一个"POST 进、SSE 出"的端点。官方 Python SDK 示例:
python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from ag_ui.core import (
RunAgentInput, EventType,
RunStartedEvent, RunFinishedEvent,
TextMessageStartEvent, TextMessageContentEvent, TextMessageEndEvent,
)
from ag_ui.encoder import EventEncoder
import uuid
app = FastAPI()
@app.post("/awp")
async def agent_endpoint(input_data: RunAgentInput):
async def stream():
enc = EventEncoder()
yield enc.encode(RunStartedEvent(
type=EventType.RUN_STARTED,
thread_id=input_data.thread_id, run_id=input_data.run_id))
msg_id = str(uuid.uuid4())
yield enc.encode(TextMessageStartEvent(
type=EventType.TEXT_MESSAGE_START, message_id=msg_id, role="assistant"))
# 实际场景:在此处对接 LLM 流式输出,逐 chunk 发 CONTENT 事件
yield enc.encode(TextMessageContentEvent(
type=EventType.TEXT_MESSAGE_CONTENT, message_id=msg_id, delta="Hello, AG-UI!"))
yield enc.encode(TextMessageEndEvent(
type=EventType.TEXT_MESSAGE_END, message_id=msg_id))
yield enc.encode(RunFinishedEvent(
type=EventType.RUN_FINISHED,
thread_id=input_data.thread_id, run_id=input_data.run_id))
return StreamingResponse(stream(), media_type="text/event-stream")
前端接入
最薄的一层是官方 HttpAgent 客户端,直接订阅事件流:
typescript
import { HttpAgent, EventType } from "@ag-ui/client";
const agent = new HttpAgent({ url: "http://localhost:8000/awp" });
agent.runAgent({ tools: [], context: [] }).subscribe({
next: (event) => {
switch (event.type) {
case EventType.TEXT_MESSAGE_CONTENT:
appendToUI(event.delta); break;
case EventType.STATE_DELTA:
applyJsonPatch(state, event.delta); break;
case EventType.TOOL_CALL_START:
renderToolCard(event); break;
}
},
});
需要开箱即用的完整体验(聊天组件、共享状态 hooks、HITL 组件)则直接上 CopilotKit:后端指向 AG-UI 端点,前端用 <CopilotChat/>、useCoAgent() 等即可。
生产化清单
- 鉴权与隔离:协议不含鉴权语义,标准做法是在前端与 Agent 之间加一层 secure proxy(架构图中的官方推荐位),或托管到 Bedrock AgentCore 这类 runtime;
- 状态与持久化 :
threadId只是标识,会话存储、断线重连后的MESSAGES_SNAPSHOT/STATE_SNAPSHOT补发需自行实现; - 事件顺序校验:SDK 内置 verifier,保证 START/CONTENT/END 配对合法,自研发射器务必启用;
- 性能 :高频状态更新用
STATE_DELTA而非快照;吞吐敏感场景可切换官方二进制传输。
七、怎么评价 AG-UI
最后给出三个判断,代替布道式的总结。
AG-UI 赌对了抽象层级。 它不定义 UI 长什么样,只定义事件语义,框架适配成本因此极低------这是它能在一年内拿下主流框架集成的根因。
它当前最大的护城河是"没有对手",最大的风险是"治理归属"。 MCP、A2A 已先后进入中立治理,而 AG-UI 仍由一家创业公司主导。若 Linux Foundation 系(A2A/MCP 阵营)或 Google(A2UI/ADK 阵营)推出交互层官方方案,格局可能重排。
对工程团队而言,采用它是低风险决策。 交互层代码本就要写,与其自定义 SSE 事件格式,不如直接采用 AG-UI 的事件词汇表。即使协议将来演进甚至被替代,"类型化事件流 + JSON Patch 状态同步"这套模式也不会过时,迁移成本可控。
参考资料
- 官方文档:https://docs.ag-ui.com (架构:/concepts/architecture,事件:/concepts/events)
- 官方仓库:https://github.com/ag-ui-protocol/ag-ui
- 发布公告:https://www.copilotkit.ai/blog/introducing-ag-ui-the-agent-user-interaction-protocol
- 事件详解:https://www.copilotkit.ai/blog/master-the-17-ag-ui-event-types-for-building-agents-the-right-way
- 协议栈对比(DZone):https://dzone.com/articles/mcp-vs-a2a-vs-agui
- Microsoft Agent Framework 集成:https://learn.microsoft.com/en-us/agent-framework/integrations/ag-ui/
- Pydantic AI 集成:https://ai.pydantic.dev/ui/ag-ui/
- A2UI v0.9(InfoQ, 2026-07):https://www.infoq.com/news/2026/07/google-a2ui-genui/
- AWS 视角实践:https://builder.aws.com/content/3Bi9i40bG41aMJD8mDW6W0EBHLe/ag-ui-a-practical-look-at-the-agent-to-user-protocol
- CopilotKit 融资报道(TechCrunch, 2026-05):https://techcrunch.com/2026/05/05/copilotkit-raises-27m-to-help-devs-deploy-app-native-ai-agents/