你让一个客服 Agent 查退款,并返回一个可以继续操作的界面。
理想结果是一张状态卡,显示金额、到账时间和“联系商家”按钮。现实通常只有两种选择:让模型直接生成 HTML/JavaScript,把输出推到应用的执行边界;或者只回一段文字,像让一个会做表格的人交来三行纯文本。
A2UI 是 Agent-to-User Interface 的缩写。它把 Agent 的输出限制为界面意图,由客户端用自己的原生组件完成渲染。模型负责描述,应用负责验收。
声明式界面与客户端渲染
同一个退款场景,模型可以描述一个 Text 组件,并让它读取 /refund/status。它提交的是声明式数据,不是要被宿主执行的网页代码。AI 的审美可以实习,执行权不必跟着实习。

A2UI 的 Catalog 是客户端掌握的组件目录。生产应用可以只开放自己的 Card、Text、Button,也可以规定组件之间的嵌套关系。模型能请求一个按钮,却不能临时发明一个 RunShellCommandButton。
这不意味着 JSON 自动安全。Catalog 中登记的函数和动作仍可能在本地执行,目录、校验器和 action handler 才是实际边界。模型提交意图,客户端决定能画什么、能做什么。
核心界面消息机制
A2UI 的核心界面更新只有四类,分别负责新建 surface、更新组件、更新数据模型和删除 surface。

组件采用扁平列表和 ID 引用。Agent 可以先发根节点,再补子节点;客户端先显示已有部分,缺失部分暂时用占位符。数据单独更新后,状态卡就能从“处理中”变成“已到账”,不用重发整棵页面。
因此,A2UI 更像一条增量 UI 流,而不是一段等待执行的 HTML。当前 v1.0 还定义了函数调用消息,动作权限仍要回到 Catalog 检查。
版本号比组件画廊重要
我 clone 官方仓库读了几处实现。Python 的 MessageProcessor 负责按消息更新 surface,NodeGraph 处理尚未到齐的组件,Web 的 DataContext 负责路径绑定和响应式刷新。协议、状态模型和 renderer 必须连成一条链,漂亮的 JSON 本身不能渲染界面。
官方仓库目前把 v0.9.1 标为生产版,v1.0 仍是候选版,项目也明确处在 early-stage public preview。接入时应核对规范、renderer 和 Catalog 是否同版,不能拿候选规范替没有对应实现的 SDK 签收。
Agent UI 方案的四项评估

模型提交的是数据还是代码?Catalog 由谁掌握?界面和数据是否分离?规范与运行时是否同版?
这四问可以迁移到客服卡片、审批表单和数据面板等场景。A2UI 的价值不在于让 Agent 获得自由画布,而在于给它一套受约束的表达语言。
作者|随机比特
