告别枯燥对话框!Google 开源 A2UI,但官方代码质量却让人大跌眼镜

20 阅读14分钟

告别枯燥对话框!Google 开源 A2UI,但官方代码质量却让人大跌眼镜?

你有没有觉得,现在的AI聊天机器人虽然很聪明,但用起来总有点"费劲"? 想象一下,你想利用智能体预订一家餐厅的流程。

你: "帮我订明晚 7 点的两人桌。"
餐厅智能体: "好的,请问是哪一天?"
你: "明天。"
餐厅智能体: "具体几点呢?"
你: "大概晚上 7 点吧。"
餐厅智能体: "抱歉,那个时间没有空位了,其他时间可以吗?"

是不是很崩溃?为了一个简单的预订,你得像挤牙膏一样,来回拉扯半天。这种传统的纯文本交互方式,在处理稍微复杂一点的任务时,效率实在太低了。不仅用户体验差,而且每一轮对话都在消耗宝贵的推理算力和时间。

痛点对比图

如果 AI 能直接扔给你一个漂亮的日历选择器和时间表单,让你自己点几下就搞定,那该多好?用户不需要用自然语言描述每一个细节,AI 也不需要反复追问确认——一个直观的界面就能解决一切。

这正是 Google 联合社区推出的 A2UI(Agent to UI) 协议要解决的问题。


什么是 A2UI?一句话说清楚

简单来说,A2UI 是一个让AI智能体直接生成交互式界面的开源协议。它的全称是 Agent to User Interface,顾名思义,就是在 AI 智能体和用户界面之间的一座桥梁。

有了A2UI,AI不再只是干巴巴地回复文字。当它发现你需要填写表单、查看图表或浏览商品列表时,它可以直接"画"出一个包含按钮、输入框、卡片、日期选择器等元素的漂亮界面,推送到你的屏幕上。你直接在这个界面上点击、滑动、输入,就像在使用一个原生的App一样流畅自然。

这背后的技术原理其实并不复杂。AI 智能体根据用户的意图,生成一段符合 A2UI 规范的 JSON 数据。这段数据描述了界面的结构——比如"第一行放一个标题,下面放一个日期选择器,再下面放两个按钮"。然后,客户端的渲染器接收到这段数据后,用自己的原生组件把它渲染出来。整个过程就像是AI绘制一份人机交互的蓝图,而你的App负责把蓝图变成真实的建筑。

A2UI 工作原理

为什么不让AI直接生成HTML?

你可能会问:"直接让 AI 生成网页代码(HTML/JavaScript)不就行了吗?何必搞一个新协议?"

这个问题问得好,但答案是:还真不行。原因有三个。

第一,安全风险巨大。在现代的多智能体生态中,帮你干活的 AI 可能运行在远端的服务器上,甚至可能是第三方提供的服务。如果直接把它们生成的代码扔到你的手机或网页里运行,等于给了远程 AI 在你设备上执行任意代码的权限。这就像你让一个陌生人直接进入你家随便操作一样危险。

第二,界面风格不统一。每个 App 都有自己的设计语言、主题颜色和交互规范。如果 AI 生成的是一段固定的 HTML 代码,它很难自动适配你 App 的风格,最终呈现出来的效果往往格格不入,像是在一个精致的 App 里嵌入了一个粗糙的网页。

第三,跨平台成本高。HTML 代码只能在浏览器里运行。如果你的产品同时有 Web 版、iOS 版、Android 版和桌面版,AI 就需要为每个平台生成不同的代码,这显然不现实。

A2UI 巧妙地避开了这些坑。它传输的是声明式的 JSON 数据,而不是可执行的代码。AI 只能请求使用你前端应用里已经预先注册好的、安全的组件(比如"给我一个红色的提交按钮"),客户端维护着一个受信任的组件目录,只有目录里的组件才会被渲染。这样就彻底杜绝了恶意代码注入的风险。同时,由于渲染工作完全由客户端的原生框架(React、Vue、Flutter 等)完成,界面能完美继承宿主 App 的主题、动画和无障碍特性。而且,同一份 JSON 数据可以在任何平台上渲染,真正实现了"一次生成,到处运行"。


理想很丰满,现实很骨感:令人震惊的官方工程化水平

A2UI 的理念无疑是先进的,它描绘了下一代 AI 交互的美好蓝图。然而,当我们满怀期待地深入研究 Google 官方维护的 A2UI 仓库时,却发现了一个令人震惊的事实:官方项目的代码质量和工程化水平,与其宏大的愿景之间存在着巨大的鸿沟。

