关于 a2ui
A2UI Development Skill 指导开发者编写符合 A2UI v0.8 协议的代码,让 AI Agent 向客户端流式传送交互界面,涵盖消息结构、数据绑定、组件与用户事件。
主要功能
- 01生成 A2UI v0.8 消息
- 02以扁平组件列表和 ID 引用组织界面
- 03通过 JSON Pointer 路径绑定数据
- 04使用标准布局、展示和输入组件
- 05处理用户操作与错误消息
适用场景
- 01为 Agent 创建交互式表单
- 02将界面字段绑定到应用状态
- 03构建多表面或渐进式渲染流程
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kobe4cn/ a2ui_skills --skill a2ui安装后在 Claude Code 中输入/a2ui确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdexamples/modal.mdform.mdmulti-surface.mdstreaming.mdbooking-flow.mdlist.mdreference/api-integration.mdagent-prompting.mdcatalog-negotiation.mdcomponents.mdstreaming.mddata-binding.mdschema.mdsurfaces.md详细介绍
A2UI 开发技能
此技能可帮助你生成符合 A2UI(Agent to UI)协议的代码,以构建丰富、交互式的用户界面,供 AI Agent 流式传输到客户端。
协议版本
此技能面向 A2UI Protocol v0.8(稳定版)。
标准目录 ID:https://github.com/google/A2UI/blob/main/specification/0.8/json/standard_catalog_definition.json
核心概念
1. 消息类型
A2UI 在 JSONL 流中使用四种消息类型:
| 消息 | 用途 |
|---|---|
surfaceUpdate | 定义或更新 UI 组件 |
dataModelUpdate | 填充或更新应用状态 |
beginRendering | 通知客户端开始渲染 |
deleteSurface | 移除 UI 界面 |
2. 邻接列表模型
组件以带 ID 引用的扁平列表形式定义,而不是嵌套树:
{"surfaceUpdate": {"surfaceId": "main", "components": [
{"id": "root", "component": {"Column": {"children": {"explicitList": ["header", "content"]}}}},
{"id": "header", "component": {"Text": {"text": {"literalString": "Welcome"}, "usageHint": "h1"}}},
{"id": "content", "component": {"Text": {"text": {"path": "/user/name"}}}}
]}}
3. 数据绑定(BoundValue)
值绑定有三种模式:
// Literal only - static value
{"literalString": "Hello"}
// Path only - dynamic from data model
{"path": "/user/name"}
// Both - initialization shorthand (sets default AND binds)
{"path": "/form/email", "literalString": "[email protected]"}
4. 样式配置
在 beginRendering 中自定义外观:
{"beginRendering": {
"surfaceId": "main",
"root": "root",
"styles": {
"font": "Roboto",
"primaryColor": "#1976D2"
}
}}
| 属性 | 描述 |
|---|---|
font | 主要字体系列 |
primaryColor | 主题颜色(十六进制格式 #RRGGBB) |
标准目录组件
布局组件
Row- 水平容器,支持distribution和alignmentColumn- 垂直容器,支持distribution和alignmentList- 可滚动列表,支持direction(垂直/水平)Card- 带有单个child的 Material 卡片容器Tabs- 选项卡导航,带有tabItems数组Modal- 对话框,带有entryPointChild和contentChildDivider- 分隔线,支持axis(水平/垂直)
显示组件
Text- 文本显示,支持usageHint(h1-h5、caption、body)。支持简单 Markdown。Image- 图片,支持url、fit、usageHintIcon- 标准图标集中的图标(参见组件参考)Video- 视频播放器,支持urlAudioPlayer- 音频播放器,支持url和description
输入组件
Button- 可点击组件,带有child和actionTextField- 文本输入,带有label、textFieldTypeCheckBox- 切换组件,带有label和valueDateTimeInput- 日期/时间选择器,支持enableDate/enableTimeMultipleChoice- 选择组件,带有options和maxAllowedSelectionsSlider- 范围输入,支持minValue/maxValue
组件权重
在 Row/Column 内的组件上使用 weight 实现弹性布局:
{"id": "sidebar", "weight": 1, "component": {"Column": {...}}},
{"id": "main", "weight": 3, "component": {"Column": {...}}}
生成 A2UI 消息
基本流程
- 通过
surfaceUpdate定义组件 - 通过
dataModelUpdate填充数据 - 通过
beginRendering触发渲染
完整示例:简单表单
{"surfaceUpdate": {"surfaceId": "booking", "components": [
{"id": "root", "component": {"Column": {"children": {"explicitList": ["title", "name_field", "date_field", "submit_btn"]}}}},
{"id": "title", "component": {"Text": {"text": {"literalString": "Book a Table"}, "usageHint": "h2"}}},
{"id": "name_field", "component": {"TextField": {"label": {"literalString": "Your Name"}, "text": {"path": "/form/name"}}}},
{"id": "date_field", "component": {"DateTimeInput": {"value": {"path": "/form/date"}, "enableDate": true}}},
{"id": "submit_btn", "component": {"Button": {"child": "submit_text", "action": {"name": "submit_booking", "context": [{"key": "name", "value": {"path": "/form/name"}}, {"key": "date", "value": {"path": "/form/date"}}]}}}},
{"id": "submit_text", "component": {"Text": {"text": {"literalString": "Confirm Booking"}}}}
]}}
{"dataModelUpdate": {"surfaceId": "booking", "contents": [{"key": "form", "valueMap": [{"key": "name", "valueString": ""}, {"key": "date", "valueString": ""}]}]}}
{"beginRendering": {"surfaceId": "booking", "root": "root"}}
事件处理
用户操作
用户进行交互(例如点击按钮)时,客户端会发送 userAction:
{
"userAction": {
"name": "submit_booking",
"surfaceId": "booking",
"sourceComponentId": "submit_btn",
"timestamp": "2025-01-01T10:00:00Z",
"context": {"name": "John Doe", "date": "2025-01-15"}
}
}
错误报告
客户端通过 error 消息报告错误:
{
"error": {
"type": "RENDER_ERROR",
"message": "Component 'user_card' references missing child",
"surfaceId": "main",
"componentId": "user_card",
"timestamp": "2025-01-01T10:30:05Z"
}
}
最佳实践
- 唯一 ID:每个组件在其界面内都需要唯一的
id - 扁平结构:使用 ID 引用表示父子关系
- 数据分离:将 UI 结构放在
surfaceUpdate中,将动态值放在dataModelUpdate中 - 路径约定:路径使用 JSON Pointer 格式(例如
/user/profile/name) - 渐进式渲染:定义好必要组件后发送
beginRendering - 清理界面:流程完成后使用
deleteSurface
参考文档
核心参考
高级主题
示例
基础模式
高级模式
评论
支持 Markdown