跳到主要内容
AG-UI:构建 AI 前端交互的统一协议 | 极客日志
TypeScript Node.js AI 大前端
AG-UI:构建 AI 前端交互的统一协议 综述由AI生成 AG-UI 是连接 AI 智能体与前端应用的统一交互协议,旨在解决 AI Agent 集成到前端时的标准化挑战。它通过定义 17 种事件类型(如文本消息、工具调用、状态同步),实现前后端解耦与实时协同。核心特性包括统一事件流、实时交互、工具编排及共享状态。文章介绍了 AG-UI 架构、事件系统、状态管理及工具调用流程,并提供了基于 CopilotKit 和 Node.js 的实战示例,展示了如何在 React 前端与 Python/Node 后端之间建立高效的人机协作链路,支持 Human-in-the-Loop 审核机制。
CoderByte 发布于 2026/4/6 更新于 2026/5/20 27 浏览AG-UI:构建 AI 前端交互的统一协议
引言
随着人工智能技术的飞速发展,AI Agent 已经从概念走向实际应用。然而,在将这些智能体集成到前端应用中时,开发者面临着一个关键挑战:如何实现 AI Agent 与用户界面之间的高效、标准化交互?
AG-UI(Agent User Interaction Protocol)正是为解决这一痛点而诞生的开源协议。它不仅仅是一个技术规范,更是连接 AI 智能体与前端应用的桥梁,让开发者能够构建真正智能化的用户体验。它们能够让开发者构建出真正嵌入 UI 应用、感知上下文、实时协同的智能体,而不仅仅是一个在后台提供文本答案的 API 服务。
一、AG-UI 是什么?
1.1 核心定义
AG-UI(Agent-User Interaction Protocol) 是由 CopilotKit 团队提出的开源、轻量级协议,专门用于规范 AI Agent 与前端用户界面之间的通信流程,是一套开源的Agent 与 UI 界面 之间的交互协议。它的核心使命是:
标准化前端应用与 AI 智能体的连接方式,通过开放协议实现通用的 AI 驱动系统通信。
1.2 协议定位
在 AI 生态系统中,AG-UI 与其他协议形成互补关系:
MCP(Model Context Protocol) :定义 AI 模型调用外部工具的协议规范
A2A(Agent-to-Agent Protocol) :规范智能体之间的通信协议
AG-UI :专注于智能体与用户(前端应用)之间的交互规范
这种分工明确的设计让 AG-UI 能够专注于解决人机交互层面的问题,而不与其他协议产生冲突。
二、为什么需要 AG-UI?
在 AG-UI 出现之前,AI 应用开发面临诸多挑战:
技术碎片化
每个 AI 框架(LangGraph、CrewAI、Mastra 等)都有独特的事件机制和 API
不同模型提供商的接口格式各异,增加适配成本
缺乏统一的前后端同步机制
实时性困难
用户期待实时的流式响应体验
传统的请求 - 响应模式无法满足复杂 AI 工作流需求
状态同步和进度反馈机制不完善
人机协作缺失
用户难以对 AI 执行过程进行实时干预
缺乏标准化的人机协作(Human-in-the-loop)机制
工具调用和状态共享缺乏统一规范
这些问题会导致开发者在和多个 AI 服务对接或构建复杂 AI 应用时重写大量代码。
假设有一套通信协议,可以统一前端应用和后端 Agent 之间的交互格式,做到前后端解耦,让大家各司其职。AG-UI 的出现,就是为了解决这个问题
三、AG-UI 核心架构
3.1 整体架构设计
Application:直接与用户交互的前端应用层,比如 ChatGPT、Cursor 等任何 AI powered 应用。
AG-UI Client:在前端侧负责与后端 Agent 进行通信,使用 AG-UI 协议。
Agent:后端 Agent 通常和 AI 服务或其他 Agent 对接,用来处理用户请求。
3.2 核心特性
统一事件流
AG-UI 的核心是单一序列的 JSON 事件,简化了代理与前端的实时同步,确保流畅无碍的通信,不论代理使用何种"语言"或内部实现。
实时交互
支持 LLM 逐步生成的 token 立即显示,提供流畅、自然的用户体验,并实现人机协同工作流程。
工具编排
现代代理可调用函数、运行代码、访问 API。AG-UI 确保前端能实时显示进度和结果,支持人工批准并无缝恢复运行。
共享状态
通过高效传输差异更新,代理能够生成逐步演进的计划、表格或代码文件夹,节省带宽并保持同步状态。
并发与取消
支持用户同时发出多个查询、中途停止或切换线程,通过线程 ID、运行 ID 和有序的关闭路径确保稳定运行。
安全边界
&& 协议内建权限管理、身份认证等机制,&&&& 提供企业级的 CORS,确保数据传输的安全性和可靠性。
3.3 事件 Events AG-UI 定义了17 种标准化事件类型 ,构成完整的 AI 交互生命周期管理体系。基于官方文档,以下是完整的事件系统架构:
EventType 枚举定义 enum EventType { TEXT_MESSAGE_START = "TEXT_MESSAGE_START" , TEXT_MESSAGE_CONTENT = "TEXT_MESSAGE_CONTENT" , TEXT_MESSAGE_END = "TEXT_MESSAGE_END" , TOOL_CALL_START = "TOOL_CALL_START" , TOOL_CALL_ARGS = "TOOL_CALL_ARGS" , TOOL_CALL_END = "TOOL_CALL_END" , TOOL_CALL_RESULT = "TOOL_CALL_RESULT" , STATE_SNAPSHOT = "STATE_SNAPSHOT" , STATE_DELTA = "STATE_DELTA" , MESSAGES_SNAPSHOT = "MESSAGES_SNAPSHOT" , RAW = "RAW" , CUSTOM = "CUSTOM" , RUN_STARTED = "RUN_STARTED" , RUN_FINISHED = "RUN_FINISHED" , RUN_ERROR = "RUN_ERROR" , STEP_STARTED = "STEP_STARTED" , STEP_FINISHED = "STEP_FINISHED" , }
AG-UI 事件分类总览 事件分类 事件类型 事件名称 功能描述 使用场景 生命周期事件(5)流程控制、错误处理 RUN_STARTED 运行开始 标记 Agent 执行开始 初始化 UI 状态,显示加载状态 STEP_STARTED 步骤开始 标记单个步骤开始 显示当前执行步骤 STEP_FINISHED 步骤完成 标记单个步骤完成 更新步骤状态,显示进度 RUN_FINISHED 运行完成 标记整个执行完成 清理状态,显示最终结果 RUN_ERROR 运行错误 标记执行出现错误 错误处理,显示错误信息 文本消息事件(3)实时对话、流式输出 TEXT_MESSAGE_START 消息开始 开始新的文本消息 创建消息容器 TEXT_MESSAGE_CONTENT 消息内容 流式传输消息内容 实时显示打字效果 TEXT_MESSAGE_END 消息结束 标记消息传输完成 完成消息渲染 工具调用事件(4)功能扩展、透明度 TOOL_CALL_START 工具调用开始 开始调用外部工具 显示工具调用状态 TOOL_CALL_ARGS 工具参数 传输工具调用参数 显示调用参数信息 TOOL_CALL_RESULT 工具调用结果 返回工具执行结果 显示工具返回的数据 TOOL_CALL_END 工具调用结束 工具调用完成 显示调用结果 状态管理事件(3)数据同步、一致性 STATE_SNAPSHOT 状态快照 完整状态数据 同步完整应用状态 STATE_DELTA 状态变更 增量状态更新 高效更新部分状态 MESSAGES_SNAPSHOT 消息快照 完整消息历史 同步对话历史 特殊事件(2)系统集成、定制化 RAW 原始事件 未处理的原始数据 调试和扩展用途 CUSTOM 自定义事件 用户定义的事件 特殊业务逻辑处理
事件流程示例 sequenceDiagram participant User as 👤 用户 participant Frontend as 🖥️ 前端 participant Agent as 🤖 AI Agent participant Tool as 🛠️ 工具 User->>Frontend: 发送消息 Frontend->>Agent: 用户输入 Agent->>Frontend: RUN_STARTED Agent->>Frontend: STEP_STARTED Agent->>Frontend: TEXT_MESSAGE_START Agent->>Frontend: TEXT_MESSAGE_CONTENT (流式) Agent->>Frontend: TEXT_MESSAGE_CONTENT (流式) Agent->>Frontend: TEXT_MESSAGE_END Agent->>Frontend: TOOL_CALL_START Agent->>Frontend: TOOL_CALL_ARGS Agent->>Tool: 执行工具 Tool->>Agent: 工具结果 Agent->>Frontend: TOOL_CALL_RESULT Agent->>Frontend: TOOL_CALL_END Agent->>Frontend: STATE_SNAPSHOT Agent->>Frontend: STEP_FINISHED Agent->>Frontend: RUN_FINISHED Frontend->>User: 显示完整响应
3.4 Agents 智能体 Agent 是 AG-UI 里的核心组成部分,负责处理前端发起的请求,和 LLM 交互并生成响应(响应需遵循 Events 格式),同时还要管理对话状态和消息历史。在 Agent 底层可以和其他任意的 AI 服务连接(比如任意的 LLM、定制的 AI 系统、RAG、其他 Agent 等等)。
基本的文本传输 : 通过 TEXT_MESSAGE_*系列事件实现流式文本交互
工具调用 : 在 AG-UI 的规范下,Agent 可以使用哪些 Tools 是由前端告知的。当 Agent 决策需要使用工具时,可以通过一系列事件(TOOL_CALL_START -> TOOL_CALL_ARGS -> TOOL_CALL_END)通知到前端,前端在收到事件后,可决定是否给用户展示对应交互,告知需要调用哪些工具以及对应参数,由用户决定是否调用。调用结果会通过 Message 传递给 Agent。
状态管理 : Agent 可以向前端传递最新完整的状态(STATE_SNAPSHOT)或增量同步状态(STATE_DELTA),可以让前端应用从中断状态恢复。
多 Agent 交互 : Agent 可以通过 A2A 等其他协议和其他 Agent 交互,此过程可以不让前端用户感知(只要不发送 Event 就行)。
Human-in-the-Loop 控制 : 可以将人在回路的控制能力作为 Tool 注入给 Agent,由 Agent 决定在必要时候让人进行决策(仍然通过工具调用链路)
…
3.5 Messages 传统与 LLM 通信时,message 中的 role 通常被分为 system、user、assistant。在 AG-UI 中,developer、工具调用的结果也被当成一种消息类型(tool)。
流式传输 : 通过 TEXT_MESSAGE_* 实现打字机效果
角色管理 : 支持 developer、user、assistant、system、tool 等多种角色
消息历史 : MESSAGES_SNAPSHOT 提供完整消息快照(上下文)
工具集成 : 工具调用结果作为独立的消息类型处理
3.6 状态管理 除了基本的同步聊天消息之外,可以同步任意的状态 ,让人和 AI 的操作可以衔接操作。
官方提供了一个比较有意思的 Demo:让 AI 优化一份菜谱,菜谱在前端使用富交互展示的,随着 AI Agent 的优化,前端交互可实时进行更新。
状态快照 : STATE_SNAPSHOT 提供完整应用状态的一次性同步,一般用于初始状态同步、中断状态恢复等
增量更新 : STATE_DELTA 支持高效的部分状态更新,使用 JSON Patch,可以流式快速更新
复杂交互 : 前端应用可以实现更复杂交互的流式更新,给用户更好的交互体验
3.7 工具调用 Tools 需要和前端交互的工具可以在前端定义 ,并通过协议传给 Agent,当 Agent 认为需要使用工具时,会使用 Event 向前端发消息,前端可向用户展示被调用的工具名称和参数,让用户决定是否继续。
获取更多的信息 : 如天气查询、搜索引擎等
操作外部系统 : 如发送邮件、创建文档等
让人进行信息输入或二次确认 : Human-in-the-loop 机制
前端定义 : 工具由前端定义并传递给 Agent
用户控制 : 用户可以决定是否执行工具调用
参数透明 : TOOL_CALL_ARGS 支持复杂参数的流式传输
结果返回 : TOOL_CALL_RESULT 提供工具执行结果的标准化返回
执行监控 : 完整的工具调用生命周期跟踪
工具调用事件序列:
ToolCallStart -> ToolCallArgs -> ToolCallResult -> ToolCallEnd
四、AG-UI 的技术优势
4.1 灵活性与兼容性
事件结构灵活性
事件无需完全匹配 AG-UI 格式,只需保持兼容性
现有框架可以最小化改动适配 AG-UI
支持渐进式迁移策略
4.2 开发者友好性
丰富的 SDK 支持
TypeScript SDK :提供完整的类型定义和开发工具
Python SDK :支持主流 AI 框架集成
多语言扩展 :社区驱动的其他语言实现
现成的集成方案 Language SDK Status AG-UI Resources .NET 🛠️ In Progress ➡️ PR Nim 🛠️ In Progress ➡️ PR Rust 🛠️ In Progress
五、演示 Demo
5.1 CopilotKit 的演示 Demo
CopilotKit 可以被看作 AG-UI 协议实现的一个框架。它提供了完整的前后端集成方案,使开发者能够快速将 AI Copilot 引入应用,包括:TypeScript/React 前端组件库、Python/Node SDK、以及可选的云端代理服务等。
后端 Agent :使用 Python + LangGraph 构建的一个 Workflow 智能体。
前端应用 :使用 React+TS 构建简单的 Demo。
Copilot 助手 :前端接入 CopilotKit 给应用嵌入的智能助手。
pip install copilotkit ...
import os from dotenv import load_dotenv load_dotenv() from fastapi import FastAPI import uvicorn from copilotkit.integrations.fastapi import add_fastapi_endpoint from copilotkit import CopilotKitRemoteEndpoint, LangGraphAgent from sample_agent.agent import graph app = FastAPI() sdk = CopilotKitRemoteEndpoint( agents=[ LangGraphAgent( name="sample_agent" , description="一个模拟智能体" , graph=graph, ) ], ) add_fastapi_endpoint(app, sdk, "/copilotkit" ) def main (): port = int (os.getenv("PORT" , "8080" )) uvicorn.run( "sample_agent.demo:app" , host="0.0.0.0" , port=port, reload=True , ) if __name__ == "__main__" : main()
npx create-next-app@latest
npm install @copilotkit/react-ui @copilotkit/react-core npm install @copilotkit/runtime class-validator
... const runtime = new CopilotRuntime ({ remoteEndpoints : [{url : "http://localhost:8080/copilotkit" },], }); export const POST = async (req : NextRequest ) => { const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint ({ runtime, serviceAdapter, endpoint : "/api/copilotkit" , }); return handleRequest (req); };
配置全局 CopilotKit 功能(agent 是后端 agent 的名字)
<CopilotKit agent="sample_agent" runtimeUrl="/api/copilotkit" showDevConsole={false } > {children} </CopilotKit >
增加 Copilot 界面,与 Agent 对话,实现智能交互体验。可以选择 sidebar(边栏)、popup(弹出式)、chat(聊天)等多种 UI 形式。这里我们添加一个 sidebar 形式的 Copilot 到主页。
import { CopilotSidebar } from "@copilotkit/react-ui" ; import { useCoAgent, useCoAgentStateRender,useCopilotAction ,useLangGraphInterrupt} from "@copilotkit/react-core" ; export default function App ( ) { return ( <> <Home /> <CopilotSidebar defaultOpen ={true} instructions ={ "您应尽可能地帮助用户 。请根据您拥有的数据以最佳方式回答问题 。"} labels ={{ title: "智能 AI Copilot ", initial: `# 👋 您好 ! 我是你的智能 Copilot 。演示功能 : - **共享状态 **: 搜索历史实时的展示 - **前端工具 **: 调用前端工具打招呼 - **生成式 UI **: 获取天气信息展示卡片 - **HITL 流程 **: 工具调用的人工审核 ` }}/> </> ); }
5.1.3 工具调用(不仅可以调用后端设置的工具(比如搜索、访问数据库、MCP),还可以调用前端定义的 UI'工具'(比如更改样式) )
使用 langchain_mcp_adapters.client 提供的 MCPClient 连接 tavily-mcp,注册 agent 工具
from langchain_mcp_adapters.client import MultiServerMCPClient ... async def get_all_tools (): """ 统一的工具准备函数,避免重复初始化 MCP 客户端 Returns: list: 包含所有可用工具的列表 """ global _all_tools
使用useCopilotAction hook 来注册一个前端 Action,创建一个前端 Action 向用户弹出简单的 Alert 消息和天气获取
... useCopilotAction ({ name : "get_weather" , description : "获取指定位置的天气信息。" , available : "disabled" ,
并将前端 Action 作为工具给 Agent 使用
def should_continue (state: AgentState ): last_message = state["messages" ][-1 ] if not hasattr (last_message, 'tool_calls' ) or not last_message.tool_calls: return END
5.1.4 状态共享 class AgentState (CopilotKitState ): search_history: list [dict ] = []
前端使用 CopilotKit 提供的useCoAgent 这个 hook 函数,useCoAgentStateRender 获取实时状态,
... const {state} = useCoAgent<AgentState >({ name : "sample_agent" , initialState : { search_history : [] }, }) ... useCoAgentStateRender<AgentState >({ name : "sample_agent" , render : ({ status, state, nodeName } ) => { return ( <div > {state.search_history?.map((search, index) => ( <div key ={index} > {search.completed ? "✅" : "❌"} 正在执行:{search.query} {search.completed ? "" : "..."} </div > ))} </div > ) }, }); ... const [localHistory, setLocalHistory] = useState<AgentState ['search_history' ]>([]); useEffect (() => { if (state.search_history && state.search_history .length > 0 ) { const latestSearch = state.search_history [0 ]; if (latestSearch.query .length <=0 ){ return ; } setLocalHistory (prevHistory => { if (prevHistory.length > 0 && prevHistory[prevHistory.length - 1 ].query === latestSearch.query ) { const newHistory = [...prevHistory]; newHistory[prevHistory.length - 1 ] = latestSearch; return newHistory; } else { return [...prevHistory, latestSearch]; } }); } }, [state.search_history ]);
5.1.5 HITL (Human-in-the-loop)人工审核(人机协作 )流程 approval_request = { "type" : "tool_approval_request" , "tool_name" : tool_call.get("name" ), "tool_args" : tool_call.get("args" , {}), "tool_id" : tool_call.get("id" ), "timestamp" : "2025-07-08" }
useLangGraphInterrupt ({ render : ({ event, resolve } ) => { const { tool_name, tool_args } = event.value ; return ( <div className ="bg-gradient-to-br from-blue-50 to-indigo-50 border border-blue-200 rounded-2xl p-6 my-4 shadow-lg" > {/* 标题 */} <div className ="flex items-center gap-3 mb-4" > <div className ="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center" > <span className ="text-lg" > 🔧</span > </div > <div > <h3 className ="text-lg font-bold text-gray-800" > 工具调用审核</h3 > <p className ="text-sm text-gray-600" > 请确认是否执行以下工具调用</p > </div > </div > {/* 工具信息 */} <div className ="bg-white rounded-xl p-4 mb-4 border border-gray-100" > <div className ="grid-cols-1 gap-3" > <div > <label className ="block text-xs font-medium text-gray-500 mb-1" > 工具名称</label > <div className ="bg-gray-50 px-3 py-2 rounded-lg" > <code className ="text-blue-600 font-mono text-sm" > {tool_name}</code > </div > </div > <div > <label className ="block text-xs font-medium text-gray-500 mb-1" > 参数</label > <div className ="bg-gray-50 px-3 py-2 rounded-lg max-h-24 overflow-y-auto" > <pre className ="text-xs text-gray-700 whitespace-pre-wrap font-mono" > {JSON.stringify(tool_args, null, 2)} </pre > </div > </div > </div > </div > {/* 操作按钮 */} <div className ="mt-4" > <div className ="flex gap-2" > <button type ="button" onClick ={() => resolve("approve")} className="flex-1 bg-green-500 hover:bg-green-600 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200 flex items-center justify-center gap-2 text-sm" > <span > ✅</span > 通过 </button > <button type ="button" onClick ={() => resolve("reject")} className="flex-1 bg-red-500 hover:bg-red-600 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200 flex items-center justify-center gap-2 text-sm" > <span > ❌</span > 拒绝 </button > </div > </div > </div > ); } });
5.2 nodejs 示例 import express, {Request , Response } from 'express' ; import dotenv from 'dotenv' ; dotenv.config (); import {RunAgentInputSchema , RunAgentInput , EventType , Message } from '@ag-ui/core' ; import {EventEncoder } from '@ag-ui/encoder' ; import {v4 as uuidv4} from 'uuid' ; import OpenAI from 'openai' ; const app = express (); app.use (express.json ()); app.post ('/awp' , async (req : Request , res : Response ) => { console .log ('app.post > req:' ); try {
六、总结 AG-UI 协议和 CopilotKit 框架代表了智能应用开发的新规范。它们不仅解决了 AI 集成的技术难题,更重要的是建立了一套标准化的开发模式,让每个开发者都能轻松构建智能应用。从前端工程师的角度,无需深究复杂的后端 AI 推理流程,只需使用熟悉的 React 组件和 Hooks,即可调动强大的 AI 为应用服务。从后端 AI 工程师的角度,你也无需操心前端展示,只要按照协议产出标准事件,UI 就会自动配合渲染。这种清晰的前后端职责分离与协同,使 AI 应用开发更加高效与标准化。
对于开发者 :这意味着更高的开发效率和更低的学习成本
对于企业 :这意味着更快的 AI 能力落地和更好的用户体验
对于用户 :这意味着更自然的人机交互和更智能的应用体验
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online