坦白说,这并不让人意外。这似乎印证了当下 AI 圈的一个普遍现象:搞 AI 生态的人,往往不懂代码、不懂软件工程、不懂软件架构。 他们擅长算法和模型,能写出惊艳的论文和 Demo,却在构建可靠的、可维护的、生产级的工程基础设施时显得捉襟见肘。A2UI 官方仓库就是这种现象的一个典型缩影。

让我们来看看那些让人大跌眼镜的"神操作"。以下所有问题均来自官方 GitHub Issues 的真实记录,有据可查。

1. 形同虚设的类型系统:381 处 any 类型

在 TypeScript 项目中,类型安全是最基本的质量底线。选择 TypeScript 而不是 JavaScript,本身就是为了获得编译时的类型检查能力,从而在代码运行之前就发现潜在的 Bug。然而,A2UI 官方代码中竟然充斥着高达 381 处 any 类型声明(Issue #1296)。

any 是 TypeScript 中的"万能类型",使用它意味着告诉编译器"别管这个变量是什么类型了,我说什么就是什么"。这等于在类型安全的城墙上凿了 381 个洞。更让人无语的是,其中 379 处是开发者故意写上去的,而不是编译器推断失败。项目的核心库 web_core 一个模块就贡献了 99 处 any

更离谱的是,React 渲染器的构建脚本甚至根本没有执行类型检查(Issue #1283)。虽然项目里存在一个 typecheck 脚本,但它既没有接入构建流程,也没有接入 CI 流水线。这意味着开发者提交的代码即使存在类型错误,也能毫无阻碍地通过 CI 检查并被合并到主分支。项目协作者 jacobsimionato 在看到这个问题时都忍不住惊呼:"Wow, this seems like a big problem! I wonder if it's masking a lot of type issues in the codebase!"(天哪,这看起来是个大问题!我怀疑它掩盖了代码库中大量的类型问题!)

2. 发布到 npm 的包竟然没有样式

你能想象一个 UI 组件库发布到 npm 后,用户安装使用时发现组件竟然没有任何样式吗?按钮没有边框,输入框没有内边距,一切都是"裸奔"状态。这种匪夷所思的事情,在 A2UI 身上真实发生了(Issue #1307)。

发布的 @a2ui/react@0.9.1 版本中,Button、TextField、ChoicePicker 等基础组件的 CSS 模块导出为空对象 {}。这导致组件渲染出来后,class 属性的值变成了字面量 "undefined undefined"——连个边框和背景色都没有。

问题的根源在于:官方的示例项目使用的是 file: 协议直接链接到本地源码目录,Vite 在开发模式下会正确处理 CSS 模块。但实际通过 npm install 安装的发布包,由于构建管道(tsup)没有正确处理 CSS 模块的导出,样式信息在打包过程中丢失了。换句话说,官方团队从来没有真正测试过用户实际安装的 npm 包。这在任何一个成熟的前端项目中都是不可想象的低级错误。

3. 开源半年才想起来统一代码格式

代码格式化是软件工程中最基础的实践之一。一个正经的开源项目,在第一天就应该配置好 Prettier、ESLint 和 EditorConfig,确保所有贡献者的代码风格一致。然而,A2UI 官方仓库直到 2026 年 5 月 5 日——也就是项目开源近半年后——才终于提交了一个名为 "Enforce formatting in repo" 的 PR(#1338)。

在此之前,整个仓库没有统一的 Prettier 配置,没有 EditorConfig,没有 CI 格式检查。不同的开发者用不同的缩进风格、不同的引号偏好、不同的换行规则提交代码,导致 PR 中充斥着大量无意义的格式差异,严重干扰了代码审查。这个迟来的格式化 PR 一次性修改了 1106 个文件,增加了 24775 行代码,删除了 27251 行代码。光是这个数字,就足以想象之前的代码风格有多么混乱不堪。

更令人哭笑不得的是,直到今天(2026 年 5 月 10 日),Angular 渲染器居然连 Linter 都还没有配置(Issue #1387)。一个 Google 出品的开源项目,连最基本的代码检查工具都没有,这实在让人难以置信。

4. 各自为政的渲染器:架构混乱与不一致

A2UI 官方维护了 Lit、React、Angular 三个 Web 渲染器,但它们之间缺乏统一的架构约束和行为规范。比如,三个渲染器处理 Image 组件的逻辑各不相同,在 flex 布局中的表现也不一致(Issue #1298)。复数处理函数硬编码了 en-US 语言环境,且各渲染器的实现方式不统一(Issue #1385)。Angular 渲染器的 catalog 实现与规范定义的 props 存在差异(Issue #1303)。

在发布和运维层面,问题同样严重。核心的 npm 发布流程本身就是损坏的(Issue #1306),CI 生成的 publishing manifest 格式有误。React 渲染器发布到 npm 的包甚至忘记添加 License 声明(Issue #1290)。发布流程至今没有实现自动化(Issue #1383,被标记为 P1 优先级),这意味着每次发版都需要手动操作,极易出错。

这些问题叠加在一起,暴露出官方团队在前端工程化、CI/CD 流程、代码规范、测试覆盖率和架构设计方面的系统性不足。这不仅大幅增加了开发者的接入成本和排错难度,也让人对官方版本的生产可用性打上了一个大大的问号。


这不是个例:AI 生态的工程化通病

A2UI 官方仓库暴露的问题,绝非个例。纵观当下整个 AI 开源生态,类似的"重概念、轻工程"现象比比皆是。

很多 AI 项目的发起者是研究人员或算法工程师,他们对模型架构和训练技巧了如指掌,但对软件工程的基本实践——版本管理、持续集成、代码审查、测试策略、发布流程——却缺乏系统性的认知。他们习惯于写"能跑就行"的实验代码,而不是"能维护、能扩展、能协作"的生产代码。

这种现象的后果是:很多 AI 项目在 Demo 阶段看起来光鲜亮丽,一旦真正投入生产环境,就会暴露出各种工程层面的问题。依赖管理混乱、接口设计随意、错误处理缺失、文档与实现脱节……这些在传统软件工程中早已被解决的问题,在 AI 生态中却像是第一次遇到一样。

A2UI 作为 Google 出品的项目,尚且如此,其他中小型 AI 开源项目的工程质量可想而知。这也是为什么,当一个 AI 生态项目展现出扎实的工程功底时,它会显得格外珍贵。


社区之光:a2ui-vue 的降维打击

面对官方工程的拉胯,社区力量站了出来。对于广大的 Vue 开发者来说,有一个激动人心的好消息:由社区开发者 Shawn Wang 打造的 a2ui-vue 项目,不仅在工程质量上实现了"降维打击",已经被A2UI 官方正式收录为生态系统中的核心渲染器之一

Vue 社区集成

与官方仓库的混乱形成鲜明对比,a2ui-vue 展现了一个成熟前端工程师应有的专业素养。这个项目不是一个匆忙拼凑的 Demo,而是一个经过深思熟虑、精心打磨的生产级开源项目。

极致的工程化体验

a2ui-vue 从项目创建的第一天起,就建立了完善的工程化体系。完整的 TypeScript 类型定义确保了类型安全,严格的 Lint 规则和格式化配置保证了代码风格的一致性,完善的 CI/CD 流程确保了每次发布的质量。这些在官方项目中缺失或迟到的基础设施,在 a2ui-vue 中从一开始就是标配。

极简接入:几行代码搞定

借助 a2ui-vue,开发者不需要去理解复杂的底层协议细节,也不用担心踩到官方那样的"空样式"坑。只需短短几行代码,就能让你的 Vue 应用具备渲染 AI 动态界面的能力。导入组件、注册渲染器、在模板中使用——整个过程行云流水,没有任何其他多余的配置和心智负担。

代码演示

丰富的组件与高度可定制

a2ui-vue 内置了 20 多个常用组件,涵盖布局、内容展示、媒体播放、表单输入等各个类别,足以满足绝大多数 AI 交互场景的需求。如果你觉得默认组件不够个性化,它还提供了灵活的扩展机制,让你可以轻松注册自定义组件和主题,让 AI 生成的界面完全符合你的品牌调性和设计规范。

无缝融入 Vue 3 生态

作为专为 Vue 3 量身定制的渲染器,a2ui-vue 完美契合 Vue 的 Composition API 和响应式系统。它不是简单地把 A2UI 协议"翻译"成 Vue 组件,而是深度融入了 Vue 的设计哲学,充分利用了 refreactiveprovide/inject 等 Vue 3 的核心特性,确保了渲染性能和开发体验的双重优秀。

无论是打造智能客服系统、内部数据分析看板,还是开发其他的全新AI原生应用,a2ui-vue 都是 Vue 技术栈团队的不可多得的利器。

结语

从“纯文本对话”到“动态交互界面”,A2UI 协议告诉我们 AI 交互体验升级的方向,AI 变得“聪明”了,它也变得更加“好用”。而 A2UI 官方仓库也给我们振聋发聩:**AI 时代,好的想法和 AI 协议固然重要,但扎实的软件工程实践也绝不能忽视。**当前 AI 生态中“重想法、轻工程”的弊病,正在成为 AI 技术真正落地最隐性的障碍。好在开源的美妙在此:**当官方“拉胯”时,就会有优秀的社区开发者主动站出来补救。**a2ui-vue 就是这样一件美好的事——它用扎实的工程实力证明了 AI 生态项目也可以专业、靠谱、优雅。

准备好让你的 AI 智能体"画"出界面了吗?现在就去了解 a2ui-vue 吧!