A2UI:让 AI Agent "说出"用户界面的开放协议

引言:Agent 时代的 UI 困境

想象这样一个场景------你对一个 AI 助手说:"帮我订一张明天晚上 7 点的两人桌。" 如果 Agent 只能回复文本,接下来将是一连串低效的对话:"请问哪一天?""什么时间?""几位?"......一个本可以用一个表单瞬间解决的事情,变成了五六个回合的文字乒乓球。

更好的方式显然是:Agent 直接生成一个表单界面,带有日期选择器、时间选择器、人数输入框和确认按钮。用户在 UI 上操作,一次提交,搞定。

但这件"显然更好"的事情,在技术上却极其棘手。Agent 可能运行在远程服务器上,甚至跨越组织的信任边界。它不能直接操控你的 UI,只能发送消息。传统的方案------在 iframe 中嵌入 Agent 返回的 HTML/JavaScript------不仅笨重、风格割裂,还引入了严重的安全隐患。

Google 发起的开源项目 A2UI(Agent-to-User Interface) 就是为了解决这个问题而生的。它定义了一种让 Agent "说 UI" 的通用语言:Agent 发送声明式的 JSON 消息来描述界面的意图,客户端应用用自己原生的组件库来渲染。安全如数据,表达如代码。


一、A2UI 是什么?一句话理解核心理念

A2UI 是一个声明式 UI 协议,而不是一个框架。它的核心思想可以拆成三层:

Agent 生成一段 JSON,描述"我想展示一个标题、一个日期选择器和一个按钮"。这段 JSON 通过任意传输通道(A2A 协议、WebSocket、SSE 等)到达客户端。客户端的 A2UI 渲染器读取 JSON,将抽象的组件描述映射为自己代码库中的原生组件------可以是 Flutter Widget、Angular Component、Lit Web Component 或 React 组件。

这意味着同一份 A2UI JSON 可以在 Web、移动端和桌面端被不同的渲染器渲染为风格统一、性能原生的界面,同时 Agent 完全无法执行任何代码------它只能从客户端预先批准的"组件目录"中选取组件来组合界面。


二、为什么需要 A2UI?三大设计支柱

安全优先。 A2UI 是一种声明式数据格式,不是可执行代码。Agent 不能注入 JavaScript,不能操纵 DOM------它只能请求渲染客户端目录中已经存在的、预先审核过的组件(如 Card、Button、TextField)。安全性由客户端完全掌控。

LLM 友好且支持增量更新。 UI 被表示为一个扁平的组件列表,组件之间通过 ID 引用来建立父子关系,而不是深层嵌套的 JSON 树。这种"邻接表"模型让 LLM 可以逐步生成组件、流式发送,客户端可以渐进式渲染------用户看到界面逐步构建,而不是盯着转圈等待。当需要更新时,只需发送带有已有 ID 的新定义即可,无需重新生成整个 UI。

框架无关且可移植。 Agent 发送的是对组件树和数据模型的抽象描述。渲染的责任完全在客户端。同一份 JSON 可以被 Lit 渲染为 Web Component,被 Flutter 渲染为原生移动控件,被 Angular 渲染为 Angular 组件,甚至未来被 SwiftUI 或 Jetpack Compose 渲染为 iOS 和 Android 原生视图。


三、核心概念详解

3.1 Surface(画布)

Surface 是 A2UI 中承载组件的容器,可以理解为一个完整的 UI 单元------一个对话框、一个侧边栏或一个主视图。每个 Surface 有唯一的 surfaceId,拥有自己的组件树和数据模型。Agent 通过创建、更新和删除 Surface 来管理界面的生命周期。

3.2 组件与邻接表模型

这是 A2UI 最独特的设计决策。传统的 UI 描述通常使用嵌套树结构,但 LLM 生成深层嵌套 JSON 时很容易出错,且难以流式传输和增量更新。A2UI 采用了扁平的邻接表模型:所有组件排成一个列表,每个组件有唯一 ID,通过 ID 引用子组件。

举个例子,一个包含标题和两个按钮的简单界面,在 v0.9 中是这样描述的:根组件 Column 声明子组件列表为 ["greeting", "buttons"],greeting 是一个 Text 组件,buttons 是一个 Row 组件再引用两个 Button。所有组件平级排列,通过 ID 建立层次关系。

A2UI 提供了一套标准组件目录,按用途分为布局类(Row、Column、List)、展示类(Text、Image、Icon、Divider)、交互类(Button、TextField、CheckBox、DateTimeInput、Slider、ChoicePicker)和容器类(Card、Tabs、Modal)。

