导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

算法

UI、组件库

Node

业务技能

针对性攻坚

公共类

基础设施

AI


基本介绍

核心概念

架构

Agent (LLM) → A2UI Generator → Transport (SSE/WS/A2A)
                                      ↓
Client (Stream Reader) → Message Parser → Renderer → Native UI

image.png

消息格式

A2UI 定义了一系列描述用户界面的 JSON 消息。在流式传输时,这些消息通常格式为 JSON 行(JSONL), 每行是一个完整的 JSON 对象。

{
  "version": "v0.9",
  "createSurface": {
    "surfaceId": "main",
    "catalogId": "<https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json>"
  }
}
{
  "version": "v0.9",
  "updateComponents": {
    "surfaceId": "main",
    "components": [...]
  }
}
{
  "version": "v0.9",
  "updateDataModel": {
    "surfaceId": "main",
    "path": "/user",
    "value": { "name": "Alice" }
  }
}

生命周期示例:餐厅预订

创建 surface

{
  "version": "v0.9",
  "createSurface": {
    "surfaceId": "booking",
    "catalogId": "<https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json>"
  }
}

定义界面结构

{
  "version": "v0.9",
  "updateComponents": {
    "surfaceId": "booking",
    "components": [
      {
        "id": "root",
        "component": "Column",
        "children": ["header", "guests-field", "submit-btn"]
      },
      {
        "id": "header",
        "component": "Text",
        "text": "Confirm Reservation",
        "variant": "h1"
      },
      {
        "id": "guests-field",
        "component": "TextField",
        "label": "Guests",
        "value": { "path": "/reservation/guests" }
      },
      {
        "id": "submit-btn",
        "component": "Button",
        "child": "submit-text",
        "variant": "primary",
        "action": {
          "event": {
            "name": "confirm",
            "context": {
              "details": { "path": "/reservation" }
            }
          }
        }
      }
    ]
  }
}

填充数据

{
  "version": "v0.9",
  "updateDataModel": {
    "surfaceId": "booking",
    "path": "/reservation",
    "value": {
      "datetime": "2025-12-16T19:00:00Z",
      "guests": "2"
    }
  }
}

用户将访客编辑为“3”

客户端自动更新 /reservation/guests

**用户点击“确认”**→客户端发送操作:

{
  "version": "v0.9",
  "action": {
    "name": "confirm",
    "surfaceId": "booking",
    "context": {
      "details": {
        "datetime": "2025-12-16T19:00:00Z",
        "guests": "3"
      }
    }
  }
}

代理响应 →更新 UI 或发送:

{
  "version": "v0.9",
  "deleteSurface": { "surfaceId": "booking" }
}

组件与结构

整个组件结构被设计成更适合 LLM 生成的扁平化 Schema(Flat Schema)

为什么选择扁平列表?

传统的嵌套方法:

A2UI 邻接表:

邻接表模型

{
  "surfaceUpdate": {
    "components": [
      {"id": "root", "component": {"Column": {"children": {"explicitList": ["greeting", "buttons"]}}}},
      {"id": "greeting", "component": {"Text": {"text": {"literalString": "Hello"}}}},
      {"id": "buttons", "component": {"Row": {"children": {"explicitList": ["cancel", "ok"]}}}},
      {"id": "cancel", "component": {"Button": { ... }}},
      {"id": "ok", "component": {"Button": { ... }}}
    ]
  }
}

组件通过 ID 引用子级,而不是通过嵌套。

组件基础

每个组件都有:

  1. ID:唯一标识符(例如 "welcome-message")。
  2. 类型:组件类型(TextButtonCard)。
  3. 属性:特定于该类型的配置。

静态 vs. 动态子级

静态 (explicitList)

固定的子级 ID 列表。

{"children": {"explicitList": ["back-btn", "title", "menu-btn"]}}

动态 (template)

从数据数组生成子级。

{"children": {"template": {"dataBinding": "/items", "componentId": "item-template"}}}

对于 /items 中的每个项目,渲染 item-template

数值填充

增量更新

自定义组件

除了标准目录外,客户端还可以定义自定义组件(图表、地图等)。

数据绑定

为什么要分离数据与布局?

想象一个“股票行情追踪”组件。

工作原理:JSON Pointers

把您的数据想象成一个文件系统树。每一条数据都有一个“地址”。

数据模型 (The Store)

{
  "user": { "name": "Alice" },
  "cart": { "total": 99.00 }
}

组件 (The View)

组件不硬编码 “Alice”,而是指向地址 /user/name

{
  "component": {
    "Text": { 
      "text": { "path": "/user/name" } 
    }
  }
}