从聊天框到 AI 原生交互:跨 Agent、跨平台的应用架构
大多数 AI 产品最初都从聊天框开始:用户说一句,模型回一句。
目录
但 Agent 进入真实应用以后,系统开始发生根本变化。它不再只是“生成答案”,而是会持续执行任务、调用工具、产生中间状态、等待用户决定、生成可操作界面,并把真实业务动作交给后端执行。
于是问题不再是“应该选哪一个 Agent UI 协议”,而是更上游的三个问题:
Agent 应用出现了哪些新的连接边界?哪些语义应该稳定?模型、Runtime、UI 与业务系统应该怎样分工?
MCP、A2A、AG-UI、A2UI、MCP Apps、Apps SDK、Framework-native Generative UI 都是这个问题空间里逐渐长出的实现路线。它们是“果”,不是文章的出发点。
本文先从问题和设计原则出发,再看可选技术体系。后文会把“运行交互协议 + 声明式 UI”作为一个较完整的开放案例深入分析,但不会预设最终一定采用 AG-UI + A2UI。
1. Agent 走进真实应用:交互为什么从聊天变成系统问题
传统应用常见的是:
点击 → API 请求 → 返回结果 → 页面更新。
Agent 应用则更像一个持续工作的协作者:
- 一个 Task 可能跨很多轮执行;
- 中间会调用搜索、数据库、浏览器、代码环境等 Tool;
- 会产生 Text、Artifact、Progress、State;
- 可能需要用户补充输入或审批;
- 用户可能直接编辑 AI 生成的结构化内容;
- 一个任务可能在不同设备、甚至不同 Agent 之间继续。
因此 AI-native interaction 的核心不是“聊天框更丰富”,而是:
自然语言、直接 UI 操作、Agent 执行和业务系统,共同作用于同一个持续存在的任务。
这时,一个原本简单的“模型 API”问题,被拆成了多个不同的连接边界。
2. 问题空间与技术版图:Tool、Agent、Host、UI 分别需要什么连接层
从上面的体验变化继续往下拆,会看到至少四条不同连接边界。它们不是同一个问题,也因此长出了不同的协议和实现路线。
| 连接边界 | 主要问题 | 当前代表性路线 |
|---|---|---|
| Agent ↔ Tool / Data | 如何发现和调用外部工具、资源、Prompt | MCP |
| Agent ↔ Agent | 不同厂商 / Runtime 的 Agent 如何发现、委派、协作 | A2A |
| Agent ↔ User App | 长运行、Tool、State、Interrupt 怎样实时进入应用 | AG-UI、应用自定义事件协议 |
| Agent ↔ Dynamic UI | Agent 怎样产生可交互 UI,而不是只返回文本 | A2UI、MCP Apps、Framework-native Generative UI |
MCP 官方把自己定位为连接 AI 应用与 Tool / Data 的开放标准;A2A 则面向独立 Agent 之间的发现、任务和协作。S22 S23
AG-UI 官方也用一张 Protocol Stack 把 MCP、A2A 与 AG-UI 放在不同连接关系中:S02

所以第一个重要结论是:
Agent 交互并没有一个“总协议”可以解决所有问题。协议生态正在按连接边界分层。
Tool 能返回 JSON,不等于用户就愿意看 JSON。
当用户需要:
- 比较多个结果;
- 填写结构化参数;
- 操作图表;
- 审阅 Diff;
- 确认订单或审批;
- 在任务执行中持续查看状态;
系统就需要从 Agent Response 进一步走向 Agent-driven UI。
这里又产生一个新的设计分叉:
UI 到底应该是“Agent 发送结构,由 Host 渲染”,还是“服务端直接交付一个可运行的小应用”?
这正是 A2UI、MCP Apps,以及各类 Framework-native Generative UI 路线开始分化的地方。
在这个问题空间里,当前公开生态至少有下面几类代表性路线。
2.1 MCP:先解决 Agent 如何获得外部能力
MCP(Model Context Protocol)首先解决的不是 UI,而是:
AI 应用怎样以标准方式连接 Tool、Resource 与 Prompt。
当前 MCP SDK 文档将其定义为连接 AI 应用与数据、工具系统的开放标准;Server 暴露 Tool / Resource,Host 连接 Server,再让模型使用这些能力。S22
MCP 的意义在于把“能力接入”从各家 Agent SDK 的私有 Tool Schema 中抽出来。
但 Tool 能被调用,并不自动解决:
- Agent 运行状态怎样进入 UI;
- 用户怎样在中途修改任务;
- Tool Result 应该怎样变成富交互界面。
所以 MCP 后来又自然延伸出了 MCP Apps 这样的 UI 扩展。
2.2 A2A:当系统里不再只有一个 Agent
A2A(Agent2Agent Protocol)面向的是另一类问题:
一个 Agent 怎样发现、调用、委派任务给另一个独立 Agent。
A2A 1.0 官方规范强调,它面向不同框架、语言、厂商构建的独立 Agent,并通过 Agent Card、Task、Message、Artifact 等公共模型实现互操作,而不要求暴露对方内部 memory、tools 或实现细节。S23
因此在多 Agent Mesh 中,更自然的结构可能是:
这里的核心协议可能首先是 A2A + MCP,而不是 AG-UI。
2.3 AG-UI:一个运行交互层
AG-UI(Agent–User Interaction Protocol)解决的是:
Agent 正在做什么,用户应用怎样持续理解它,以及用户操作怎样再回到 Agent。
官方将它定义为开放、轻量、事件驱动的 Agent ↔ User App 协议;Run、Message、Tool、State、Interrupt 等都只是为了让应用获得统一的运行语义。S01 S04

