AG-UI 协议深度解析:连接 AI Agent 与用户界面的标准化桥梁

本文基于 AG-UI 官方 GitHub 源码库和官方文档,深入解析这一新兴的代理-用户交互协议。

前言

AI Agent 技术发展很快,但有个问题一直没有很好的解决方案:代理和用户界面之间怎么通信?

传统的 HTTP 请求/响应模式明显不够用——代理运行时间长,中间过程不透明,用户只能干等。AG-UI 协议就是为了解决这个问题。


一、什么是 AG-UI 协议?

1.1 官方定义

AG-UI is an open, lightweight, event-based protocol that standardizes how AI agents connect to user-facing applications.

简单说,AG-UI 是一个开放的、轻量级的、基于事件的协议,定义了 AI 代理和前端应用之间的通信标准。

1.2 在代理协议栈中的位置

目前代理领域有三个主要协议,各司其职:

协议 全称 作用
MCP Model Context Protocol 给代理提供工具能力
A2A Agent-to-Agent Protocol 代理之间的通信
AG-UI Agent-User Interaction Protocol 代理和用户界面的通信

三者的关系可以这样理解:

                      用户界面应用
                   (Web App, Mobile App)
                          |
                          | AG-UI 协议
                          v
                      AI Agent 层
               (LangGraph, CrewAI, Mastra...)
                    /           \
           MCP 协议              A2A 协议
                  /                   \
              工具层                  其他代理
           (APIs, DBs)

1.3 AG-UI 解决了什么问题?

代理应用有几个特点,传统请求/响应模式处理不好:

问题一:运行时间长

代理执行一个任务可能需要几秒到几分钟。传统模式下用户只能等,什么反馈都没有。AG-UI 用流式事件推送,代理做到哪儿,前端就能显示到哪儿。

问题二:行为不确定

代理可能会调用工具、执行子任务,这些行为事先不知道。AG-UI 用事件驱动模型,代理做了什么都能实时通知前端。

问题三:输入输出复杂

既有文本消息,又有工具调用,还有状态更新。AG-UI 用统一的事件模型把这些都覆盖了。


二、核心架构

2.1 设计原则

AG-UI 的设计很务实:

  1. 代理只需要发射标准事件,大概 16 种类型
  2. 支持双向交互,用户可以输入、中断、提供反馈

中间件层做了两件事来保证兼容性:

  • 事件格式要求宽松,只要 AG-UI 兼容就行,不用完全一致
  • 传输方式不限制,SSE、WebSocket、Webhooks 都可以

2.2 整体架构

+----------------------------------------------------------+
|                       Frontend                            |
|  +------------------+    +-----------------------------+  |
|  |   Application    |<-->|      AG-UI Client           |  |
|  |   (React/Vue)    |    |  (HttpAgent/AbstractAgent)  |  |
|  +------------------+    +--------------+--------------+  |
+------------------------------------------+----------------+
                                           |
                            AG-UI Protocol | (HTTP + SSE/Protobuf)
                                           |
+------------------------------------------+----------------+
|                       Backend            |                |
|  +---------------------------------------v--------------+ |
|  |              AI Agent (Server)                       | |
|  |  (LangGraph / CrewAI / Google ADK / Mastra ...)      | |
|  +------------------------------------------------------+ |
+-----------------------------------------------------------+

2.3 传输层

AG-UI 不绑定具体的传输方式,这是它的一个特点。

参考实现里支持两种格式:

格式 Content-Type 特点
SSE (JSON) text/event-stream 文本格式,方便调试
Protocol Buffer application/x-ag-ui-proto 二进制格式,性能更好

三、事件类型

AG-UI 定义了 20 多种事件类型,按功能分成几类。

3.1 生命周期事件

跟踪代理运行的状态:

RUN_STARTED    // 代理开始运行
RUN_FINISHED   // 运行成功结束
RUN_ERROR      // 运行出错
STEP_STARTED   // 步骤开始(可选)
STEP_FINISHED  // 步骤结束(可选)

典型的事件序列:

RUN_STARTED -> [STEP_STARTED -> STEP_FINISHED]* -> RUN_FINISHED | RUN_ERROR

