AG-UI 协议:把 AI Agent 接进前端应用的 "最后一公里"

你有没有过这种体验:后端 Agent 已经能干活 —— 能查数据库、能调 API、能跑多步推理,但当你把它” 塞进” 自己的 Web 应用时,尴尬的事情就发生了:

  • 前端写好的表单状态传不进去,Agent 拿到的是残缺的上下文
  • Agent 中途要向用户确认一个参数,只能抛一条文本消息,没有” 确认 / 取消” 按钮
  • 流式输出到一半,前端不知道该把光标放哪里、该不该禁用按钮
  • 想在 Slack 里用同一个 Agent,结果发现协议层只支持 Web

这些问题的根本原因,是 Agent 与用户界面之间,缺一层统一的协议

MCP(Model Context Protocol)解决了”Agent 怎么调用工具”;A2A(Agent-to-Agent)解决了”Agent 之间怎么沟通”;那么”Agent 怎么跟真实用户交互” 呢?

CopilotKit 团队给出的答案是 AG-UI Protocol—— 一个开源、轻量、事件驱动的协议,专门把 Agent 接进前端应用。它已经被 Google ADK、LangGraph、AWS Strands、Microsoft Agent Framework、Mastra、PydanticAI 等 15+ 主流框架原生支持,相当于补齐了智能体协议栈的” 第三块拼图”。

项目背景:从 CopilotKit 到 AG-UI

CopilotKit 是 2023 年起步的一个 React 库,定位是” 前端 Agent SDK”—— 给前端开发者提供 Chat UI、Generative UI、共享状态、人机协同这些能力,做了两年多,到现在已经积累了 36K+ Star。

但在落地过程中,团队很快发现一个问题:Agent 后端和前端之间没有统一协议。每个 Agent 框架(LangGraph、CrewAI、自研 Agent)都有自己的事件格式,前端要么针对每种后端写一套适配,要么只能跑 demo。

于是他们把 CopilotKit 里负责”Agent↔UI” 通信的那一层抽了出来,独立成项目 ag-ui-protocol/ag-ui(14K+ Star),并联合 LangGraph / CrewAI 一同设计协议规范。

AG-UI 的设计目标很明确:

  • 轻量:核心只定义约 16 种标准事件类型,不绑死任何传输方式
  • 可插拔:支持 SSE、WebSocket、Webhook 等任意传输
  • 宽松匹配:事件字段允许命名差异,最大化兼容性
  • 多框架:今天不只有 React,Angular、Vue、React Native、Slack、MS Teams 都在路线图上

它解决的问题,本质上是 Agent 想” 长出手脚” 碰用户时,没有一套通用语言

核心功能亮点

1. 16 种标准事件,覆盖 Agent 全生命周期

AG-UI 把 Agent 执行过程中可能产生的所有交互,抽象成大约 16 种标准事件,包括:

  • RUN_STARTED / RUN_FINISHED / RUN_ERROR:一次 Agent 调用的起止
  • TEXT_MESSAGE_START / TEXT_MESSAGE_CONTENT / TEXT_MESSAGE_END:流式文本
  • TOOL_CALL_START / TOOL_CALL_ARGS / TOOL_CALL_END / TOOL_CALL_RESULT:工具调用全过程
  • STATE_SNAPSHOT / STATE_DELTA:前端↔Agent 共享状态
  • MESSAGES_SNAPSHOT:历史消息快照
  • 以及 HITL(Human-in-the-Loop)相关的事件

后端只需要” 按一种 AG-UI 兼容格式”emit 事件,前端按”AG-UI 兼容输入” 接收参数,中间用什么传输(SSE / WebSocket / Webhook)都可以。

2. 双向状态同步(Shared State)

这是 AG-UI 最实用的能力之一:前端表单、列表、配置项和 Agent 内部状态双向实时同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 前端:声明这块 UI 与 Agent 共享 state
const { state, setState } = useCoAgent({
name: "research_agent",
initialState: { city: "San Francisco" }
});

// Agent 内部更新 state,前端自动重渲染
// 前端点按钮改 city,Agent 下一步也能看到
return (
<div>
<h1>{state.city}</h1>
<button onClick={() => setState({ city: "NYC" })}>
切换城市
</button>
</div>
);

这背后靠的是 STATE_SNAPSHOT(全量)和 STATE_DELTA(增量)事件,加上 JSON Patch 兼容的 patch 格式。前端不用再自己写” 轮询拉状态” 的脏逻辑。

3. 生成式 UI(Generative UI)

Agent 不只能吐文字,还能直接渲染 UI 组件。比如:

  • Agent 决定展示一个航班对比表 → 后端 emit 一个 TOOL_CALL,前端拿到结构化数据后渲染 <FlightTable />
  • Agent 需要用户选一个文件 → emit TOOL_CALL 配合自定义事件,前端弹出文件选择器

CopilotKit 提供了 renderAndWaitForResponse 这种机制:Agent 渲染组件,用户在 UI 上操作,结果作为下一轮输入回传给 Agent。整个过程不需要前端写胶水代码。

4. 人机协同(Human-in-the-Loop)

Agent 执行到某一步,可以主动暂停并请求用户输入

  • “我准备调用 delete_database,确认吗?” → 弹一个确认框
  • “我需要你提供 GitHub Token 才能继续” → 弹一个输入框
  • “请从这 3 个分支里选一个” → 弹一个下拉

HITL 通过专门的事件类型实现,前端可以用任何 UI 库(Material UI、Ant Design、Tailwind UI…)渲染。Agent 不会” 自作主张” 继续往下走,必须等用户响应。

5. 多平台同一份 Agent