官方 Overview 的核心含义:不同 Agent Runtime 和不同 Client 可以通过公共交互边界接线。协议统一的是运行语义,不要求 Runtime 内部实现一致。
如果应用完全由自己控制,也可以维护自定义 Runtime Event Protocol。AG-UI 的价值主要在于:当 Agent / Client 数量增加时,不必让每个前端都理解每种 Runtime 的私有事件。
2.4 A2UI:一个声明式 UI 层
A2UI(Agent to UI)解决的是另一个问题:
Agent 怎样表达“需要什么界面”,而不是直接发送 React、HTML 或任意 JavaScript。
官方将 A2UI 描述为声明式 UI 格式:Agent 发送 UI 数据,Host 根据 Catalog 用本地 Renderer 画出真实组件。S09
所以 A2UI 的核心不是消息字段本身,而是一个分工:
- Agent 决定需要什么信息和交互;
- Catalog 约束它可以使用什么 UI 能力;
- Renderer / Host 决定这些能力在 React、Flutter 等平台怎样实现;
- 用户 Action 再回到 Agent 或应用。
具体 JSON 操作、middleware 和内部消息格式属于实现细节,只有真正接入时才需要进入。
2.5 MCP Apps:不是描述 UI,而是直接交付一个受沙箱约束的小应用
MCP Apps 是另一种很不同的路线。
官方定义是:
MCP Server 可以为 Tool 声明一个 ui:// UI Resource,Host 将 HTML App 放在 sandboxed iframe 里运行,并通过 postMessage / JSON-RPC 与它通信。S24
其架构更像:
这种方式的核心特点是:
- Server / App 作者拥有完整 HTML / CSS / JS 表达能力;
- Host 用 iframe 和 CSP 做隔离;
- Tool 与 UI 可以一起分发;
- 支持 MCP Apps 的 Host 可以复用同一个 App。
它与 A2UI 的设计哲学并不相同:
| A2UI | MCP Apps | |
|---|---|---|
| Agent / Server 发送什么 | 声明式 Component Blueprint | 预构建 HTML App |
| 谁控制最终视觉 | Host / Renderer | App 作者 |
| 隔离方式 | 不执行远程 UI 代码 | sandboxed iframe |
| 跨 Native Renderer | 更自然 | 主要是 Web View / iframe 模型 |
| 表达上限 | 受 Catalog 限制 | 接近完整 Web App |
| 适合 | Host-owned Design System、动态生成 UI | Tool-backed 富应用、复杂自定义交互 |
A2UI 官方自己的生态比较页也将这两种路线明确区分。S11
2.6 OpenAI Apps SDK:MCP Apps 路线上的一个 Host / 产品实现
OpenAI Apps SDK 不是另一套完全独立的底层协议。
当前 OpenAI 官方文档明确建议:新的 UI 先使用开放的 MCP Apps standard,ChatGPT 特有能力再通过可选的 window.openai 扩展增强;组件运行在 ChatGPT iframe 中,并通过 MCP Apps bridge 与 Host 通信。S25
因此如果目标是:
- 把 Tool + UI 分发到 ChatGPT;
- 同时希望尽量兼容其他 MCP Apps Host;
这条路线可能比“自建 AG-UI Host + A2UI Renderer”更直接。
2.7 Framework-native Generative UI:在自己控制的技术栈里最快
还有一类路线根本不追求跨 Host 协议标准。
例如 Vercel AI SDK 的 Generative UI 思路,是让模型 Tool Call 的结果直接映射到 React Component;AI SDK UI 提供构建 Chat / Generative UI 的 Framework hooks。S26
这种方式的优点非常实际:
- 前端工程路径短;
- React 组件可以直接复用;
- 不需要额外设计跨平台 UI Protocol;
- 适合自己同时控制 Agent 和 Web App 的产品。
它的代价是:
可移植边界更多停留在你的应用框架里,而不是跨 Host / 跨 Renderer 的开放协议层。
这并不是“不够先进”,而是目标不同。
2.8 技术路线真正的分叉点
因此 Agent UI 不应该被简化成“AG-UI vs A2UI”。
更准确的技术地图是:
3. 设计原则:先稳定任务语义,再选择协议和框架
协议和框架都可能变化,但用户正在完成的任务不应该跟着技术栈一起消失。
协议可以替换,Task 不应该跟着消失。
3.1 先稳定业务语义
建议优先稳定:
| 稳定对象 | 它回答的问题 |
|---|---|
| Task | 用户到底在持续完成哪件事? |
| Artifact | 当前工作的可交付对象是什么? |
| Action | 用户或 Agent 想产生什么业务效果? |
| State | 哪些状态需要被共享、恢复或持久化? |
| Capability | 当前 Agent / Host / Channel 实际能做什么? |
| Permission | 当前操作者是否允许执行这件事? |
| Version / Revision | 用户确认的内容是否还是即将执行的那一版? |
相反,不需要为了统一而强行标准化:
- Agent 内部 Planner;
- Runtime 私有 checkpoint;
- Model private memory;
- React / Flutter 的实现;
- Slack 与 Web 的像素布局。
核心原则是:
技术体系可以替换;用户正在完成的“同一件事”必须保持稳定。
这也是后面所有架构设计的真正起点。
3.2 再用五个问题决定技术边界
1. Host 是谁控制的?
如果 Web / Mobile / Desktop 都是自己的产品,Host 拥有很强控制权,可以选择:
- AG-UI;
- A2UI;
- Framework-native UI;
- 自定义协议。
如果 UI 要进入 ChatGPT、Claude Desktop 等第三方 Host,MCP Apps 这种 Host Extension 标准会更自然。
2. 谁应该控制视觉和组件实现?
如果必须严格继承企业 Design System:
Declarative UI / Host Renderer 更合适。
如果集成方必须拥有完整视觉和交互:
Sandboxed App / iframe 路线更合适。
3. 是否真的需要跨 Renderer?
如果产品只有 React Web:
Vercel AI SDK / CopilotKit / 自研 Generative UI 很可能已经足够。
如果目标明确包含 Flutter、Angular、Native 等多个 Renderer:
A2UI 这类声明式中间表示才更有价值。
4. 是否需要跨独立 Agent?
如果只是一个 Runtime 内部的 Sub-agent:
不一定需要 A2A。
如果多个 Agent 属于不同系统、团队或厂商:
A2A 的 Agent Card、Task、Artifact 模型会更重要。S23
5. UI 是任务主体,还是 Tool 的附属交互?
如果 UI 本质上是某个 MCP Tool 的“脸”:
MCP Apps 很自然。
如果 UI 是整个 Agent Application 的长期工作区:
Runtime Interaction + Host-owned UI 的体系通常更自然。
3.3 典型技术组合
| 目标场景 | 更自然的技术组合 |
|---|---|
| 自有 Web App,需要替换多个 Agent Runtime | AG-UI / 自定义 Runtime Protocol + Native UI |
| 自有多端 App,需要 Agent 动态生成 Native UI | AG-UI 或 A2A + A2UI |
| 远程 Agent Mesh,同时携带可渲染结果 | A2A + A2UI |
| MCP Tool 希望在 ChatGPT / Claude 等 Host 里提供富 UI | MCP + MCP Apps |
| ChatGPT 内的业务 App,需要额外 Host 能力 | MCP Apps + OpenAI Apps SDK extensions |
| 单一 React 产品,前后端都自己控制 | Vercel AI SDK / Framework-native Generative UI |
| 复杂 Editor / Canvas / 3D App | Native App / MCP Apps,Agent 通过 Tool / Action 控制;不一定适合全量声明式生成 |
3.4 为什么后文重点观察“运行交互 + 声明式 UI”
不是因为它们已经“赢了”,而是因为这一组合很适合观察一套开放的 AI Interaction Architecture:
- 分层清楚:运行交互和 UI 表达被拆成两个独立问题;
- 公开、可检查:都有公开规范、SDK / Renderer 以及官方组合路径;A2UI 也不限定只能经 AG-UI 传输。S15 S17
- 能暴露真正的架构问题:Host-owned UI、跨 Renderer、State、Action、Capability、Permission 都会在这条路径上出现。
因此后文会拿它们做一个较完整的开放案例,但结论仍然适用于 MCP Apps、A2A + UI、Framework-native Generative UI 或自定义体系。
如果产品是 Tool-first、第三方 Chat Host-first,MCP Apps 可能更直接;如果核心是跨组织 Agent Mesh,A2A 更重要;如果只有一个 React App,Framework-native Generative UI 往往更简单。
4. 模型与系统如何协作:Prompt、Tool、Schema、Protocol 各管什么
到这里容易产生一个实际问题:
这些交互到底是靠 Prompt 让模型“听话”,还是靠 Tool Calling,还是协议本身在约束模型?
答案是:它们负责不同层,通常会同时存在。
| 层 | 最简单的理解 | 能保证什么 | 不能保证什么 |
|---|---|---|---|
| Prompt / Context | 告诉模型“你有什么能力、什么时候用” | 引导模型选择和生成 | 不能作为安全边界 |
| Tool / Function Schema | 给模型一组结构化动作接口 | 工具名和参数形状更稳定 | 不代表模型有执行权限 |
| Structured Output / UI Schema | 约束模型生成的数据形状 | UI / 结果更容易解析和校验 | 不代表业务内容正确 |
| AG-UI / A2UI / MCP 等协议 | 在系统之间传递运行事件、Tool、UI、Action | 统一通信和生命周期 | 不负责模型推理本身 |
| Runtime / Business Validation | 真正执行前再次校验 | 权限、版本、幂等、业务规则 | 不能省略 |
Tool Calling:最适合“模型需要选择一个动作”
AG-UI 官方的 Tool 结构本质上就是:name + description + JSON Schema parameters。Schema 同时帮助 Agent 生成参数,也帮助应用解析和校验参数。S05
下面是厂商无关的简化示意,不对应某一家模型 API:
const tools = [
{
name: "searchOrders",
description: "查询用户订单",
parameters: {
type: "object",
properties: {
keyword: { type: "string" }
},
required: ["keyword"]
}
},
{
name: "requestApproval",
description: "请求用户确认一个高风险动作",
parameters: {
type: "object",
properties: {
actionId: { type: "string" },
summary: { type: "string" }
},
required: ["actionId", "summary"]
}
}
];
// 模型只负责:选哪个 tool、填什么参数
const turn = await model.run({ messages, tools });
// 系统仍然负责最终校验和执行
for (const call of turn.toolCalls) {
const args = validateSchema(call.name, call.args);
await dispatchWithPermissionCheck(call.name, args);
}
最重要的一点是:
Tool Calling 是“模型提出一个结构化动作”,不是“模型获得这个动作的权限”。
生成 UI:固定模板优先,动态生成再用 Schema / Structured Output
A2UI 官方 Agent Development Guide 把模型侧流程概括成四步:
理解意图 → 生成 A2UI → 校验并发送 → 处理用户 Action。S27
其中生成阶段可以使用 Prompt 或 Structured Output;Catalog 的 Schema 和示例可以被放进模型上下文,让模型知道自己允许使用哪些组件。S27
工程上可以简单分成两种方式:
固定业务流程优先使用代码或模板。
例如审批、订单确认、支付参数这类 UI,不需要为了“AI-native”强行让模型每次重新设计布局。
只有当界面结构本身确实取决于任务内容时,才值得让模型动态生成 A2UI。
Protocol:负责搬运,不负责“教模型思考”
最后要把协议和模型能力彻底分开:
- AG-UI 搬运 Run / Tool / State / Interrupt;
- A2UI 搬运声明式 UI 和 Action;
- MCP 暴露 Tool / Resource;
- A2A 传递 Agent Task / Artifact。
这些协议并不会让模型自动知道什么时候该调用 Tool,也不会替代 Prompt、Tool Schema、Structured Output 和运行时校验。
更准确的链路是:
这也是为什么模型侧设计和协议侧设计应该分开评审:前者决定模型会尝试做什么,后者决定系统怎样表达和传递,最后的 Business Gate 决定什么真的允许发生。
5. 推荐架构:Experience、Interaction、Runtime、Control Plane 如何分工
理解问题空间、设计原则和模型侧约束之后,再看完整系统如何组织。
推荐把系统看成四个逻辑层:
它们不一定要部署成四个服务,但职责应该尽量清楚。
5.1 完整架构
图里真正应该被长期稳定下来的,不是某个协议名称,而是底部的业务 Control Plane。
5.2 Experience Layer:允许不同平台拥有不同体验
Web、移动端、IM、CLI 不应该被迫使用同一种界面。
Host 负责:
- 呈现任务;
- 收集用户输入;
- 提供当前选中对象等语义上下文;
- 运行本地交互;
- 在支持时渲染 A2UI;
- 在受限平台做 Channel Adapter。
统一的是用户正在完成的任务,不是像素。
5.3 Interaction Layer:协议只解决通信和表达
这一层可以包括:
- AG-UI;
- A2UI;
- Native Generative UI;
- Channel Adapter;
- Capability / Catalog 解析。
它负责把 Agent 的运行过程和动态 UI 表达转换为 Host 可以理解的公共语义。
但它不应该成为业务数据库。
5.4 Agent Runtime:保留内部自由度
Runtime 可以继续自由选择:
- LangGraph;
- ADK;
- 自研 Runtime;
- 单 Agent / Multi-agent;
- MCP;
- A2A;
- 私有 checkpoint;
- private memory。
只要它在公共边界上暴露真实、可验证的能力,就不要求内部实现一致。
5.5 Business Control Plane:为什么服务端不会消失
以下能力不能依赖模型或 Renderer 决定:
- 用户身份;
- tenant;
- 权限;
- Artifact 版本;
- Action 幂等;
- 审批;
- 审计;
- 事务;
- 长任务状态;
- 真实副作用是否成功。
因此:
协议负责解耦,Business Control Plane 负责连续性、授权和正确性。
“解耦”从来不意味着零耦合。
真正的目标是:
把不稳定、散落的私有耦合,收敛成少数稳定、明确、可测试的边界。
6. 治理边界:状态、权限、能力、组件和协作怎么管
完整架构看起来很干净,但真正决定它能不能进入生产的,是所有权、权限、能力和版本边界。
完整架构看起来很干净,但系统收敛并不是免费的。
真正复杂的地方,往往不在“协议能不能连通”,而在下面这些边界怎样被团队共同维护。
6.1 State Ownership:谁才是权威状态
至少要区分四类状态:
| 状态 | 推荐权威来源 |
|---|---|
| Agent checkpoint / private memory | Agent Runtime |
| Task / Artifact / Revision | Business Backend |
| A2UI Data Model | Surface / Renderer |
| 未提交输入、焦点、滚动等 | Local UI |
不要把它们合成一个巨大的共享 JSON,然后所有地方都能 patch。
典型事故是:
用户正在编辑标题,Agent 同时返回整份新状态,把用户尚未提交的输入静默覆盖。
因此需要明确:
- 哪一层有权覆盖哪一类状态;
- Artifact 是否有 revision;
- UI dirty field 如何处理;
- 冲突是自动合并、提示用户,还是拒绝写入。
6.2 Action:按钮不是权限
A2UI 能让 Agent 生成一个“发布”按钮,但:
生成一个按钮 ≠ 获得发布权限。
真实副作用仍然应该进入统一的业务 Command / Action Handler。
例如:
这样 Web、Slack 或自然语言“确认”只是不同输入形式,不会形成三个互相独立的业务执行入口。
6.3 Catalog:跨平台能力和跨平台成本来自同一个地方
A2UI 最大的价值之一是 Catalog。
但 Catalog 也是主要成本来源。
一个高阶业务组件通常至少要定义:
- Schema;
- 数据语义;
- Action;
- Web Renderer;
- Mobile Renderer;
- fallback;
- accessibility 行为。
Catalog 越“业务化”,例如:
- DiffReview;
- OrderCard;
- ApprovalPanel;
- DashboardChart;
- RichEditor;
Agent 输出就越短、越稳定,但每个目标 Renderer 的实现成本越高。
Catalog 越“原子化”,只提供 Text / Row / Button / Input,跨平台实现容易,但模型需要生成更长的组件树,UI 一致性也更难控制。
这本质上是一个生成复杂度 vs Renderer 适配成本的粒度权衡。
A2UI 官方也建议生产系统定义自己的 Catalog,并映射到自己的 Design System。S21
6.4 多 Agent 还需要 Surface Ownership
多 Agent 同时工作的系统里,还必须知道:
这个 Surface 到底是谁创建的?
A2UI Actions 文档专门讨论了 Surface Ownership:由哪个 Agent 创建的 Surface,其 Action 和相应 Data Model 应路由回正确的 Agent,而不是广播给所有 Agent。S14
这既是正确性问题,也是数据隔离问题。
6.5 Capability:能连接不等于能力相同
同样是 AG-UI Agent,不代表都支持:
- Tool streaming;
- Shared State;
- Interrupt / Resume;
- Multimodal;
- Cancel;
- A2UI。
AG-UI 有能力发现机制,但官方也明确:discovery 不等于 negotiation,缺省能力应该视为 unknown。S07
所以 Host 不应该写:
if (agent.protocol === "ag-ui") {
showAllFeatures();
}
而应该根据真实 Capability 决定功能和降级路径。
6.6 版本矩阵不能只写“支持 A2UI”
A2UI 当前生产基线是 v0.9.1,v1.0 仍是 Candidate。S18 S20
生产环境应该记录整组兼容面:
AG-UI SDK
+ Runtime Adapter
+ A2UI Middleware
+ A2UI Protocol
+ Renderer
+ Catalog
协议名相同,不代表任意版本组合都天然兼容。
6.7 真正需要哪些团队配合
| 角色 | 主要责任 |
|---|---|
| Agent / AI 工程 | Runtime Adapter、Tool、真实 Capability、必要时生成 A2UI |
| 前端 | AG-UI Client、Renderer、Catalog、本地交互 |
| 业务后端 | Task、Artifact、Action、Permission、Revision、幂等、审计 |
| 平台集成 | Slack / Teams / Mobile Channel Adapter |
| Design System | 哪些组件进入 Catalog、不同 Renderer 的一致语义 |
| QA / Infra | 多 Runtime × 多 Client × 多版本兼容与可观测性 |
因此这类架构的协作成本主要不是“装几个 SDK”,而是:
让多个团队开始围绕同一组任务、状态、动作和能力语义工作。
7. 系统收敛:真正降低的是语义版本数量和信息熵
知道代价之后,才能准确讨论为什么值得做。
“省开发成本”只是结果之一,更深层的价值是:
减少整个系统里同时存在的语义版本数量,降低工程上的信息熵。
7.1 交互语义收敛
原来不同 Agent 可能分别使用:
waiting_for_user
needs_input
paused
approval_required
不同 UI 又可能定义:
modal_waiting
pending_confirmation
human_required
它们本质上可能都是:
当前 Task 正在等待 Human Input。
当这些语义进入统一 Interaction Model 后,日志、UI、监控和测试都不需要重复解释。
7.2 State 收敛
原来常见的状态混乱是:
- Runtime 觉得自己拥有完整 state;
- UI 也保存完整 state;
- Backend 还有一份数据库 state;
- A2UI Surface 又有一份 data model。
收敛并不是把它们全部合并,而是明确所有权:
系统因此减少的是同一事实被多处当成权威来源的情况。
7.3 Action 收敛
以前可能是:
Web 按钮 → REST API A
Slack Card → Webhook B
自然语言“确认” → Agent Tool C
最后三条链都可能执行同一项“发布”。
收敛后:
这不仅降低开发重复,也大幅降低权限漂移和重复副作用的风险。
7.4 Capability 收敛
不同 Agent 和不同 Channel 不需要再用大量产品硬编码描述:
“这个入口应该可以做什么。”
Capability、Catalog 和 Channel 能力开始变成显式输入。
系统可以根据真实能力决定:
- 完整呈现;
- 降级;
- 隐藏;
- 转到更可信的入口。
7.5 N×M → N+M 只是表象
没有公共边界时:
建立公共边界后:
接线模块数量可以从接近 N×M 下降为 N+M。
但这只是表象。
仍然存在:
- Component × Renderer:自定义 Catalog 的实现;
- Agent × Client:行为兼容测试;
- Business Action:安全和业务校验。
所以更准确的收益是:
从大量重复但不完全相同的局部协议,收敛到一组可以治理、测试、观测和演进的公共语义。
真正减少的不是接口数量,而是同一个概念需要被重新解释的次数。
8. 进阶能力:跨 Agent、跨平台能走多远
跨 Agent、跨平台不应该是架构一开始的人为目标。
更自然的关系是:
当 Task、Action、State 和 Capability 已经从具体 Runtime / UI 中抽离,跨 Agent 与跨平台才成为系统收敛后的能力红利。
8.1 跨 Agent:迁移业务事实,不迁移 Runtime
“同一个 UI 可以接 Agent A 和 Agent B”相对容易。
真正困难的是:
Agent A 执行到一半,Agent B 能不能无损接管?
通常不能直接保证。
不同 Runtime 可能持有:
- 私有 checkpoint;
- internal memory;
- pending tool call;
- planner 状态;
- 调用栈;
- 子 Agent 状态。
更可靠的设计是抽取可移交的业务事实:
因此:
跨 Agent 的可靠边界,是业务状态和交接事实可移植,而不是 Runtime 内部执行状态完全可移植。
8.2 跨平台:迁移 UI 语义,不迁移像素
A2UI 当前提供 Web、Flutter 等 Renderer 路径。S16
其抽象关系是:
基础组件越多,跨平台越容易:
- Text;
- Button;
- Card;
- TextField。
高阶业务组件越多,体验越强,但跨 Renderer 实现成本越高。
所以:
A2UI 降低的是 UI 组合逻辑和 Agent 输出协议的重复,不是消灭跨平台组件开发。
8.3 封闭平台要共享任务语义,而不是强行共享 UI Tree
Slack、Teams、CLI 等平台通常不能直接运行你的完整 Renderer。
这时应该使用 Channel Adapter:
因此真正需要跨平台保持一致的是:
- Task;
- Artifact;
- Action;
- Permission;
- 用户意图;
- Revision。
而不是同一棵 UI Tree。
8.4 安全语义不能随着平台一起降级
如果某个平台无法完整展示待批准内容,或者无法可靠绑定操作者身份,那么它可以:
- 展示状态;
- 提醒用户;
- 提供只读摘要;
- 引导到可信入口。
但不应该因为“需要跨平台”就把严格审批降级成一句:
回复 yes 即可。
跨平台能力的正确目标是:
体验可以降级,业务安全语义不能静默降级。
8.5 最终能得到什么
完成这些收敛以后,一个成熟系统可以更自然地实现:
- 同一个 Task 在 Web 和 Mobile 之间继续;
- 同一个业务 Action 从 UI、IM、自然语言等不同入口进入统一 Command;
- Agent 更换后继续使用相同 Artifact / Constraints;
- Renderer 变化后仍理解相同 Surface / Catalog 语义;
- 不同平台根据 Capability 选择完整交互或合理降级。
这才是“跨 Agent、跨平台”真正有价值的含义。
9. 演进路线:从单点功能到可治理系统
前面描述的是目标架构。
现实系统不应该一次性把所有协议、Renderer、Channel 和 Runtime 全部重构完。
更稳妥的路线是:
9.1 第一步:先定义 Task / Artifact / Action
不要先安装 AG-UI 或 A2UI,然后再寻找业务模型。
先回答:
- Task 是什么;
- Artifact 是什么;
- 哪些 Action 会产生真实副作用;
- Artifact 怎样版本化;
- 什么叫“等待用户”;
- 什么叫“业务完成”。
至少建立稳定的:
taskId
artifactId
revision
actionId
permission
这样未来断线、换端、换 Agent 时,业务事实不会只存在某一个 Runtime 或页面内存里。
9.2 第二步:用第二个 Runtime 验证交互边界
同一个 Web UI 接两个不同 Runtime。
第一版只覆盖:
- Text;
- Tool Progress;
- Error;
- 一个 Human Input / Interrupt。
验收目标不是功能多,而是:
前端不再需要增加 Runtime 私有判断。
这一步验证 AG-UI / Adapter 边界是否真的成立。
9.3 第三步:A2UI 先做固定结构,不要先追求自由生成
优先选择高价值、确定性强的场景:
- Result List;
- Form;
- Approval;
- Diff Review。
先由代码或稳定模板产生 Surface,只让数据动态更新。
等 Action、Data Model、Renderer、权限链路跑通以后,再考虑让模型动态组合组件。
9.4 第四步:专门验证最容易出事故的边界
不要只测“能不能渲染”。
至少需要覆盖:
- 断线重连;
- 重复 Action;
- Artifact revision 冲突;
- 用户编辑时后台状态更新;
- 权限变化;
- Action 过期;
- 多 Agent Surface Ownership;
- 未知 Catalog / Component;
- Renderer 版本不匹配;
- Tool 已产生副作用但客户端取消连接。
9.5 第五步:增加一个真正不同的平台
不要只做另一个 Web 页面。
优先选:
- Flutter;
- Slack / Teams;
- CLI。
因为这会最快暴露:
- 哪些抽象真的跨平台;
- 哪些组件只在浏览器成立;
- 哪些业务动作不能降级;
- 哪些内容应该进入 Channel Adapter。
9.6 第六步:最后才开放动态 UI
只有当固定模板已经覆盖不了真实需求时,再开放 Agent 在受控 Catalog 内动态组合。
同时限制:
- Catalog;
- 组件数量;
- Schema;
- Action 类型;
- Retry 次数;
- Resource URL;
- 高风险操作入口。
这样可以避免:
先建设一个很漂亮的“大一统 AI UI 平台”,最后却没有足够真实场景证明它值得存在。
9.7 最终验收不应该只看“能不能跑”
建议至少观察:
| 场景 | 合格行为 |
|---|---|
| 同一 UI 换 Agent | UI 无需增加 Runtime 私有分支 |
| 同一 Task 换端 | 任务和未决 Action 保留 |
| Agent 能力缺失 | 明确降级,不伪造能力 |
| 未知 Component | 安全失败或 fallback |
| 用户编辑时后台更新 | 不静默覆盖输入 |
| 重复 Action | 不重复产生业务副作用 |
| Artifact 已变化 | 旧审批不能执行新内容 |
| 断线与事件重放 | 恢复显示,不重新执行已完成命令 |
| 多 Agent / 多 Surface | Action 不串线、数据不广播 |
| 受限平台 | 体验可降级,安全语义不降级 |
结语:真正应该统一的是“同一件事”
回到全文,真正的问题从来不是“哪一个协议会成为最终标准”。
协议、Framework、Renderer 和 Host 都可以继续演进;更重要的是,不管技术体系怎样变化,用户正在完成的 Task、Artifact、Action、Permission 与 Version 是否仍然具有稳定含义。
更准确的心智模型是:
最后可以得到几个结论:
- AI-native interaction 的核心不是聊天框变漂亮,而是语言、UI 与执行开始共享同一个 Task。
- 运行交互层可以采用 AG-UI,也可以是经过治理的自定义 Runtime Protocol。
- 动态 UI 可以采用 A2UI、MCP Apps、Framework-native Generative UI 或其他适合 Host 所有权模型的方案。
- 真正长期稳定的不是协议本身,而是 Task、Artifact、Action、State、Capability、Permission 与 Version。
- 系统收敛最大的收益不是少写几个接口,而是降低语义版本数量,让状态、动作、权限和能力进入统一治理。
- 跨 Agent 和跨平台是这种收敛后的能力红利,而不是架构一开始的目的。
- Runtime 私有状态通常不能无损迁移;应该优先迁移业务事实。
- 跨平台也不是零适配;Renderer、Catalog 和 Channel Adapter 仍然是必要成本。
如果只记住一句:
让“谁在执行”和“怎么呈现”都可以变化,但让“用户正在完成的同一件事”保持稳定。
这才是从聊天框走向 AI 原生应用时,真正值得建立的架构边界。
参考资料
检索核对日期:2026-09-25。优先采用官方文档和维护者仓库;版本状态和集成范围应以实际部署时锁定的 SDK、Adapter、Middleware、Renderer 与 Catalog 为准。
| 编号 | 官方资料 | 用途 |
|---|---|---|
| S01 | AG-UI Overview | AG-UI 定位与 Agentic App 背景 |
| S02 | MCP, A2A, and AG-UI | 官方 Protocol Stack |
| S03 | AG-UI Core Architecture | Run / Event / Adapter |
| S04 | AG-UI Events | 运行事件语义 |
| S05 | AG-UI Tools | 前端 / 后端 Tool 边界 |
| S06 | AG-UI Interrupts | Human-in-the-loop 与恢复 |
| S07 | AG-UI Capabilities | 能力发现与边界 |
| S08 | AG-UI Serialization | 历史恢复 |
| S09 | What is A2UI? | A2UI 背景与核心设计 |
| S10 | A2UI Core Concepts | Surface、消息与 Data Model |
| S11 | A2UI:How Does A2UI Compare? | AG-UI 与 A2UI 的关系 |
| S12 | A2UI Catalogs | Catalog 与能力边界 |
| S13 | A2UI Data Binding | Structure / State 分离 |
| S14 | A2UI Actions | Event、Local Function、Surface Ownership |
| S15 | A2UI Transports | Transport-independent 设计 |
| S16 | How to Use A2UI | Web、Flutter、Agent 接入 |
| S17 | A2UI with Any Agent Framework | AG-UI + A2UI 官方组合 |
| S18 | A2UI v0.9.1 Protocol | 当前生产协议 |
| S19 | AG-UI A2UI Runtime / Renderer Wiring | Middleware、固定 / 动态 UI |
| S20 | A2UI v1.0 Candidate | 候选版演进 |
| S21 | Defining Your Own Catalog | Production Catalog |
| S22 | Model Context Protocol TypeScript SDK | MCP 的 Tool / Data 开放标准定位 |
| S23 | A2A Protocol v1.0 | 独立 Agent 的发现、Task、Artifact 与互操作 |
| S24 | MCP Apps Overview | Tool + HTML UI Resource + sandboxed iframe |
| S25 | OpenAI:Add UI to your MCP server | ChatGPT 对开放 MCP Apps 标准及 Host 扩展的实现 |
| S26 | Vercel AI SDK:Generative UI | Framework-native Generative UI 路线 |
| S27 | A2UI Agent Development Guide | Prompt / Structured Output / Schema Validation 的模型侧流程 |
评论公开保存在 GitHub Discussions。