3.3 数据绑定

A2UI 将 UI 结构与应用状态分离。每个 Surface 拥有一个 JSON 数据模型,组件通过 JSON Pointer 路径 (如 /user/name/cart/items/0/price)绑定到数据模型中的值。

这种分离带来了强大的响应式更新能力:当 Agent 更新数据模型中的某个路径时,绑定到该路径的所有组件自动更新显示内容,无需重新发送组件定义。同时,交互组件(如 TextField)支持双向绑定------用户输入立即写入本地数据模型,当用户点击提交按钮时,按钮的 Action 从数据模型中解析出最新值发送给 Agent。

动态列表是数据绑定的一个精彩应用:一个模板组件绑定到数据模型中的数组路径,数组中每增加一个元素就自动渲染一个新实例,且模板内的路径自动限定到当前数组元素的作用域。

3.4 消息类型与生命周期

以 v0.9 为例,Agent 与客户端之间通过四种核心消息通信。createSurface 创建画布并指定使用的组件目录。updateComponents 定义或更新 UI 组件。updateDataModel 更新应用状态。deleteSurface 移除一个界面。

一个典型的餐厅预订流程是这样的:Agent 先发送 createSurface 创建画布,然后通过 updateComponents 定义表单结构(标题、人数输入框、提交按钮),再通过 updateDataModel 填充初始数据(日期、人数)。用户修改人数,客户端自动更新本地数据模型。用户点击确认,客户端将按钮 Action 中引用的数据路径解析为当前值,封装为 action 消息发送给 Agent。Agent 处理后可以更新界面或删除 Surface。

3.5 Catalog(组件目录)

Catalog 是 A2UI 安全模型的关键枢纽。它是一个 JSON Schema 文件,定义了 Agent 可以使用的所有组件、函数和主题。客户端告诉 Agent 自己支持哪些 Catalog,Agent 在创建 Surface 时选择一个 Catalog 并锁定。之后 Agent 生成的所有 JSON 都会在双端被验证------Agent 端在发送前验证,客户端在接收后再验证。如果验证失败,客户端会发送 VALIDATION_FAILED 错误,Agent 可以据此自我纠正。

A2UI 团队维护了一个"Basic Catalog"作为起步用的通用组件集,但大多数生产应用会定义自己的 Catalog 来反映自己的设计系统。你可以从零开始定义,也可以导入 Basic Catalog 中的部分组件再扩展自定义组件(如图表、地图、股票行情组件)。Catalog 之间通过 URI 作为唯一标识符进行协商和版本管理。

3.6 传输层

A2UI 是传输无关的------任何能传递 JSON 的机制都可以工作。目前与 A2A 协议和 AG UI 有成熟的集成,REST、WebSocket 和 SSE 在路线图中。消息通常以 JSON Lines(JSONL)格式流式传输,每行一个完整的 JSON 对象。在 A2A 绑定中,A2UI 消息被编码为 DataPart,MIME 类型为 application/json+a2ui


四、v0.8 → v0.9:从"结构化输出优先"到"提示词优先"

A2UI 的版本演进体现了对 LLM 生成能力更深层的理解。v0.8 被设计为通过 LLM 的"结构化输出"模式生成,依赖深层嵌套和特定的包装结构。v0.9 则做了一次哲学性的转变------为"嵌入系统提示词"而优化。

最直观的变化是组件格式从嵌套键变成了扁平判别器。v0.8 写作 "component": { "Text": { "text": { "literalString": "Hello" } } },v0.9 则简化为 "component": "Text", "text": "Hello"。数据模型更新从键值对数组变成了标准 JSON 对象。子组件列表从 {"explicitList": [...]} 变成了简单的数组。这些改动大幅减少了 token 消耗,也更符合 LLM 天然擅长生成的 JSON 模式。

v0.9 还引入了几个重要的新能力:createSurface 消息要求指定 catalogId,使目录协商变得显式;新增了 sendDataModel 标志,允许客户端在每条消息的元数据中自动附带完整数据模型,实现"无状态 Agent"模式;引入了 formatString 函数支持字符串插值;以及结构化的 VALIDATION_FAILED 错误反馈机制,让 LLM 可以在"生成-验证-纠正"循环中自我改进。


五、双向交互:Action 与数据同步