这是 CopilotKit 在协议之上的延伸:同一个 Agent 后端,能跑在 Web、React Native、Slack、MS Teams

原理是:Agent 只 emit AG-UI 事件,CopilotKit 在不同平台提供对应的 UI 适配层(React 一个、Slack 一个、Teams 一个)。Agent 业务逻辑只写一遍,部署到哪都行。

6. 协议栈里的” 第三块拼图”

AG-UI 团队自己画的协议栈图:

  • MCP(Anthropic 主导):让 Agent 拿到工具
  • A2A(Google 主导):让 Agent 之间对话
  • AG-UI(CopilotKit 主导):让 Agent 走进用户应用

三块协议各管一摊,互不冲突。AG-UI 的定位是最贴近用户的那一层。

实战示例:5 分钟接入

下面用一个最简的例子演示 AG-UI 的工作流。环境准备:

1
2
3
4
5
6
7
8
9
# 1. 创建一个新应用
npx create-ag-ui-app my-agent-app
cd my-agent-app

# 2. 安装依赖
npm install

# 3. 配置 LLM key
echo "OPENAI_API_KEY=sk-..." > .env

假设我们用一个最简的” 行程规划”Agent,后端用 TypeScript(节选关键部分):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// server/agent.ts —— Agent 后端
import { runAgent } from "@ag-ui/core";

runAgent({
agentId: "trip_planner",
systemPrompt: "你是一个贴心的行程规划助手。用户提到城市时,更新共享 state.city。",
tools: [
{
name: "update_city",
description: "更新当前行程目标城市",
parameters: { city: "string" }
}
],
onStateChange: (state) => {
// 这里 emit STATE_DELTA 事件,前端会自动同步
return { delta: { city: state.city } };
}
});

前端用 CopilotKit(已自动注入 AG-UI 客户端):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// app/page.tsx
"use client";
import { useCoAgent } from "@copilotkit/react-core";

export default function Page() {
const { state, setState } = useCoAgent({
name: "trip_planner",
initialState: { city: "Tokyo" }
});

return (
<main className="p-8">
<h1 className="text-3xl">当前行程目标:{state.city}</h1>
<button
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
onClick={() => setState({ city: "Paris" })}
>
切到巴黎
</button>
</main>
);
}

跑起来:

1
2
3
4
npm run dev
# 浏览器打开 http://localhost:3000
# 在 CopilotKit 的 Chat 面板里说:"我们去京都吧"
# 你会看到页面标题实时变成"当前行程目标:京都"

不需要写 fetch / SSE / WebSocket 代码,不需要手动管理 eventSource,AG-UI 的中间件已经把双向通信打通了。

如果想看更完整的 demo,可以直接跑 AG-UI Dojo—— 官方用 50-200 行的最小例子展示了 9 个核心能力:共享状态、工具型生成式 UI、HITL 等,每一种都可以下载源码对照学习。

与同类项目的差异

项目 定位 与 AG-UI 的关系
MCP Agent ↔ 工具 协议栈上一层,AG-UI 与之正交,可同时使用
A2A Agent ↔ Agent 协议栈上一层,AG-UI 不替代它
OpenAI Assistants API 厂商私有 Agent 协议 闭源、绑死 OpenAI;AG-UI 开放、中立
LangGraph Studio UI LangGraph 专属前端 框架绑定,AG-UI 跨 15+ 框架
Vercel AI SDK Next.js 流式 AI UI 主要是 UI 层封装,AG-UI 还管协议层和 HITL

最关键的差异:AG-UI 是协议层,不是产品。CopilotKit 是协议的参考实现 + React SDK,但协议本身(事件类型、状态 patch 格式)任何人都可以独立实现,跨厂商、跨语言。

适用场景与限制

适合用 AG-UI 的场景:

  • 在自己的 SaaS 产品里嵌入 AI 助手,需要 Agent 与业务表单 / 数据双向同步
  • 同一个 Agent 后端要同时跑在 Web、Slack、Teams 三端
  • 多 Agent 编排后,需要一个统一的前端 UI 层(HITL 审批、状态确认、工具结果渲染)
  • 想用 LangGraph / CrewAI / PydanticAI 等开源 Agent 框架,又想给前端一套不锁死框架的接入方式

当前限制:

  • 框架覆盖虽广,但 Angular / Vue / Slack / Teams 还在 Beta,生产用前要评估稳定性
  • AG-UI 强调” 宽松匹配”,意味着不同实现的兼容程度需要自测,规范不如 MCP/A2A 那么严格
  • 协议本身不解决 Auth / 计费 / 审计,这些还得自己加
  • React Native 客户端还在 Help Wanted 阶段,跨端团队得自己造轮子或者等社区

语言 SDK 现状(截至 2026-07):

  • 1st Party:Python、TypeScript、Kotlin、Go、Dart、Java、Rust、Ruby、C++
  • Community:.NET/ Nim / Flowise / Langflow 等在路上

写在最后

Agent 这两年的发展有一条很清楚的脉络:先把 Agent 本身做好(推理、工具调用、多步规划),再做协议(MCP、A2A),最后做” 长出手脚”。AG-UI 是这最后一公里的早期答案之一。

它现在不像 MCP 那样有 Anthropic 这种大厂背书,但 14K+ 的 Star、15+ 框架原生集成、Google ADK / AWS Strands / Microsoft Agent Framework 这些” 标准制定者” 的 1st Party 支持,说明它已经在事实上成为 Agent↔UI 这层的” 事实协议”。

如果你正在做 AI 产品,建议花一两个小时跑一下 AG-UI Dojo—— 你大概率会和我一样,被 STATE_DELTA + useCoAgent 这种” 声明式共享状态” 的体验爽到。

参考链接: