A2UI Express DSL 端到端生成实例全解析:从系统提示词契约到编译后的 A2UI v1.0 JSON

发布时间:2026/9/15 6:37:54
A2UI Express DSL 端到端生成实例全解析:从系统提示词契约到编译后的 A2UI v1.0 JSON A2UI Express DSL 端到端生成实例全解析从系统提示词契约到编译后的 A2UI v1.0 JSON【免费下载链接】a2ui项目地址: https://gitcode.com/GitHub_Trending/a2/a2ui本文基于 A2UI 仓库中 A2UI Express DSL 基线评估运行的一次完整端到端追踪记录展开从注入模型的系统提示词契约布局规则、语法格式与枚举定义、用户请求、模型产出的原始 Express DSL到宿主编译器最终编译出的标准 A2UI v1.0 JSON 布局。读完本文你将掌握 A2UI Express 的完整语法契约、位置参数组件与函数签名、数据绑定与校验写法以及如何通过仓库提供的命令行工具将.a2ui文件编译为可下发的标准协议载荷并亲自复现这一流程。1. 什么是 A2UI Express DSLA2UI Express 是一种面向生成式 UI 场景的紧凑、省 token 的声明式语法作为大模型如 Gemini、Gemma生成 UI 的中间表示。宿主编译器解析该语法后会将其编译为标准 A2UI v1.0 线上协议载荷wire payload再发送给客户端渲染。据 A2UI Express 技术规格 所述其核心设计目标包括Token 足迹缩减相比原生 A2UI 线载荷可减少约 55%70% 的输出 token消除结构键、括号和重复引号端侧模型优化面向上下文窗口与推理预算受限的小型本地模型设计位置签名可干净地嵌入提示词契约流式兼容面向行的文法允许宿主逐行解析并渐进渲染界面协议对齐与标准 A2UI v1.0 保持完整语义兼容支持数据绑定、客户端校验规则与本地事件处理。本文所基于的 express_dsl_examples.md 记录了该流程的一次真实完整链路是理解这套语法与编译管线的最佳入口。2. 完整输入提示词系统提示词契约System Prompt在下文的基线评估中以下系统提示词被注入模型。它由两部分构成语法规则Grammar Rules与位置组件/函数签名Positional Signatures。提示词契约由仓库中的ExpressPromptGenerator依据已加载的目录 schema 动态生成见 prompt_generator.py并非手工编写。2.1 语法规则Grammar Rules模型必须遵守以下 15 条规则组件构造组件构造器可赋给变量也可内联嵌套在父组件参数中header ComponentA(prop1val1) root ComponentB([header, ComponentC(Click, actionEvent(submit))])支持关键字参数paramvalue与带_占位符的位置参数。变量名必须以字母或下划线开头仅可包含字母、数字与下划线。单一入口界面树必须有唯一入口赋给保留变量root。基本类型字符串用或包裹支持\n、\t、\\、\转义以r前缀表示原始字符串如r...、r...不做转义处理数字整数或小数如42布尔true/false空值null日期时间日期时间输入如DateTimeInput的值必须严格使用带时区偏移的 RFC 3339 格式如2026-03-14T00:00:00Z。列表用数组表示如[child1, child2]。映射用键值块表示如{title: Overview, child: contentCol}。映射键始终是字面字符串键不支持动态变量解析。数据绑定数据模型中的绝对路径以$为前缀如$/user/firstName相对列表作用域同样以$为前缀如$firstName单独的$表示空相对路径解析为当前上下文的根例如在模板中表示条目自身。逻辑与校验客户端检查规则以?为前缀如?required或?regex(^[0-9]{5}$)如需自定义校验失败错误信息追加一个额外字符串参数如?regex(^[0-9]{5}$, Postal code must be 5 digits)。动作事件服务端动作使用Event辅助器表示如Event(save_deal, {rep: $/form/rep})。嵌套函数直接按目录签名调用客户端函数如myFunction(value)。数据模型填充直接将值赋给绝对数据路径如$/path/to/key value即可填充共享 dataModel 中的值值可以是基本类型、数组或映射。动态列表模板若组件期望模板子列表使用_template辅助器_template($/path/to/list, itemTemplate)模板组件变量定义在另一行使用$前缀的相对路径引用如itemTemplate Image($url)删除界面输出独立的deleteSurface(surfaceId)命令无需变量赋值deleteSurface(dashboard-surface-1)静态属性签名中标注(static)的参数必须以字面值或数组内联定义不能使用$前缀的动态数据绑定路径。必需动作名为action或组件签名中标注的参数是严格必需的必须传合法的Event如Event(click)或函数调用若用户请求未描述具体动作也必须提供Event(click)之类的占位点击事件而非传null或省略该参数。表面Surface定位输出surface(surfaceId)指定目标界面表面surface(dashboard-surface-1) root Card(...)2.2 位置组件签名Positional Component Signatures模型被要求严格按下列位置签名实例化组件不得输出属性键名组件位置签名关键参数说明AudioPlayerAudioPlayer(url, description?, weight? (static))url音频地址description标题或摘要weight在 Row/Column 中的相对权重类似 CSSflex-grow仅当为 Row/Column 直接子级时可用ButtonButton(child (static), variant? (static), action (static), weight? (static), checks? (static))child子组件 ID带文字的按钮用Text仅当需求明确要求图标按钮时用Iconvariant取值default / primary / borderlessprimary为主 CTAborderless无边框背景形似链接CardCard(child (static), weight? (static))child单一子组件 ID多元素必须先用 Column/Row 包裹后传入容器 IDCheckBoxCheckBox(label, value, weight? (static), checks? (static))value当前状态true/falseChoicePickerChoicePicker(label?, variant? (static), options (static), value, displayStyle? (static), filterable? (static), weight? (static), checks? (static))variant取值multipleSelection / mutuallyExclusiveoptions为映射列表键label显示文本、value稳定值displayStyle取值checkbox / chipsfilterable为 true 时显示搜索过滤框ColumnColumn(children, justify? (static), align? (static), weight? (static))垂直布局children为字符串数组固定子集或模板对象justify取值start / center / end / spaceBetween / spaceAround / spaceEvenly / stretchalign取值center / end / start / stretchDateTimeInputDateTimeInput(value, enableDate? (static), enableTime? (static), min?, max?, label?, weight? (static), checks? (static))value为 ISO 8601 格式的日期/时间未设置时初始化为空字符串min/max为 ISO 8601 上下限DividerDivider(axis? (static), weight? (static))axis取值horizontal / verticalIconIcon(name, weight? (static))name从受控图标枚举中取值accountCircle / add / arrowBack / arrowForward / attachFile / calendarToday / call / camera / check / close / delete / download / edit / event / error / fastForward / favorite / favoriteOff / folder / help / home / info / locationOn / lock / lockOpen / mail / menu / moreVert / moreHoriz / notificationsOff / notifications / pause / payment / person / phone / photo / play / print / refresh / rewind / search / send / settings / share / shoppingCart / skipNext / skipPrevious / star / starHalf / starOff / stop / upload / visibility / visibilityOff / volumeDown / volumeMute / volumeOff / volumeUp / warningImageImage(url, description?, fit? (static), variant? (static), weight? (static))fit对应 CSSobject-fit取值contain / cover / fill / none / scaleDownvariant取值icon / avatar / smallFeature / mediumFeature / largeFeature / headerListList(children, direction? (static), align? (static), weight? (static))direction取值vertical / horizontalalign取值start / center / end / stretchModalModal(trigger (static), content (static), weight? (static))trigger为触发模态打开组件的 IDcontent为模态内展示组件的 IDRowRow(children, justify? (static), align? (static), weight? (static))水平布局justify取值center / end / spaceAround / spaceBetween / spaceEvenly / start / stretchalign跨轴垂直取值start / center / end / stretch使用 camelCase 值SliderSlider(label?, min? (static), max (static), value, steps? (static), weight? (static), checks? (static))steps为离散分档数指定后滑块吸附到离散值TabsTabs(tabs (static), weight? (static))tabs为对象数组每项含title标签标题与child子组件 IDTextText(text, variant? (static), weight? (static))支持简单 Markdown 格式不含 HTML、图片与链接variant取值caption / bodyTextFieldTextField(label, value?, placeholder?, variant? (static), weight? (static), checks? (static))variant取值longText / number / shortText / obscured如密码框VideoVideo(url, posterUrl?, weight? (static))posterUrl为播放前展示的海报图 URL2.3 位置函数签名Positional Function Signatures校验规则与逻辑函数同样以位置签名注入and(values)对布尔值列表执行逻辑与。email(value)校验是否为合法邮箱地址。formatCurrency(value, currency, decimals?, grouping?)将数字格式化为货币字符串。formatDate(value, format)按模式将时间戳格式化为字符串。formatNumber(value, decimals?, grouping?)按分组与小数精度格式化数字。formatString(value)对数据模型值与函数列表中的其他函数做字符串插值。值字符串可包含${expression}形式的插值表达式支持 JSON Pointer 路径如${/absolute/path}或${relative/path}与渲染端函数调用如${now()}函数参数必须命名如${formatDate(value:${/currentDate}, format:MM-dd)}字面${需转义为\${。length(value, min?, max?)校验字符串长度约束。not(value)对布尔值执行逻辑非。numeric(value, min?, max?)校验数值范围约束。openUrl(url)在浏览器或处理程序中打开指定 URL无返回值。or(values)对布尔值列表执行逻辑或。pluralize(value, zero?, one?, two?, few?, many?, other)基于 CLDR 复数类别返回本地化字符串必须提供other兜底英语一般只需one与other。regex(value, pattern)校验值是否匹配正则字符串。required(value)校验值非 null、非 undefined、非空。2.4 Catalog 说明与指南Catalog Instructions Guidelines布局使用Row与Column组件组织其他组件。字符串拼接与格式化A2UI不支持之类的二元运算符或格式化符号拼接字符串或动态注入数据绑定必须使用目录函数formatString(value)其中值字符串以${expression}作为占位符formatString(Hello ${/user/name})严格层级必须严格遵守请求的组件嵌套与层级若提示词指定某组件“位于/包含于”另一组件内必须将其作为该组件的子级而非兄弟节点或其他容器。校验提示组件支持校验时自定义错误信息直接写在 check 的message中不要创建单独的文本展示组件显示校验错误。3. 用户请求User Request在提示词契约之后模型收到如下用户输入Translate the following request into A2UI Express DSL wrapped insidea2uiand/a2uisentinels:Generate a single createSurface message with components inline with surfaceId main for a weather forecast UI. It should have a Text with the city name, New York. Below it, a Row with the current temperature as a Text component (68°F) and an Image for the weather icon (e.g., a sun). Below that, a Divider. Then, a List component to display the 5-day forecast. Each item in the list should be a Row with the day, an icon, and high/low temperatures.REMINDER: You must output ONLY A2UI Express DSL wrapped ina2uiand/a2uisentinels. Do NOT output JSON ora2ui-jsonblocks under any circumstances. Directly generating JSON will fail compilation.这是一个标准的自然语言 → 生成式 UI任务城市名文本、当前温度行温度文本 天气图标图片、分割线、以及 5 天预报列表每天一行星期、图标、高低温。4. 模型原始输出A2UI Express DSL模型被要求用紧凑的 Express DSL 输出 UI整体包裹在a2ui与/a2ui哨兵标签内。本次评估的真实输出如下a2ui $/forecast [{day: Monday, icon: https://img.icons8.com/color/48/000000/sun.png, temp: 72°F / 55°F}, {day: Tuesday, icon: https://img.icons8.com/color/48/000000/partly-cloudy-day.png, temp: 68°F / 50°F}, {day: Wednesday, icon: https://img.icons8.com/color/48/000000/rain.png, temp: 60°F / 48°F}, {day: Thursday, icon: https://img.icons8.com/color/48/000000/partly-cloudy-day.png, temp: 65°F / 52°F}, {day: Friday, icon: https://img.icons8.com/color/48/000000/sun.png, temp: 70°F / 54°F}] root Column([cityName, currentRow, divider, forecastList]) cityName Text(New York) currentRow Row([currentTemp, currentIcon], center, center) currentTemp Text(68°F) currentIcon Image(https://img.icons8.com/color/96/000000/sun.png, Sunny) divider Divider(horizontal) forecastList List(_template($/forecast, forecastItem), vertical) forecastItem Row([itemDay, itemIcon, itemTemp], spaceBetween, center) itemDay Text($day) itemIcon Image($icon, Weather icon) itemTemp Text($temp) /a2ui这段输出展示了 Express DSL 的核心表达力值得逐行解读数据模型填充规则 10$/forecast [...]直接在共享 dataModel 中初始化 5 天预报数组映射列表形式单一入口规则 2root Column(...)作为界面树唯一入口位置参数Text(New York)、Divider(horizontal)、Image(url, Sunny)均按目录签名顺序传参不写属性键布局语义currentRow Row([...], center, center)分别对应children、justify、align动态列表模板规则 11forecastList List(_template($/forecast, forecastItem), vertical)将$/forecast数据列表与forecastItem模板组件绑定forecastItem内部用相对路径$day、$icon、$temp引用列表条目字段规则 6。顺带一提仓库 examples 目录 中还存在一份同主题的 04_weather-current.a2ui它展示了同样的天气场景如何用函数辅助formatString、formatDate与嵌套模板写出更丰富的形式可对照阅读。5. 编译后的标准 A2UI v1.0 布局载荷A2UI Express 编译器解析上述紧凑 DSL 后动态生成组件 ID、构建父子引用链、将位置参数按目录 schema 解析形成标准 A2UI v1.0 的createSurface消息结构[ { version: v1.0, createSurface: { surfaceId: main, catalogId: https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json, components: [ { id: root, component: Column, children: [cityName, currentRow, divider, forecastList] }, { id: cityName, component: Text, text: New York }, { id: currentRow, component: Row, children: [currentTemp, currentIcon], justify: center, align: center }, { id: currentTemp, component: Text, text: 68\u00b0F }, { id: currentIcon, component: Image, url: https://img.icons8.com/color/96/000000/sun.png, description: Sunny }, { id: divider, component: Divider, axis: horizontal }, { id: forecastList, component: List, children: { path: /forecast, componentId: forecastItem }, direction: vertical }, { id: forecastItem, component: Row, children: [itemDay, itemIcon, itemTemp], justify: spaceBetween, align: center }, { id: itemDay, component: Text, text: { path: day } }, { id: itemIcon, component: Image, url: { path: icon }, description: Weather icon }, { id: itemTemp, component: Text, text: { path: temp } } ], dataModel: { forecast: [ { day: Monday, icon: https://img.icons8.com/color/48/000000/sun.png, temp: 72\u00b0F / 55\u00b0F }, { day: Tuesday, icon: https://img.icons8.com/color/48/000000/partly-cloudy-day.png, temp: 68\u00b0F / 50\u00b0F }, { day: Wednesday, icon: https://img.icons8.com/color/48/000000/rain.png, temp: 60\u00b0F / 48\u00b0F }, { day: Thursday, icon: https://img.icons8.com/color/48/000000/partly-cloudy-day.png, temp: 65\u00b0F / 52\u00b0F }, { day: Friday, icon: https://img.icons8.com/color/48/000000/sun.png, temp: 70\u00b0F / 54\u00b0F } ] } } } ]对比 DSL 与编译结果可以清楚看到几条关键映射规律扁平化邻接表DSL 中的每个变量对应组件数组中的一个条目嵌套关系由children数组中的 ID 引用表达标准 A2UI v1.0 要求扁平组件数组模板展开_template($/forecast, forecastItem)被编译为children: {path: /forecast, componentId: forecastItem}的模板对象绑定路径规范化绝对路径$/forecast变为/forecast模板内的相对路径$day变为{path: day}数据模型抽取$/forecast [...]赋值被抽取为载荷顶层的dataModel对象。6. 编译原理与源码佐证6.1 编译管线据 A2UI Express 技术规格编译在推理管线中执行将 A2UI Express 纯文本流处理为标准 A2UI v1.0 JSONPlain text stream → Lexer and line parser → Abstract syntax tree → Schema mapper → AST flattener → Standard A2UI v1.0 JSON对应地核心实现位于 compiler.py 中的ExpressCompiler类见 compiler.py 第 181 行它依赖 ANTLR 生成的词法/语法分析器ExpressLexer、ExpressParser文法定义在 Express.g4与ExpressAstVisitor完成解析与 AST 构建。6.2 关键机制Schema 驱动的键映射因为 Express 省略了属性键编译器完全依赖已加载目录的 JSON schema 将位置参数按属性声明顺序逐一映射尾部可选参数可省略跳过中间可选参数用_占位。例如Column(children, justify?, align?)中Column([icon, title], _, center)会把数组映射到children、center映射到alignjustify保持未指定。编译器源码中的_set_nested_path见 compiler.py 第 44-68 行还展示了$/path/to/key value如何被解析成嵌套 dataModel 字典。静态属性约束签名中标注(static)的参数禁止动态绑定编译期的_schema_allows_databinding/_has_databinding见 compiler.py 第 71-117 行负责递归检测属性 schema 是否允许 DataBinding 引用从而强制执行规则 13。错误恢复与微调循环当编译遇到语法错误或目录 schema 不匹配时会触发结构化恢复流程——隔离出错行并丢弃该 AST 子分支将其与目标组件签名、解析器错误信息打包成微型修正提示词交给快速基础模型修正后热替换回活跃 AST避免整个界面坍缩。协议信封构造编译结果按需包裹为createSurface含surfaceId、catalogId、components、dataModel、surfaceParams或updateComponents、updateDataModel、deleteSurface、callFunction等标准消息省略surface()时回退到默认表面 IDdefault_surface。6.3 目录无关性编译器不硬编码任何组件名、函数签名或属性假设。宿主启动时注册目标目录的 JSON schema提示词生成工具把 schema 编译成位置签名注入系统提示词解析器按加载的 schema 结构动态映射参数——这意味着更换自定义目录后系统无需任何手工更新即可适配。7. 更多实战示例从仓库 examples 目录深入学习为了进一步印证语法契约的通用性仓库 examples 目录 提供了 36 个覆盖各种场景的.a2ui示例以下三个与上文规则直接对应航班状态卡01_flight-status.a2ui——演示绝对路径填充、formatDate与formatString插值、Divider()无参调用$/flightNumber OS 87 $/origin Vienna root Card(main_column) main_column Column([header_row, route_row, divider, times_row], _, stretch) date Text(formatDate($/date, E, MMM d), caption) origin Text(formatString(## ${/origin})) divider Divider() departure_time Text(formatDate($/departureTime, h:mm a))登录表单09_login-form.a2ui——演示校验规则?required、?email、?length、占位事件、and聚合校验与Event服务端动作$/email $/password email_field TextField(Email, $/email, [?required(Email is required), ?email(Please enter a valid email address)]) password_field TextField(Password, $/password, _, obscured, [?required(Password is required), ?length(8, Password must be at least 8 characters long)]) login_btn Button(login_btn_text, _, Event(login, {email: $/email}), ?and([email($/email), length($/password, 8)], Please fix errors before signing in))注意这里TextField第三个位置参数placeholder用_跳过第四个参数直接传obscuredvariant正是跳过中间可选参数用_占位规则的活用例。高级表单校验32_advanced-form-validator.a2ui——演示原始字符串正则?regex(r^\?[0-9]{10,15}$, ...)、or聚合、布尔数据绑定与嵌套函数调用插值$/formData/zip welcome_text Text(formatString(Hello! Today is ${formatDate(value: ${/now}, format: EEEE, MMMM d)}.)) phone_field TextField(Phone Number, $/formData/phone, ?regex(r^\?[0-9]{10,15}$, Invalid phone format)) submit_btn Button(submit_btn_text, _, Event(register, {data: $/formData}), ?and([$/formData/agree, or([required($/formData/email), required($/formData/phone)]), required($/formData/zip)], You must agree to terms AND provide either Email or Phone, plus a Zip code.))8. 亲手复现CLI 工具与运行流程所有 A2UI Express 代码导入与命令行工具都受环境变量A2UI_EXPRESS_ENABLED门控防止污染稳定的 v1.0 基线工作区所有 Python 命令调用前都必须加A2UI_EXPRESS_ENABLEDtrue前缀。详细说明见 Express 开发者指南。8.1 离线编译 DSLrun_compiler.py将.a2ui文件直接编译为标准 v1.0 JSON源码见 run_compiler.pycd specification/proposals/express A2UI_EXPRESS_ENABLEDtrue uv run --project ../../../agent_sdks/python/a2ui_agent scripts/run_compiler.py \ examples/04_weather-current.a2ui \ --surface-id weather_surface关键参数dsl_file位置参数待编译的 A2UI Express DSL 文件路径--surface-id编译表面的唯一 ID默认express_surface--catalog-id输出中引用的可选目录 URI默认空--catalog目录 JSON schema 路径默认指向 basic 目录。编译过程内部通过Catalog.from_json(catalog_dict, spec_version0.9.1)加载目录详见 run_compiler.py 第 76-78 行再由ExpressCompiler.compile()产出消息列表并打印为格式化 JSON。8.2 远程模型推理与校验run_inference.py用标准 Gemini 模型如gemini-3.1-flash-lite做JSON 示例 → Express DSL → 回编译校验的完整评估源码见 run_inference.pyexport GEMINI_API_KEYyour_gemini_api_key_here cd specification/proposals/express A2UI_EXPRESS_ENABLEDtrue uv run --project ../../../agent_sdks/python/a2ui_agent scripts/run_inference.py \ ../../v1_0/catalogs/basic/examples/01_flight-status.json \ --model gemini-3.1-flash-lite该脚本依次从 JSON 示例提取目标组件列表 → 把活跃目录 schema 编译为纯文本位置签名 → 以提示词契约作为系统指令查询 Gemini API低温 0.1 保证确定性输出→ 将返回的 Express DSL 回编译为标准 v1.0 JSON → 校验组件树结构、父子引用与数据指针路径。它还支持--local本地 Ollama默认localhost:11434与--mlx本地 Apple MLX-LM默认localhost:8080两种本地推理模式。8.3 其他工具提示词生成器run_prompt_generator.py生成包含位置组件签名与规则的模型提示词契约A2UI_EXPRESS_ENABLEDtrue uv run --project ../../../agent_sdks/python/a2ui_agent scripts/run_prompt_generator.py --catalog ../../v1_0/catalogs/basic/catalog.json反向解编译器run_decompiler.py将标准 A2UI v1.0 JSON 信封还原为紧凑 Express 代码A2UI_EXPRESS_ENABLEDtrue uv run --project ../../../agent_sdks/python/a2ui_agent scripts/run_decompiler.py ../../v1_0/catalogs/basic/examples/01_flight-status.json文档再生成recreate_dsl_examples.py直接从活跃代码重新生成本文所基于的 express_dsl_examples.md含系统提示词契约与天气示例A2UI_EXPRESS_ENABLEDtrue uv run --project ../../../agent_sdks/python/a2ui_agent scripts/recreate_dsl_examples.py9. 小结一次端到端的 A2UI Express 生成示例完整展示了其核心价值模型只需要输出极简的、以变量赋值与位置参数构成的 DSL 文本外层包裹a2ui哨兵宿主编译器即可借助目录 schema 完成位置参数 → 属性键映射、扁平化邻接表构建、数据模型抽取与协议信封封装最终得到标准 A2UI v1.0 的createSurface消息。掌握这套语法契约——尤其是 15 条语法规则、组件/函数位置签名、$数据绑定与?校验前缀、_template动态模板与Event事件辅助器——你就能读懂 examples 目录 中的全部示例并通过 run_compiler.py 与 run_inference.py 亲手复现从 DSL 到协议 JSON 的完整编译链路。【免费下载链接】a2ui项目地址: https://gitcode.com/GitHub_Trending/a2/a2ui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考