3.2 文本消息事件

用流式传输实现打字机效果:

TEXT_MESSAGE_START   // 消息开始
TEXT_MESSAGE_CONTENT // 内容块,增量发送
TEXT_MESSAGE_END     // 消息结束

实际的事件流长这样:

{"type": "TEXT_MESSAGE_START", "messageId": "msg_1", "role": "assistant"}

{"type": "TEXT_MESSAGE_CONTENT", "messageId": "msg_1", "delta": "Hello"}
{"type": "TEXT_MESSAGE_CONTENT", "messageId": "msg_1", "delta": ", "}
{"type": "TEXT_MESSAGE_CONTENT", "messageId": "msg_1", "delta": "world!"}

{"type": "TEXT_MESSAGE_END", "messageId": "msg_1"}

前端把 delta 拼起来就是完整消息:Hello, world!

3.3 工具调用事件

代理调用工具时发送:

TOOL_CALL_START  // 开始调用工具
TOOL_CALL_ARGS   // 参数(流式发送)
TOOL_CALL_END    // 调用定义完成
TOOL_CALL_RESULT // 工具返回结果

3.4 状态管理事件

用快照 + 增量更新的方式同步状态:

STATE_SNAPSHOT     // 完整状态快照
STATE_DELTA        // 增量更新,用 JSON Patch
MESSAGES_SNAPSHOT  // 消息历史快照

增量更新采用 JSON Patch (RFC 6902):

{
  "type": "STATE_DELTA",
  "delta": [
    { "op": "replace", "path": "/status", "value": "processing" },
    { "op": "add", "path": "/results/-", "value": {"id": 1, "text": "..."} }
  ]
}

3.5 特殊事件

RAW    // 透传外部系统的事件
CUSTOM // 自定义事件

3.6 事件模式总结

模式 描述 场景
Start-Content-End 开始 -> 内容块 x N -> 结束 文本消息、工具调用
Snapshot-Delta 完整快照 + 增量更新 状态同步
Lifecycle 开始 -> 结束/错误 运行监控

四、AG-UI 与 SSE、HTTP Streamable 的关系

这三个概念容易混淆,这里说清楚。

4.1 概念层级

+----------------------------------------------------------+
|                   AG-UI 协议                              |
|    (应用层:事件类型、消息语义、状态同步规范)                 |
+----------------------------------------------------------+
                          |
                          | 使用
                          v
+------------------+------------------+--------------------+
|       SSE        |    WebSocket     |    Webhooks        |
|    (传输机制)     |    (传输机制)    |    (传输机制)       |
+------------------+------------------+--------------------+
                          |
                          | 基于
                          v
+----------------------------------------------------------+
|                HTTP Streamable                            |
|              (HTTP 的流式响应能力)                          |
+----------------------------------------------------------+

关键点:AG-UI 是应用层协议,SSE 和 HTTP Streamable 是传输层技术

4.2 对比

特性 AG-UI SSE HTTP Streamable
层级 应用协议层 传输层 传输层
本质 规范、契约 W3C 标准传输技术 HTTP 流式传输能力
定义内容 事件类型、消息格式、语义 数据推送格式 分块传输编码
数据格式 JSON 事件对象 data: xxx\n\n 文本或二进制
关系 使用 SSE/HTTP 作为传输 被 AG-UI 使用 底层能力

4.3 SSE 在 AG-UI 中怎么用的

从源码看,HttpAgent 的请求头是这样的:

{
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Accept": "text/event-stream",  // 请求 SSE 流
  },
  body: JSON.stringify(input),
}

服务端返回的 SSE 格式:

data: {"type":"RUN_STARTED","threadId":"t1","runId":"r1"}

data: {"type":"TEXT_MESSAGE_START","messageId":"msg_1","role":"assistant"}

data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_1","delta":"Hello"}

data: {"type":"TEXT_MESSAGE_END","messageId":"msg_1"}

data: {"type":"RUN_FINISHED","threadId":"t1","runId":"r1"}

客户端 SSE 解析的核心逻辑(简化版):

function parseSSEStream(source) {
  let buffer = "";
  
  source.subscribe({
    next: (chunk) => {
      buffer += chunk;
      // 事件用双换行符分隔
      const events = buffer.split("\n\n");
      buffer = events.pop(); // 保留不完整的部分
      
      for (const event of events) {
        // 提取 data: 行,解析 JSON
        const dataLines = event
          .split("\n")
          .filter(line => line.startsWith("data:"))
          .map(line => line.slice(5).trim());
        
        const json = JSON.parse(dataLines.join(""));
        emit(json);
      }
    }
  });
}

4.4 小结

AG-UI 和 SSE 不是一回事。AG-UI 定义了通信的内容(事件类型、语义),SSE 只是传输手段之一。你也可以用 WebSocket 或者其他方式传输 AG-UI 事件。


五、代码示例

5.1 创建项目

npx create-ag-ui-app my-agent-app

5.2 客户端代码

import { HttpAgent, EventType } from "@ag-ui/client";

const agent = new HttpAgent({
  url: "https://your-agent-endpoint.com/agent",
  agentId: "my-agent",
  threadId: "conversation-1"
});

agent.runAgent({
  tools: [...],
  context: [...]
}).subscribe({
  next: (event) => {
    switch (event.type) {
      case EventType.TEXT_MESSAGE_START:
        console.log("消息开始:", event.messageId);
        break;
      case EventType.TEXT_MESSAGE_CONTENT:
        appendToChat(event.delta);
        break;
      case EventType.TEXT_MESSAGE_END:
        console.log("消息完成");
        break;
      case EventType.RUN_ERROR:
        console.error("错误:", event.message);
        break;
    }
  },
  error: (err) => console.error("连接错误:", err),
  complete: () => console.log("运行完成")
});

5.3 服务端代码 (Python)

from ag_ui.core import (
    RunStartedEvent,
    TextMessageStartEvent,
    TextMessageContentEvent,
    TextMessageEndEvent,
    RunFinishedEvent,
)
from ag_ui.encoder import EventEncoder

encoder = EventEncoder()

async def run_agent(thread_id: str, run_id: str):
    # 运行开始
    yield encoder.encode(RunStartedEvent(
        thread_id=thread_id,
        run_id=run_id
    ))
    
    # 消息开始
    message_id = "msg_1"
    yield encoder.encode(TextMessageStartEvent(
        message_id=message_id,
        role="assistant"
    ))
    
    # 流式发送内容
    for chunk in ["Hello", ", ", "world", "!"]:
        yield encoder.encode(TextMessageContentEvent(
            message_id=message_id,
            delta=chunk
        ))
    
    # 消息结束
    yield encoder.encode(TextMessageEndEvent(message_id=message_id))
    
    # 运行完成
    yield encoder.encode(RunFinishedEvent(
        thread_id=thread_id,
        run_id=run_id
    ))

六、支持情况

合作伙伴

框架 状态
LangGraph 已支持
CrewAI 已支持

一方支持

框架 状态
Microsoft Agent Framework 已支持
Google ADK 已支持
AWS Strands Agents 已支持
Mastra 已支持
Pydantic AI 已支持
LlamaIndex 已支持

多语言 SDK

SDK 状态
TypeScript/JavaScript 官方支持
Python 官方支持
Kotlin 社区支持
Go 社区支持
Java 社区支持
Rust 社区支持
Dart 社区支持

七、总结

AG-UI 做的事情不复杂:定义一套标准事件,让代理和前端能顺畅通信。

几个要点:

  1. 流式传输:代理执行过程中实时推送进度,用户不用干等
  2. 事件驱动:统一的事件模型覆盖文本、工具调用、状态等各种场景
  3. 传输无关:不绑定 SSE,WebSocket 也能用
  4. 生态支持:主流 Agent 框架基本都有集成

概念对照

概念 说明
AG-UI 应用层协议,定义事件类型和语义
SSE 传输技术之一,AG-UI 默认用这个
HTTP Streamable HTTP 的流式响应能力
事件 AG-UI 通信的基本单位

相关资料

  • 官方文档:https://docs.ag-ui.com
  • 在线演示:https://dojo.ag-ui.com
  • GitHub:https://github.com/ag-ui-protocol/ag-ui
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