关键词:A2UI、A2UI Express、生成式 UI(Generative UI)、Google、大模型、LLM、Token 优化、推理延迟、Gemini、AI Agent、决策模型、推理格式
一句话摘要:Google A2UI 新版本推出可替换的推理格式 A2UI Express,让大模型生成界面的 Token 消耗降到约三分之一、延迟最高降低约 3 倍;再配合 Jev 决策模型做受控生成,固定结构界面最高可快约 80 倍。本文用通俗语言讲清 A2UI Express 的语法、评测数据、决策模型方案和选型思路。
系列文章:本文是《从聊天框到动态界面:一文看懂生成式 UI 与 Google A2UI》的进阶篇。入门篇讲了生成式 UI 是什么、A2UI 怎么工作;这一篇聚焦一个落地时绕不开的问题:生成式 UI 太慢,以及 Google 给出的提速方案。
本文主要参考 Google Developers Blog 2026 年 10 月 27 日的文章 Fast, reliable A2UI, with swappable inference formats。文中数据来自原文,文字由笔者重新组织和改写,示例代码为笔者编写的示意代码。技术细节以官方文档为准。
阅读前提
本文默认你已经了解入门篇中的这几个概念。如果还不熟悉,建议先读入门篇:
| 概念 | 一句话回顾 |
|---|---|
| 组件目录(Catalog) | 客户端公布的"菜单",Agent 只能用目录里的组件 |
| 扁平组件列表 + ID 引用 | 组件不层层嵌套,父组件通过 ID 引用子组件 |
| 组件与数据分离 | 组件通过 /title 这样的路径绑定到数据模型 |
| 三类消息 | createSurface 开画布,updateComponents 放组件,updateDataModel 填数据 |
读完本文你会了解:
- 为什么让大模型直接写 A2UI JSON 会慢;
- A2UI 的"推理格式可替换"机制是怎么工作的;
- A2UI Express 的语法,以及它和入门篇 JSON 的对应关系;
- 四种候选格式的评测数据,以及"关闭思考模式反而更好"的结论;
- 用决策模型生成固定结构界面的思路;
- 不同场景下如何选型。
一、先说结论
如果你只有一分钟,记住这几点:
- 问题:让大模型直接输出复杂的 JSON 界面描述,速度慢、容易出错。用户要等模型把整个界面"写"完。
- 方案一:A2UI Express。模型改写一种类似 Python 的简洁语法,再由 SDK 里的确定性代码编译成标准 A2UI JSON。同样的界面,Token 数大约只有原来的三分之一,有效率和 JSON 持平。官方称延迟最多可降低约 3 倍。
- 方案二:决策模型(受控生成)。对于设置页、结账页这类结构固定的界面,不让大模型设计布局,而是让一个专门的决策模型做选择题。官方称这种方式最多可快约 80 倍。
- 推理格式可替换:Express 只是默认选项。你也可以接入自己的 DSL(domain-specific language,领域特定语言),只要提供提示词生成器和编译器,组件目录和渲染器都不用改。
二、生成式 UI 为什么慢?时间都花在大模型生成上
入门篇用"点菜"类比了 A2UI 的流程:
- 客户端公布菜单(组件目录);
- Agent 按菜单点菜(大模型生成 A2UI 消息);
- 客户端用原生组件上菜(渲染);
- 用户交互,事件回传。
第 1、3、4 步都是普通代码,速度很快。用户等待的时间,几乎全部花在第 2 步:大模型一个 Token 一个 Token 地把界面描述"写"出来。
所以提速的方向很明确:让第 2 步少写点、写得准、或者干脆不让大模型写。 本文的两个方案正好对应这几条路。
三、痛点:让大模型直接写 A2UI JSON 为什么又慢又容易出错?
回顾入门篇里那张订餐厅卡片的 JSON 示意。每个组件都要写 "id"、"component"、属性键名、引号和花括号。早期的 A2UI 正是要求模型直接输出这样的完整 JSON 传输消息。
结合原文和笔者的理解,问题有三个:
| 问题 | 说明 |
|---|---|
| Token 浪费 | 大量 Token 花在键名、引号、括号这类"格式开销"上,真正有信息量的内容占比不高 |
| 容易出错 | 模型要在很长的输出里保持括号配对,同时满足复杂的 JSON Schema 约束,越长越容易出错 |
| 与 LLM 强绑定 | JSON 需要逐字生成文本,只有会"写字"的大模型能胜任,更快的非文本决策模型接不进来 |
入门篇提到,A2UI v0.9 的 SDK 已经能"边解析边修复"模型输出的 JSON。但修复只能补救错误,没法减少要生成的 Token 数。要真正提速,得从模型输出的格式本身下手。
四、A2UI 推理格式(inference format)可替换:模型输出与网络传输解耦
新版本引入了一个概念:推理格式(inference format),也就是模型实际输出的格式。
关键思路是:
模型输出的格式和网络上传输的格式不必是同一种。
模型只负责写一种对它友好的中间格式,然后由 SDK 中的确定性代码把它编译成标准 A2UI JSON。传输层发出去的依然是入门篇里介绍的 createSurface、updateComponents、updateDataModel 消息,渲染器完全不用改。
┌──────── 本次新增 ────────┐
大模型 ──▶ 推理格式(如 Express) ──▶ SDK 编译器 ──▶ 标准 A2UI JSON ──▶ 传输 ──▶ 渲染器
(确定性代码) (入门篇的三类消息) (不变)
每种推理格式由两部分组成,都由 SDK 根据组件目录的 Schema 自动生成:
- 提示词片段:教模型这种格式的语法;
- 编译器:把模型的回复编译成经过校验的 A2UI 消息。
因为两者都从同一份 Schema 生成,模型没法描述目录里不存在的组件或属性。入门篇强调的"Agent 只能点菜单上的菜"这条安全原则,在新格式下依然成立。
切换只需要一个参数
入门篇的接入流程里,"用目录生成系统提示词"和"解析校验模型输出"这两步,现在都交给同一个处理器完成。以 Python SDK 为例(以下为基于官方 SDK 的调用示例,参数细节以官方文档为准):
from a2ui.processor import A2uiGenerator, CatalogConfig
from a2ui.inference_formats import ExpressFormatFactory
catalog = CatalogConfig.from_path("catalog.json")
generator = A2uiGenerator(
[catalog],
examples=my_examples, # few-shot 示例仍按 A2UI JSON 编写
inference_format_factory=ExpressFormatFactory(), # 关键:指定推理格式
)
processor = generator.create_processor(renderer_capabilities)
# 把 SDK 生成的格式说明拼进系统提示词
system_prompt = f"{my_instructions}\n\n{processor.prompt_snippet}"
# 模型回复后,由 SDK 解析成文本片段 + 校验过的 A2UI 消息
parts = processor.parse_response(model_reply)
值得注意的是,few-shot 示例仍然用 A2UI JSON 编写,由 SDK 自动转换成目标格式。这意味着以后切换推理格式,示例不用重写。
目前支持情况:
- Python:
a2ui-agent-sdk0.9.0(PyPI) - TypeScript:
@a2ui/agent(npm),把new ExpressFormatFactory()作为生成器的第三个参数传入 - Dart:
a2ui_agent0.0.1-wip004(pub.dev)
五、A2UI Express 语法详解:类 Python 写法与 JSON 的对应关系
1. 语法规则
Express 的规则很少,熟悉 Python 的人几分钟就能看懂:
| 写法 | 含义 | 对应入门篇的概念 |
|---|---|---|
变量名=组件(参数...) | 一行声明一个组件 | 扁平组件列表中的一项 |
| 变量名 | 就是组件 ID | ID 引用 |
| 位置参数 | 编译器按 Schema 中声明的属性顺序映射,_ 表示跳过 | 组件属性 |
$/路径 | 绑定到数据模型 | 组件与数据分离 |
$/路径="值" | 给数据模型赋值 | updateDataModel |
Event("名称", {...}) | 声明一个服务端动作 | 交互事件回传 |
surface("id") | 声明界面 | createSurface |
可以看出,Express 并没有发明新概念。它只是把 A2UI 原有的扁平列表、ID 引用、数据绑定换了一种更紧凑的写法。这也是它能被确定性地编译回 JSON 的原因。
2. 同一张卡片,两种写法
把入门篇里订餐厅卡片的例子改写成 Express(示意代码,具体组件和参数顺序取决于你的目录定义):
surface("book-table")
$/title="明晚 2 人,可选时段"
root=Card(col)
col=Column([title, slots, submit])
title=Text($/title)
slots=Row([t1, t2, t3])
t1_label=Text("18:00")
t1=Button(t1_label, _, Event("pick_time", {"time": "18:00"}))
t2_label=Text("20:30")
t2=Button(t2_label, _, Event("pick_time", {"time": "20:30"}))
t3_label=Text("21:00")
t3=Button(t3_label, _, Event("pick_time", {"time": "21:00"}))
submit_label=Text("确认预订")
submit=Button(submit_label, _, Event("book_table", {}))
和入门篇的 JSON 对照着看:
- JSON 里的
{ "id": "col", "component": "Column", "children": [...] }变成了col=Column([...]); - 键名、引号、花括号几乎全部消失;
- 结构完全等价,SDK 可以一对一地还原成 JSON。
3. 配合宏(Macro)使用
Python SDK 还支持宏。当界面要展示你系统里已有的数据时,模型只需要写一个带 ID 的调用,比如 OrderStatus("ord_42"),由你注册的宏去查询订单并填充具体数值。
笔者认为这个能力很实用:订单金额、物流状态这类数据不经过模型"复述",直接来自你的数据库,既省 Token,又避免了模型把数字写错。对于金融、电商这类对数据准确性要求高的场景,这一点很关键。
六、A2UI Express 评测数据:Token、有效率与四种推理格式对比
Google 团队对比了四种候选格式:
| 格式 | 风格 | 定位 |
|---|---|---|
| Direct JSON | 原生 JSON | 2025 年 12 月发布时的基线 |
| Express | 类 Python 赋值语句 | 最终选定的默认格式 |
| Atom | Lisp 风格 S 表达式,无赋值、无闭合标签 | 实验 |
| Elemental | 带自定义元素的 HTML | 实验,押注模型擅长写 HTML |
测试使用同一套 51 个任务的评测集,模型为 gemini-3.5-flash,分别在开启和关闭思考模式下运行。
关闭思考模式时的结果
| 格式 | 每个界面生成的 Token 数(中位数) | 编译为有效 A2UI 的比例 |
|---|---|---|
| Direct JSON | 958 | 96.1% |
| Express | 307 | 96.1% |
| Elemental | 503 | 92.2% |
| Atom | 468 | 21.6% |
几个值得注意的点:
- Express 的有效率与 JSON 相同(96.1%),Token 数只有约 1/3.1。
- Atom 虽然 Token 也少,但有效率只有 21.6%。 笔者的理解是,S 表达式依赖深层括号嵌套,而入门篇提到 A2UI 采用扁平列表正是为了避开深层嵌套。Atom 等于又走回了模型不擅长的路。
- Elemental(HTML 风格)表现中规中矩。 模型确实熟悉 HTML,但闭合标签本身就带来不少 Token 开销。
开启思考模式反而更差
原文还给出了一个反直觉的结果:对 Express 开启思考模式后,
- 每个界面额外增加了约 1,822 个推理 Token(中位数),总计约 2,087 个;
- 有效率反而从 96.1% 降到 87.8%。
也就是说,对于"按语法写界面"这种任务,让模型多想并没有带来帮助。官方建议:使用 Express 时关闭思考模式,以获得最快的推理速度。
设计灵感
原文提到 Express 部分受到开源项目 OpenUI 的语言 OpenUI Lang 的启发,后者同样采用 name = Component(...) 加位置参数的写法。两者目前还不能互通,OpenUI 团队已经在 issue #3214 中提议一起制定共享语法。
七、决策模型受控生成:用 Jev 让固定结构界面最高快 80 倍
Express 解决的是"让大模型更快地写出界面"。但有些界面其实根本不需要大模型来设计。
比如设置页、结账页、确认页,它们的结构基本固定。这时需要的不是"创作",而是"从预先定义好的几种布局里选一个"。
入门篇提到 A2UI 既支持"现场生成",也支持"当作模板再填数据"。决策模型方案可以看作两者的折中:结构由选择题决定,文字由小模型生成。
Jev:一个专做选择题的模型
原文介绍了 TypeSafe 公司的 Jev,属于所谓的 System One 模型。
名词解释:System One / System Two 的说法来自心理学家卡尼曼的《思考,快与慢》。System 1 指快速、直觉式的判断,System 2 指慢速、需要推理的思考。这里借用这个比喻:大模型逐字生成内容属于"慢思考",决策模型直接输出判断结果属于"快思考"。
Jev 的工作方式:
- 不生成文本,也不生成 JSON;
- 你给它一个状态和一组带类型的问题,它对每个问题给出校准过的概率;
- 问题类型包括:判断真假(Noul)、从选项中选一个(Choice)、按评分标准打分(Score);
- 一次请求可以回答很多问题,耗时约 100~300 毫秒。
Apparite:把决策模型接到 A2UI 上
开源设计工具 Apparite(jev2ui) 展示了一种组合方式:
- 问题预先写在一份 Markdown 语法文件里:引用块是问题,列表项是选项和判断标准;
- 例如设置页的每一行用什么控件,可以设计成一道选择题:开关(switch)、值选择(value)、跳转(nav)、单选(check)、危险操作(danger);
- 以一个播客 App 的设置页为例,Jev 判断"快进时长"是 value,"自动下载"是 switch,"退出登录"是 danger,置信度都接近 1.00。
生成一个界面分三步,正好对应入门篇介绍的三类消息:
| 步骤 | 做什么 | 发出的消息 |
|---|---|---|
| 1 | 一次 Jev 请求回答约 30 个布局问题 | 无 |
| 2 | 普通代码根据决策从组件目录拼出组件树,文字先用占位符,约 200 毫秒发出 | createSurface、updateComponents |
| 3 | 小模型 gemini-3.5-flash-lite 流式填写文字;文字到达后,再用少量 Jev 请求确定依赖文字的细节(比如每行的控件类型) | updateDataModel |
这里能清楚地看到入门篇所说的"组件与数据分离"的价值:界面骨架可以先上屏,内容随后填入,用户不用等整个界面生成完。
实测数据(样本较小,仅供参考)
在一组 11 个提示词的测试中:
- 组件树上屏时间:92~298 毫秒
- 完整界面完成时间:0.8~1.7 秒
- 文字模型每个界面只生成 101~341 个 Token
- 11 个提示词全部生成了有效的 A2UI
项目方也明确说明样本量小,这些数字只是初步结果。
局限
- 受控生成只能产出语法文件里描述过的布局。Apparite 目前覆盖 9 种界面原型和 12 种区块;
- A2UI 官方 SDK 还没有内置决策模型推理格式,Apparite 只是一个参考实现。
八、A2UI Express 与决策模型怎么选?选型对照表
| 场景 | 推荐方式 | 理由 |
|---|---|---|
| 界面结构固定、可以预先定义(设置页、结账页、确认页) | 决策模型受控生成 | 最快,模型只做选择题 |
| 界面需要根据需求灵活组合 | A2UI Express | 速度快,同时保留 A2UI 的完整表达能力 |
| 有特殊需求或想尝试新语法 | 自定义推理格式 | 只需写提示词生成器和编译器,目录和渲染器不用动 |
简单说:界面能提前定义多少,就决定了你能快多少。
九、A2UI Express 快速上手:SDK 安装与接入步骤
1. 在 Agent 中使用 Express
# Python
pip install a2ui-agent-sdk
# TypeScript
npm install @a2ui/agent
创建生成器时传入 ExpressFormatFactory(),并关闭模型的思考模式。组件目录和渲染器保持不变。如果你已经按入门篇接入了 A2UI,迁移成本主要就是这一处改动。
2. 把目录生成为 Skill
如果你使用 Gemini 或其他支持加载 Skill 的模型,可以用 Python SDK 的 SkillGenerator 根据组件目录生成 Skill,让模型学会只用你的组件写 Express(示意代码):
import json
from a2ui.core import Catalog
from a2ui.inference_formats.express import ExpressFormat
from a2ui.skill import SkillGenerator
with open("catalog.json", encoding="utf-8") as f:
catalog = Catalog.from_json(json.load(f))
skills = SkillGenerator(ExpressFormat([catalog])).generate_skillset()
skills.export_to_directory("skills") # 输出 a2ui-core 及每个目录对应的 Skill
3. 体验受控生成
克隆 jev2ui 示例仓库按说明运行,或者直接访问托管版本 apparite.cnfg.ai。
十、关于 A2UI Express 与生成式 UI 的几点思考
1. "模型写 DSL,代码负责编译"会成为常见模式
这次更新背后的思路很有普遍性:不要让大模型直接输出机器格式,让它输出一种对它友好的中间语言,再用确定性代码翻译。
这和前端开发者熟悉的 JSX 很像。开发者写 JSX,Babel 编译成 createElement 调用,没人手写后者。同样的道理也适用于 SQL 生成、配置文件生成、工作流编排等场景。如果你的 Agent 需要输出复杂的结构化数据,不妨评估一下能否设计一个更紧凑的 DSL。
2. Token 少三分之二,不只是快
Token 数直接对应三件事:延迟、成本、出错概率。输出从约 958 个 Token 降到约 307 个,对于高频调用的生成式 UI 场景,账单的变化会很明显。
3. 需要留意的权衡
结合原文信息,笔者认为有几点值得在落地前评估:
- 流式渲染:入门篇提到,A2UI 的扁平列表设计和 v0.9 SDK 的流式解析,让客户端可以边收边渲染。原文提到 Python 和 TypeScript SDK 可以逐块流式处理 Direct JSON,而 Express 需要等完整回复后再编译。也就是说,Express 总耗时更短,但在当前版本中可能没法边生成边渲染。对于很长的界面,首屏体验需要实测对比。
- 位置参数依赖 Schema 顺序:Express 按目录 Schema 声明的属性顺序映射参数。笔者推测,如果团队调整了目录中属性的顺序,模型的输出习惯和编译结果之间可能出现偏差。由于 few-shot 示例以 A2UI JSON 编写、由 SDK 转换,这个风险应该比较可控,但仍建议把目录变更纳入回归测试。
- 评测范围:数据基于 gemini-3.5-flash 和 51 个任务。换用其他模型或更复杂的业务界面时,结果可能不同,建议用自己的场景跑一遍。
4. 生成式 UI 正在走向"分层"
把这次更新放在更大的背景下看,生成式 UI 的架构正在分层:
- 决策层:快速模型判断"用什么结构";
- 内容层:小模型填写文字;
- 创作层:大模型处理真正需要设计的新界面;
- 执行层:确定性代码负责编译、校验和渲染。
不同层用不同的模型,按需组合。入门篇说前端的角色会从"做菜的人"变成"设计菜单和厨房的人";这一篇则说明,Agent 开发者也要开始考虑"哪道菜交给哪个厨师"。对于做 Agent 产品的团队来说,"什么时候该用大模型,什么时候不该用"可能比"用哪个大模型"更值得花时间想清楚。
总结
| 要点 | 内容 |
|---|---|
| 瓶颈在哪 | 大模型逐 Token 生成 A2UI 消息的那一步 |
| 推理格式可替换 | 模型输出格式与传输格式分离,SDK 负责编译,渲染器不变 |
| A2UI Express | 类 Python 语法,Token 约为 JSON 的 1/3,有效率持平,建议关闭思考模式 |
| 决策模型 | 固定结构界面做选择题,骨架几百毫秒上屏,小模型只填文字 |
| 选型原则 | 界面能提前定义多少,就能快多少 |
常见问题 FAQ
Q1:A2UI Express 是什么?
A2UI Express 是 Google A2UI 协议新增的一种推理格式(inference format),一种类似 Python 的简洁语法。大模型生成 Express,再由 A2UI 的 Agent SDK 用确定性代码编译成标准的 A2UI JSON 消息。它的目的是减少大模型生成界面时的 Token 消耗、降低延迟、提高准确率。
Q2:A2UI Express 能节省多少 Token?能快多少?
按官方在 gemini-3.5-flash 上的评测,生成同类界面时,Express 每个界面约 307 个 Token,Direct JSON 约 958 个,大约是 1/3;有效率两者相同(96.1%)。官方称延迟最多可降低约 3 倍。
Q3:A2UI Express 和直接写 JSON 有什么区别?
Express 把 JSON 里的键名、引号、花括号几乎全部省掉,用"变量名=组件(参数)"的一行式写法表达同样的组件树,结构完全等价,可以被 SDK 一对一地编译回 JSON。渲染器和组件目录都不用改。
Q4:什么时候该用决策模型而不是 Express?
当界面结构固定(如设置页、结账页、确认页)时,用 Jev 这类决策模型做"选择题"更快,官方称最高可快约 80 倍。当界面需要灵活组合时,用 Express 保留完整表达能力。简单说:界面能提前定义多少,就能快多少。
Q5:使用 A2UI Express 需要开启大模型的思考模式吗?
不需要。评测显示,对 Express 开启思考模式后,有效率反而从 96.1% 降到 87.8%,还多出约 1,822 个推理 Token。官方建议使用 Express 时关闭思考模式,以获得最快的推理速度。
Q6:如何安装和使用 A2UI Express?
Python 用 pip install a2ui-agent-sdk,TypeScript 用 npm install @a2ui/agent,创建生成器时传入 ExpressFormatFactory() 并关闭思考模式即可。组件目录和渲染器保持不变。
参考资料
- 入门篇:《从聊天框到动态界面:一文看懂生成式 UI 与 Google A2UI》
- 本文主要参考:Fast, reliable A2UI, with swappable inference formats(Google Developers Blog,2026-10-27)
- Introducing A2UI: An open project for agent-driven interfaces(2025-12-15)
- A2UI v0.9: The New Standard for Portable, Framework-Agnostic Generative UI(2026-04-17)
- A2UI Express 规范
- a2ui-agent-sdk 更新日志、Jev 文档、Apparite(jev2ui)README,均可从原文末尾的链接找到
声明:本文为对公开资料的学习与评论,数据引用自原文,原文版权归 Google 所有;内容经重新组织和改写,示例代码为笔者编写的示意代码或基于开源 SDK 的标准调用方式。如有理解偏差,欢迎评论区指正。
如果这篇文章对你有帮助,欢迎点赞、收藏、关注,有问题请在评论区留言交流。
568



被折叠的 条评论
为什么被折叠?