A2UI 不只是单向的 UI 推送,它支持完整的双向通信。交互组件(如 Button)可以定义 Action,分为两种:Server Event 发送到 Agent 处理(如提交表单),Local Function Call 在客户端本地执行(如打开 URL、格式化字符串、输入验证)。

Action 中的 context 是一个精心设计的机制------它允许按钮在触发时从数据模型中"摘取"特定路径的当前值,封装成一个简洁的上下文对象发送给 Agent,避免 Agent 需要解析整个数据模型。

v0.9 的 Data Model Sync 更是支持了一种优雅的"口头提交"模式:当 sendDataModel 启用时,用户甚至不需要点击按钮------只要说"好的,提交吧",客户端会将当前完整数据模型附在消息元数据中,Agent 从元数据中读取所有表单值即可完成处理。

在多 Agent 架构中,协调器(Orchestrator)需要维护 Surface 到子 Agent 的所有权映射,确保用户的 Action 被路由回正确的子 Agent,并且在转发消息时剥离其他 Agent 的数据模型,防止跨 Agent 的数据泄露。


六、生态系统与真实应用

A2UI 不是一个纸上协议------它已经在多个 Google 产品和合作伙伴项目中投入使用。

Google Opal 使用 A2UI 驱动 AI 小应用的动态生成式 UI 系统,让数十万用户可以用自然语言创建、编辑和分享 AI 应用。Flutter GenUI SDK 在底层使用 A2UI 作为服务端 Agent 与 Flutter 应用之间的通信协议,实现跨 iOS、Android、Web、桌面的原生渲染。Google ADK(Agent Development Kit)内置了 A2UI v0.8 标准目录的原生渲染支持。CopilotKit / AG UI 提供了 A2UI 的 Day-zero 兼容,AG UI 作为传输层,A2UI 作为 UI 内容格式,形成互补。

A2UI 与同类方案的定位也值得理解:MCP Apps 让远程服务器通过 iframe 提供完整的 UI 体验,适合服务器完全掌控 UI 的场景;AG UI 是一个前后端连接的传输协议;A2UI 则是 UI 负载本身的格式标准。三者可以组合使用------A2UI + AG UI 用 AG UI 做管道、A2UI 做内容,A2UI + A2A 用 A2A 协议在多 Agent 系统中传递 A2UI 消息。


七、动手试一试

体验 A2UI 最快的方式是运行仓库自带的餐厅查找器 Demo。克隆仓库、设置 Gemini API Key、进入 samples/client/lit 目录运行 npm run demo:all,就能在浏览器中看到一个由 Gemini 驱动的 Agent 实时生成交互式 UI 的完整流程。

如果你想更深入地开发,有三条路径可选:前端开发者可以将 A2UI 渲染器集成到自己的应用中(目前支持 Lit、Angular,React 在路线图中);后端开发者可以使用 Google ADK 构建生成 A2UI 响应的 Agent;或者直接使用 AG UI/CopilotKit 或 Flutter GenUI SDK 等已内置 A2UI 支持的框架。


结语

A2UI 的出现代表了 Agent 交互范式的一次重要进化------从"Agent 只能说文字"到"Agent 可以说 UI"。它用声明式数据格式解决了安全问题,用邻接表模型解决了 LLM 生成和流式渲染的问题,用框架无关的抽象解决了跨平台问题,用 Catalog 协商机制解决了可扩展性问题。

作为 Google 发起、Apache 2.0 许可的开源项目,A2UI 目前处于 v0.8(稳定)和 v0.9(草案)阶段,正在积极向 v1.0 迈进。如果你正在构建 AI Agent 驱动的应用,无论是对话式界面、企业工作流还是多 Agent 系统,A2UI 都值得关注和尝试。

相关推荐
像颗糖2 小时前
Nanobot openai_codex 如何支持自定义 Responses
openai·cursor
掘金酱2 小时前
小册上新|玩🦐吗?ai 编程全栈指南了解一下?
前端·人工智能·ai编程
玖墨nor3 小时前
如何武装你的 Antigravity 工作区:Rule / Workflow / Skill 三层机制实战
ai编程
gujunge5 小时前
Spring with AI (3): 定制对话——Prompt模板引入
ai·大模型·llm·openai·qwen·rag·spring ai·deepseek
小虎AI生活6 小时前
1200 万人、增长 47%:一人公司 2026 爆发的数据实锤
ai编程
爱吃的小肥羊6 小时前
Claude Code Skills 资源大盘点:导航站 + GitHub 精选仓库全整理
人工智能·ai编程