聊天框正在过时:Generative UI 与 A2UI/AG-UI 会怎样改变 AI 应用?

0 阅读5分钟

聊天框正在过时:Generative UI 与 A2UI/AG-UI 会怎样改变 AI 应用?

大多数 AI 应用都有一个相似界面:左边历史会话,右边聊天框,用户输入一句话,模型返回一大段 Markdown。

这种形态适合问答,却不适合完成复杂任务。

当用户让 Agent 安排会议时,比起回答“我找到了三个时间”,更自然的交互应该是直接展示可选时间卡片;当用户分析销售数据时,Agent 应该返回图表和筛选器,而不只是用文字描述趋势。

这就是 Generative UI:Agent 根据当前任务动态选择和组织界面。

Google 在 2026 年发布 A2UI v0.9,用统一声明描述 Agent 的 UI 意图;AWS 近期也展示了通过 AG-UI 在 Agent 与前端之间同步事件、状态和人工输入的生产架构。Google:A2UI v0.9AWS:Generative UI with AG-UI

这类协议的价值不是让模型随意生成网页代码,而是让 Agent 在安全边界内“说 UI”。


一、为什么不能让模型直接返回 HTML?

最直接的 Generative UI 方案,是让模型生成 HTML 和 JavaScript,然后放进页面。

这会立刻带来问题:

  • XSS 和任意脚本执行;
  • 样式与产品设计系统不一致;
  • 无障碍和多端适配困难;
  • 组件行为无法测试;
  • Agent 可能构造钓鱼界面;
  • 每次生成的 UI 结构都不同。

更稳妥的方式是:前端掌握组件实现,Agent 只能从已注册的组件目录中选择,并填写经过 Schema 校验的属性。

Agent 不生成:<script>...</script>

Agent 生成:
component = "sales_chart"
props = { period: "30d", group_by: "region" }

前端收到声明后,使用自己的 SalesChart 组件渲染。


二、A2UI 与 AG-UI 分别解决什么问题?

两者经常一起出现,但关注点不同。

A2UI:描述“界面是什么”

A2UI 是一种声明式 UI 格式。Agent 表达组件树、数据和交互意图,客户端使用自己的组件库渲染。

AG-UI:传输“Agent 正在做什么”

AG-UI 更关注 Agent 与前端之间的事件流,例如:

  • Run 开始和结束;
  • 文本增量输出;
  • 工具调用;
  • 状态同步;
  • UI 组件更新;
  • 等待用户输入。

可以把两者理解为:

AG-UI = Agent 与前端之间的通信管道
A2UI  = 管道中可传递的一种声明式 UI 内容

Google 的 A2UI 文档也将它定位为跨框架、跨设备的 UI 意图标准,而不是某个特定前端框架的替代品。Google:Introducing A2UI


三、一个受控的 Generative UI 架构

flowchart LR
    U[&#34;用户&#34;] --> F[&#34;Web / App&#34;]
    F --> G[&#34;AG-UI Gateway&#34;]
    G --> A[&#34;Agent Runtime&#34;]
    A --> T[&#34;业务工具&#34;]
    A --> C[&#34;组件目录&#34;]
    A --> G
    G --> F
    F --> V[&#34;Schema 校验&#34;]
    V --> R[&#34;本地组件渲染&#34;]

核心边界有三条:

  1. Agent 只能使用组件目录中存在的组件;
  2. 属性必须通过严格 Schema 校验;
  3. 真正的业务写操作仍然走后端工具和权限检查。

界面按钮不能直接等于业务权限。即使 Agent 渲染了“退款”按钮,点击后仍要经过退款服务的身份、金额和状态校验。


四、Go 后端如何表达 UI 事件?

可以先定义一个简单、与前端框架无关的事件结构:

type UIEvent struct {
	RunID     string          `json:"run_id"`
	Sequence  int64           `json:"sequence"`
	Type      string          `json:"type"`
	Component string          `json:"component,omitempty"`
	Props     json.RawMessage `json:"props,omitempty"`
}

type SalesChartProps struct {
	Title  string   `json:"title"`
	Labels []string `json:"labels"`
	Values []int64  `json:"values"`
}

Agent 决定展示销售图表后,后端不直接接受任意 JSON,而是先转换并验证:

func NewSalesChartEvent(
	runID string,
	sequence int64,
	props SalesChartProps,
) (UIEvent, error) {
	if len(props.Labels) == 0 || len(props.Labels) != len(props.Values) {
		return UIEvent{}, ErrInvalidChartData
	}

	payload, err := json.Marshal(props)
	if err != nil {
		return UIEvent{}, err
	}

	return UIEvent{
		RunID:     runID,
		Sequence:  sequence,
		Type:      "component.upsert",
		Component: "sales_chart",
		Props:     payload,
	}, nil
}

事件通过 SSE 或 WebSocket 发送。Sequence 用于断线后补发,component.upsert 表示同一个组件可以随着 Agent 获得新数据而增量更新。


五、Generative UI 还需要解决状态一致性

假设 Agent 展示一个旅行计划表,用户手动修改酒店,Agent 随后又更新行程。如果双方都覆盖整个对象,很容易丢失用户修改。

因此需要明确:

  • 哪些状态由 Agent 拥有;
  • 哪些状态由用户拥有;
  • 哪些字段允许共同修改;
  • 冲突时采用版本号、Patch 还是人工确认。

推荐每次更新携带版本:

component_id: itinerary_1
base_version: 7
next_version: 8
patch: replace /days/2/hotel

如果前端已经处于版本 9,就拒绝旧 Patch,并让 Agent重新读取当前状态。


六、什么场景值得使用 Generative UI?

适合:

  • 数据分析与图表;
  • 表单填写;
  • 商品或方案比较;
  • 日程、旅行和工作流编排;
  • Human-in-the-loop 审批;
  • Agent 任务进度与产物展示。

不一定适合:

  • 简单问答;
  • UI 高度固定的核心交易页面;
  • 需要像素级稳定和严格合规的流程;
  • 组件目录尚未建立的早期 Demo。

Generative UI 的目标不是让所有页面都由 AI 生成,而是在任务不确定时动态组合有限、可信的交互能力。


结语

聊天框不会消失,但它很可能从最终界面退回到一种输入方式。

未来的 AI 应用会根据任务在文本、表格、图表、表单和审批组件之间切换。Agent 负责决定当前需要什么交互,前端负责使用可信组件把它呈现出来。

真正可生产的 Generative UI,不是“模型生成任意代码”,而是:

Agent 表达 UI 意图,协议传递事件和状态,客户端掌握渲染与安全边界。