A2UI解决的核心问题是:如何让AI代理安全地跨信任边界渲染UI。
这话听着有点绕,举项目中的一个示例就清楚了。你问AI助手“帮我订个餐厅”,传统的方式是一轮轮文字对话:
用户: "订个两人桌"AI: "什么时间?"用户: "明天晚上7点"AI: "7点没位置了,5点、6点、8点、9点有,选哪个?"用户: "那8点吧"这种交互效率低,更好的方式是AI直接生成一个包含日期选择器、时间选择器和提交按钮的表单界面。
这里存在一个问题,如果AI生成的是可执行代码,会存在安全风险,可能被注入恶意代码。A2UI的做法是:AI只生成声明式的JSON数据,由客户端负责渲染成UI。
传统方式: AI → 生成代码 → 执行代码 → UI (有安全危险)A2UI方式: AI → 生成JSON → 客户端渲染 → UI (安全)为什么需要A2UI
随着智能体的应用越来越普及,我们也希望智能体在与我们交互时形态能够更丰富。纯文字对话能用,但不够高效,纯静态UI展示又缺乏一定的灵活性。我们需要的是能根据上下文动态生成的UI,它既能承载复杂的交互,又能随对话实时变化。
但这里有个问题,如果AI代理运行在我们的应用内部还好说,它可以直接操作UI控件树来生成界面。但实际的工作场景中,AI代理往往在远程,它没法接触到我们的UI,只能通过信息传递。
我了解到在前端场景,有一种解决方案是,把远程UI渲染在iframe里做沙箱隔离。但这种方式比较重,视觉上也很难和宿主应用保持一致。
A2UI的思路不同:AI生成的不是UI代码,而是UI的结构化描述。应用收到描述后,再用自己的原生组件来渲染。这样既保证了安全性,又保证了视觉一致性。
一图胜千言:
这个思路听起来简单,但要真正落地,需要在UI结构化描述的格式设计上下功夫。
设计原则
首先是安全。前面说过,直接执行LLM生成的代码有安全风险,所以A2UI选择了声明式数据格式。客户端维护一个组件白名单,里面是预先确认过的可信组件(比如Card、Button、TextField这些),AI只能请求渲染白名单里的组件。
{ "component": { "Button": { "child": {"id": "btn_text"}, "action": { "name": "submit_order", "context": [{"key": "orderId", "value": {"path": "/order/id"}}] } } }}即使AI试图生成一个Script组件来执行任意代码,也被会客户端直接拒绝。
其次是对LLM友好。UI用扁平的组件列表展示,通过id互相引用。为啥不用嵌套结构呢?因为LLM是顺序生成token的,深层嵌套意味着它要了整棵结构树才能保证括号匹配、层级正确。扁平列表就简单多了,一个组件生成完,接着生成下一个,想引用别的组件直接写id。这就让增量更新变得容易,用户发起请求后,AI代理只需要输出变化的那几个组件,不用重新生成整个界面。
{ "surfaceUpdate": { "surfaceId": "contact-card", "components": [ { "id": "root", "component": { "Column": { "children": { "explicitList": [ {"id": "avatar"}, {"id": "name"}, {"id": "email"}, {"id": "btn"} ] } } } }, { "id": "avatar", "component": { "Image": { "url": {"path": "/user/avatar"}, "usageHint": "avatar" } } }, { "id": "name", "component": { "Text": { "text": {"path": "/user/name"}, "usageHint": "h2" } } }, { "id": "email", "component": { "Text": { "text": {"path": "/user/email"} } } }, { "id": "btn", "component": { "Button": { "child": {"id": "btn_text"}, "action": { "name": "follow_contact", "context": [{"key": "contactName", "value": {"path": "/user/name"}}] } } } }, { "id": "btn_text", "component": { "Text": { "text": {"literalString": "关注"} } } } ] }}最后是跨平台。A2UI把UI的结构和实现分开:AI代理发送组件树的描述,客户端负责用自己的原生组件渲染。同一份JSON描述,Lit、Angular、Flutter等不同的UI框架都能用。
接着,再深入A2UI内部看下具体的技术原理。
技术原理
A2UI的组件库分四层:组件库、系统指令、LLM、后处理层。下面我们从核心概念开始,逐层拆解。
Surface
Surface是A2UI最核心的概念,可以理解为一个独立的容器。一个应用可以有多个容器,比如一个联系人列表Surface加一个详情卡片的Surface。
创建Surface的消息长这样:
{ "beginRendering": { "surfaceId": "contact-card", "root": "main_column", "styles": { "primaryColor": "#007BFF", "font": "Roboto" } }}Surface内部维护三个关键数据结构
rootComponentId:根组件ID,用于描述Surface的层级关系components:Surface下的组件集合dataModel:数据模型,存储UI需要的动态数据
Component
A2UI定义了18种标准组件,分为三大类:
| 类别 | 组件 | 说明 |
|---|---|---|
| 展示类 | Text, Image, Icon, Video, AudioPlayer, Divider | 只显示内容,不接收输入 |
| 布局类 | Row, Column, List, Card, Tabs, Modal | 用于排列其他组件 |
| 交互类 | Button, TextField, CheckBox, DateTimeInput, MultipleChoice, Slider | 接收用户输入 |
如果这18个组件不够用,我们还可以自己扩展。客户端通过ComponentRegistry注册自定义组件:
// 定义一个组织架构图组件@customElement("org-chart")class OrgChart extends LitElement { @property() data: any; render() { return html`<div class="org-chart">${this.renderTree(this.data)}</div>`; }}// 注册到A2UIcomponentRegistry.register("OrgChart", OrgChart, "org-chart");注册后,LLM就可以生成引用这个组件的JSON,客户端会用你定义的组件来渲染。当然,也可以用同样的方式覆盖标准组件,比如给TextField加上自定义的校验样式。
Data Model
数据模型是UI的数据源,组件通过路径绑定从数据模型获取值。而具体数据的获取,是通过绑定到LLM Agent的一系列工具调用来实现的。
"dataModelUpdate": { "surfaceId": "contact-card", "path": "/", "contents": [ {"key": "user", "valueMap": [ {"key": "name", "valueString": "Alice"}, {"key": "email", "valueString": "alice@example.com"}, {"key": "avatar", "valueString": "https://example.com/avatar.jpg"}, {"key": "id", "valueString": "12345"} ]} ] }前面设计原则章节,组件结构中的的{"path": "/user/name"}就是在引用数据模型中的值。当数据更新时,引用它的组件自动更新。
路径的格式遵循了RFC 6901 JSON Pointer标准:
/user/name→ dataModel.user.name/cart/items/0→ dataModel.cart.items[0]/cart/items/0/price→ dataModel.cart.items[0].price
Action
Action定义了用户交互时触发的操作。当用户点击按钮时,客户端会解析context中的路径引用,从dataModel获取实际值,然后构造userAction消息,发送给Agent。
{ "userAction": { "name": "follow_contact", "surfaceId": "contact-card", "sourceComponentId": "btn", "timestamp": "2024-01-15T10:30:00.000Z", "context": { "contactId": "12345", "contactName": "Alice" } }}Agent收到后处理业务逻辑,然后返回新的dataModelUpdate更新UI状态。
消息流协议
A2UI使用JSONL(JSON Lines)格式,每行一条消息,支持流式传输。完整的交互流程我用AI画了一幅图来呈现,应该比较直观。
渲染器
客户端的核心是A2uiMessageProcessor,负责处理所有消息并维护Surface状态。以Lit为例渲染器为例,每个组件都是一个Web Component:
@customElement("a2ui-button")export class Button extends Root { @property() accessor action: Action | null = null; render() { return html` <button @click=${() => { if (!this.action) return; // 创建状态事件,冒泡到应用层处理 const evt = new StateEvent({ eventType: "a2ui.action", action: this.action, sourceComponentId: this.id, }); this.dispatchEvent(evt); }}> <slot></slot> </button> `; }}目前已有Lit和Angular的渲染器实现,Flutter的正在开发中。
如何学习AI大模型?
如果你对AI大模型入门感兴趣,那么你需要的话可以点击这里大模型重磅福利:入门进阶全套104G学习资源包免费分享!
这份完整版的大模型 AI 学习和面试资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
这是一份大模型从零基础到进阶的学习路线大纲全览,小伙伴们记得点个收藏!
第一阶段:从大模型系统设计入手,讲解大模型的主要方法;
第二阶段:在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;
第三阶段:大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;
第四阶段:大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;
第五阶段:大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;
第六阶段:以SD多模态大模型为主,搭建了文生图小程序案例;
第七阶段:以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。
100套AI大模型商业化落地方案
大模型全套视频教程
200本大模型PDF书籍
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
LLM面试题合集
大模型产品经理资源合集
大模型项目实战合集
👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