跳到正文
北京时间
原文
Google Developers Blog(RSS)·· 2026-06-17精选AI 评分64

Google 分享 A2UI 与 MCP Apps 三种集成架构模式

A2UI + MCP Apps: Combining the best of declarative and custom agentic UIs

AI 导读

Google 分享了三种集成 A2UI 与 MCP Apps 的架构模式,旨在结合两者优势。A2UI 采用声明式框架,通过 JSON payload 定义 UI,由宿主原生渲染,确保一致性与安全性,但受限于预定义组件库。MCP Apps 在 iframe 中使用标准 Web 技术提供自定义界面,但存在设计碎片化、性能与安全挑战。三种模式包括:通过 MCP 服务器提供 A2UI,利用 MCP Resources 或 Tool 调用传递 JSON,实现“一次编写,原生渲染”的跨平台能力;以及静态与动态交付方案。Google 正考虑扩展 MCP 以原生支持 A2UI。

推荐理由

Google 这篇指南给出了三种具体的架构模式,帮开发者同时用上 A2UI 的原生安全性和 MCP 的定制能力,对正在做 Agent UI 的团队是直接的工程参考。

正文 · AI 翻译

header

随着智能体工作流从简单的文本交互演进到丰富的 UI,开发者面临着一个长期存在的权衡:深度定制与无缝集成之间的取舍。

在此之前,开发者往往不得不在两条截然不同的路径之间做出选择:

  • Model Context Protocol (MCP) Apps 在 iframe 中利用标准 Web 技术提供了创作自由。然而,这些应用对 iframe 的依赖可能导致碎片化的用户体验,表现为设计系统冲突或冗余滚动条等美学上的不一致,同时在计算性能和安全封装两方面都带来了显著的障碍。
  • Agent-to-User Interface (A2UI) 采用声明式框架。A2UI 不发送原始的 HTML、CSS 和 JavaScript,而是使用 JSON 载荷来定义要渲染的内容,让宿主应用通过其原生组件来处理呈现。宿主应用随后将这些数据安全地转换为其自身的原生 UI 元素。虽然这确保了设计的一致性和更高的安全性,但开发者被限制在特定的组件库内。这种方法提供了高性能、安全且集成的体验,尤其适用于图表和表单等结构化数据,但在处理复杂的客户端逻辑时则显得力不从心。

为了解决这些权衡问题,我们分享了三种架构模式,并附上实现指南和示例代码,以演示 A2UI 与 MCP Apps 的无缝集成。我们正在考虑制作一个 MCP 扩展来支持 A2UI,让这些模式更易于采用。如果你感兴趣,请告诉我们。

集成这两种方法,可以让开发者对标准 UI 元素利用原生组件渲染,同时将自定义 iframe 嵌入保留给高度定制化、复杂的体验。

模式 1. 在 MCP 服务器上使用 A2UI

通过 MCP 服务器提供 A2UI,可以让开发者为其工具添加丰富的、原生渲染的 UI,作为 MCP Apps 的替代方案。它将广泛采用的 MCP 工具连接的简洁性与原生 A2UI 渲染结合在一起。

这种方法降低了开发者采用生成式 UI 的入门门槛。它提供了动态 UI 的优势,而无需构建完整的 Agent-to-Agent(A2A) 架构,也无需处理复杂的发现机制。

架构优势

  • 绕过 iframe 限制:在 MCP 服务器中使用 MCP Apps 来实现 UI,会导致视觉上的割裂和延迟。A2UI-over-MCP 绕过了 iframe,让宿主应用能够使用自己的设计系统原生渲染智能体的意图。
  • 关注点分离: MCP 负责后端工具和数据访问,而 A2UI 负责前端组件渲染。这使智能体逻辑保持简洁,专注于推理,而非 UI 实现细节。
  • 增强的环境可移植性: 一个 MCP 服务器可以向 A2UI 客户端提供数据,后者可在 React、Flutter 或 Angular 上渲染,无需自定义接线。它提供了“一次编写,随处原生渲染”的能力,解决了服务器必须为每个不同界面准备独特响应的问题。
  • 简化的安全性: 从 MCP 工具流出的数据与 A2UI 默认安全的 JSON 架构集成。与传递原始 HTML 的传统方法不同,A2UI 采用基于能力的安全模型,客户端仅渲染来自预定义目录中的受信任组件。
  • 加速开发周期: 构建 MCP 工具或定义资源的专业技能,如今可直接转化为生成复杂用户界面的能力。通过使用 A2UI Agent SDK,工程团队可以绕过手动编写 JSON 的复杂性,因为该库原生管理 schema 强制和验证。

实际效果一览

下面是一个由 A2UI-over-MCP 架构驱动的演示应用。该应用由 2 个面板组成。左侧面板包含一个简单的表单,允许用户选择烹饪方式和蛋白质类型,右侧面板则显示一张食谱卡片。用户在左侧面板中选择烹饪方式和蛋白质类型,然后点击“Get Recipe”按钮,即可获取一张新的食谱卡片并显示在右侧面板上。

该应用中的两个面板均由 A2UI 生成,并且都利用了 A2UI-over-MCP 架构,其中 A2UI 载荷直接从 MCP 服务器获取,并通过 A2UI 框架直接渲染。通过利用 A2UI 框架来渲染 UI,宿主应用无需维护任何 UI 组件逻辑,同时只需将自身的主题应用到 A2UI 组件上,即可保持设计一致性。

A2UI-over-MCP Recipe Studio 实际运行效果

底层原理:它是如何工作的

MCP 服务器不再返回标准的文本响应或打包的 HTML/JS Web 应用,而是为了返回 A2UI 载荷,返回一个带有特定 MIME 类型的结构化 JSON 载荷:application/a2ui+json。

{
  "content": [
    {
      "type": "resource",
      "resource": {
        "uri": "a2ui://dynamic-ui/recipe-card",
        "mimeType": "application/a2ui+json",
        "text": "[
          { "version": "v0.9",
            "createSurface": { ... }
          }
        ]"
      }
    }
  ]
}

示例:通过 MCP 工具调用以嵌入式资源形式传递的 A2UI 载荷] — 在 GitHub 上查看完整示例代码

开发者可以利用两种不同的投递机制来传输这一载荷:通过 MCP Resources(resources/read)或通过 MCP Tool 调用(tools/call)。无论采用哪种方式,该端点都使用 a2ui:// URI 方案。一旦接收,具备 A2UI 能力的主机环境会自动将 JSON 结构导向其原生渲染引擎进行执行。

实现策略:静态投递与动态投递

1. 通过 MCP Resources 的静态投递(resources/read)

对于需要规定性界面、且该界面无论对话上下文如何都保持恒定的工作流,开发者可以将 A2UI 载荷作为标准 MCP Resources 提供。主机应用只需检索一个专用 URI——例如 a2ui://config-panel——服务器便会直接投递不可变的 JSON 结构。

  • 理想用例:基础性组件,例如隐私声明、标准化配置表单或持久性偏好设置。
  • 核心优势:这种方法确保了高可预测性和高效缓存,且计算开销为零,因为它消除了由 LLM 进行实时 UI 合成的需要。

2. 通过 MCP Tool 调用的动态投递(tools/call)

为了解锁真正的生成式 UI 和实时数据注入,客户端可以调用一个 MCP Tool。后端执行逻辑以检索实时上下文,让智能体能够动态组装 A2UI 布局。这个定制化的载荷随后作为嵌入资源在 CallToolResult 中返回。

  • 理想用例:响应式数据可视化、上下文感知的天气模块,或针对特定用户需求量身定制的个性化内容卡片。
  • 核心优势:提供架构上的灵活性,赋能智能体构建能够响应用户目标的、精致的、原生体验感十足的应用。

a2ui-over-mcp-flow

架构图:一个智能体使用 MCP 检索本地数据集上下文,并使用 A2UI 将动态数据可视化组件直接流式传输到客户端。

探索代码

要查看这一架构的实际运行效果,请查阅 A2UI-over-MCP 快速入门指南,以运行上方演示中展示的 A2UIxMCP Recipe Studio Web App。这个交互式演示包含一个从 MCP Resource 加载的静态 A2UI 界面(一个食谱选择表单)和一个由 MCP Tool 提供的动态 A2UI 界面(一张自定义生成的食谱卡片),二者并排运行。

理解差异:基于 MCP 的 A2UI 与基于 A2A 的 A2UI

工程团队经常提出的一个问题是,除了传输协议之外,基于 MCP 的 A2UI 实现与原生 Agent-to-Agent(A2A) 架构有何不同。区别在于动态性和编排复杂度的层次:

  • 基于 MCP 的 A2UI(Resources):静态且规定式的 UI。这是固定数据录入表单等刚性结构需求的最佳选择。
  • 基于 MCP 的 A2UI(Tools):基于工具参数的模板化动态 UI。它也可以提供静态且规定式的 UI。动态控件仅限于工具的输入参数。
  • 基于 A2A 的 A2UI:在受支持目录中的组件范围内,完全生成式且开放式的 UI。智能体拥有完整的对话上下文,并即时驱动 UI 构建。如有需要,这种方法也可以提供模板化 UI 和静态 UI。

虽然工程师通常利用 MCP Tools 来获得确定性结果,但这些端点本身并不局限于静态逻辑。尽管在标准 MCP Tool 配置中使用后端 LLM 并非常规做法,但如果开发者愿意,他们可以在工具调用背后编排一个智能体层,通过基于 MCP 的 A2UI 架构提供更具生成性的 UI 体验。然而,驱动 UI 生成的上下文仍将局限于工具参数以及为后端智能体规定的提示词。

模式 2. 在 A2UI 组件中运行 MCP 应用

虽然通过 MCP 使用 A2UI 非常适合原生集成,但有时你需要 MCP App 那种隔离的、高度自定义的环境。你可以通过将 MCP App 封装在 A2UI 组件中来实现这一点,同时不会破坏宿主的原生设计系统或安全边界。通过将 MCP App 封装在 A2UI 组件中,工程师可以将复杂的、状态密集的模块委托给安全的 iframe,从而实现高度定制化的体验。

这种混合方法赋予工程师针对复杂、状态密集模块的创作灵活性,同时确保主界面与宿主的原生设计保持一致,并维持稳健的状态同步协议。

架构优势

  • 品牌一致性与受控委托:宿主保持对 MCP App iframe 之外用户体验的设计控制权,同时将 MCP App 内部的用户体验谨慎地委托给外部工具开发者
  • 专业化能力:复杂的、状态密集的模块——例如具有实时状态转换的交互式游戏,或具有定制验证逻辑的复杂工作流(如演唱会选座)——通常难以用纯声明式组件构建。嵌入 MCP App 可以解决这一问题,在开发者最需要的地方赋予他们创作自由。
  • 安全状态对齐:宿主应用通过一个受管控的、基于事件的循环,与 MCP App 的内部状态保持同步。通过将 A2UI 渲染引擎作为中介,该架构确保了状态一致性,同时将主环境的上下文与第三方代码隔离开来。

实际效果演示

下面是一个演示应用,它将 MCP App 展示为一个 A2UI 组件。服务端 Agent 以一个 A2UI 载荷作为响应,其中有一个组件是 MCP App 组件,其输入参数包含了基于网页的 Pong 游戏的完整代码。该 A2UI 载荷还包含 2 个不属于 MCP App 的计分卡。

当用户开始与 CPU 对战 Pong 游戏时,球拍的控制和球的位置状态由嵌入的 MCP App 内的代码管理。然而,每当出现得分时,该事件会被转发给 Agent,原生 A2UI 组件会以更新后的得分重新注水,从而在 A2UI 界面中的所有组件(原生 A2UI 和 MCP App)之间实现状态同步。

示例:A2UI Pong 游戏实际运行

底层揭秘:它是如何工作的

为实现这种混合方案,开发者定义了一个 自定义 A2UI 组件,它充当安全的 iframe 封装层(称为 MCP App Component)。这个通用封装层可以承载任何标准 MCP App,并提供一个桥接通道,让该应用与外部世界通信。

每当智能体发起请求时,MCP 服务器会将应用的 HTML 和 JavaScript 资源传输给智能体。随后,智能体将应用代码嵌入结构化的 A2UI JSON 中,并将其与指定的组件参数集成。合并后的 JSON 被发送到宿主,MCP App 便在上述 iframe 封装层内与其他 A2UI 原生组件一同渲染。

A2UI 渲染引擎通过一个安全的、事件驱动的循环,在原生组件和嵌入的 MCP App 之间维护状态,我们称之为 状态同步。同步并不依赖实时的 DOM 抓取或状态轮询,而是遵循一个显式的拦截循环:

  1. 拦截与转换: 当 MCP App 内部发生关键状态转换时(例如 Pong Game 中得分),该应用会触发一次标准的 MCP 工具调用。封装它的 A2UI 组件层会在本地拦截该请求,将 JSON 参数映射为结构化的 A2UI Action 上下文,并立即返回确认,从而解除该应用本地 UI 循环的阻塞。
  2. 请求路由:宿主应用将转换后的上下文打包为一个 A2UI Action,并将其路由到后端 AI 智能体。该智能体充当总体协调者,仅跟踪宏观的“关键状态”(例如游戏得分或预订确认),而不跟踪微观状态(例如球拍/球的坐标或临时表单输入)。
  3. 水合:一旦智能体评估了整体界面状态,它就会返回一个格式化的 DataModel Update JSON。A2UI 引擎直接更新原生组件(如记分卡),并通过 App Bridge 推送这一更新后的资源,以重新水合内部 MCP App 的内部状态。

探索代码

要查看这一架构的实际运行,请参阅我们的A2UI 中的 MCP Apps 快速入门指南,以运行一个实时客户端。这个交互式演示包含一个与 MCP Server 集成的 AI 智能体,该服务器可提供一个 Calculator App 和一个 Pong Game,二者均可在一个通用 MCP App 包装器组件的 Angular 实现中提供。

模式 3. 在 MCP Apps 中运行 A2UI

这一模式充当了一座强大的现代化桥梁,使开发者能够将动态的、由智能体驱动的 UI 注入到遗留应用或非 A2UI 环境中,而无需进行复杂的架构改造。

在这种模式中,MCP App 捆绑包自带 A2UI 渲染器。为了获取动态 A2UI 界面,MCP App 将一次工具调用桥接到服务器,以取回 A2UI 载荷,从而利用前文讨论过的 A2UI-over-MCP 机制。一旦收到 A2UI JSON 载荷,MCP App 便完全在其自身的 iframe 边界内解析并渲染这些载荷。通过将生成式 UI 的复杂性吸收进一个自包含的渲染器,这种模式让开发者能够以极少甚至无需架构改造的方式,将动态的 AI 驱动交互引入现有系统。

架构优势

  • 面向非 A2UI 宿主的生成式 UI:这使 MCP App 即便在宿主环境本身并不原生支持 A2UI 的情况下,也能提供由智能体驱动的 A2UI 能力。
  • 为遗留系统提供升级:遗留应用只需支持一个基础的 MCP App iframe 容器。MCP App 吸收了所有生成式 UI 的复杂性,以极少的工程投入为老旧系统解锁动态 AI 交互。
  • 自包含的交互循环:由于 A2UI 渲染器完全位于 iframe 化的 MCP App 边界之内,本地状态转换(例如接受 / 拒绝文档修订)可以在应用内安全且直接地处理。只有受管理的、预定义的上下文才会通过 App Bridge 回传给宿主。

实际效果演示

下面是一个演示应用,用于展示 A2UI 嵌入式 MCP App。宿主应用加载一个 MCP App,该 App 提供一个从 MCP Server 获取的在线文本编辑器。这个 MCP App 与 A2UI 库打包在一起,后者提供了将 A2UI JSON Payload 渲染为 UI 的能力。通过引入模式 1 中讨论的 A2UI-over-MCP 技术,这个 MCP App 可以有效地与 MCP Server 通信,以通过 A2UI 协议支持生成式 UI 功能。

在这个演示中,用户通过高亮选中一部分文本来启动其 AI 辅助文本编辑。当用户高亮选中文本时,后端服务器将该文本作为参数,以设计出与上下文相关的文本编辑参数。这些控件通过 A2UI 提供,MCP App 在收到该 payload 后将其渲染出来。随后,用户可以调整这些参数,引导 AI 按照他们想要的方式编辑相应部分。当用户点击“Generate Revision”时,AI 智能体将把这些参数纳入考量,并向用户提供一条编辑建议。

示例:生成式文档编辑器

底层揭秘:它是如何工作的

与其他模式相比,这种架构模式消除了宿主环境中原生支持 A2UI 的需求。通过将 A2UI 渲染引擎直接打包在 MCP App 包内,开发者可以将复杂性转移到嵌入式应用本身。

通过利用 App Bridge,嵌入式 MCP App 使用 Pattern 1 中的 A2UI-over-MCP 机制与后端 AI 智能体通信。它从 MCP Server 收到的任何包含 MIME 类型 application/a2ui+json 的响应,都会被当作 A2UI Payload 处理,并交由 A2UI 库进行渲染。

为了实现这些具有生成性质的功能,这个演示应用在 MCP Server 背后放置了一个 AI 智能体。这使得 MCP Tool Calls 能够利用 LLM,根据所提供的参数生成与上下文相关的控制参数和文本修订。

以下交互生命周期支配着这个自包含循环:

  1. 上下文触发:用户与主界面进行交互,例如在文档编辑器中高亮某段特定文字。
  2. 事件转发:App Bridge 通过 postMessage 将该事件传输给宿主,宿主随后将上下文路由至后端 AI 智能体。
  3. 生成式 Payload 返回:智能体评估需求,并通过 MCP Server 返回一个定制的 A2UI JSON payload,其中可能包含动态滑块或专门的编辑控件。
  4. 内部渲染:在识别出 application/a2ui+json MIME 类型后,应用的内部渲染器会将该界面动态挂载到指定面板中。
  5. 托管通信:高层级用户操作通过桥接转发至后端处理,而本地状态转换——例如接受或拒绝修订——则直接在应用沙箱内管理,以维持安全隔离。
<html>
<body>

  <div>
    <h3>MCP App (Editor Panel)</h3>
    <p>This text is native to the sandboxed third-party app.</p>
    
    <!-- A2UI Surface custom element provided by the A2UI SDK -->
    <a2ui-surface surfaceId="recipe-card"></a2ui-surface>
  </div>

  <script>
    // Note: The pseudocode below assumes AppBridge from @modelcontextprotocol/ext-apps
    // and a2uiProcessor from the A2UI SDK are preloaded or inlined.
    const bridge = new AppBridge({ name: 'editor-panel', version: '1.0.0' });

    // Helper to extract and process dynamic A2UI responses from tool results
    function processA2UIResponse(result) {
      const a2uiResource = result?.content?.find(
        c => c.type === 'resource' && c.resource?.mimeType === 'application/a2ui+json'
      );
      if (a2uiResource?.resource?.text) {
        const payload = JSON.parse(a2uiResource.resource.text);
        window.a2uiProcessor.processMessages(payload);
      }
    }

    // 1. Initialize AppBridge and fetch initial controls
    async function initApp() {
      await bridge.connect();
      
      // Call server tool to load initial layout controls
      const result = await bridge.callServerTool({ name: 'fetch_controls', arguments: {} });
      processA2UIResponse(result);
    }

    // 2. Handle interactive User Actions routed by the A2UI SDK
    window.a2uiProcessor.events.subscribe(async (event) => {
      if (!event.message.userAction) return;
      const action = event.message.userAction;
      
      // Route the user action directly via the bridge to the MCP Server tool
      const result = await bridge.callServerTool({
        name: action.name,
        arguments: action.context
      });
      
      // Feed any updated server UI states back to the A2UI processor
      processA2UIResponse(result);
    });

    // Initialize the app on startup
    initApp();
  </script>
</body>
</html>

HTML

示例:嵌入式 MCP App 功能逻辑的高层级概览。它重点展示了使用 postMessage 进行宿主通信、获取动态 A2UI 布局,以及将用户交互转发回服务器。

探索代码

要查看这一确切架构的实际运行效果,请参阅我们的 MCP Apps 中的 A2UI 快速入门指南,以运行一个实时客户端。这个交互式演示中的 MCP App 包含其自有的 A2UI 渲染引擎,可为用户提供生成式文本编辑体验。

结论

将 A2UI 与 MCP Apps 相结合,可帮助你的智能体 UI 在保持安全、强大且原生体验的同时,不牺牲创意表现力。这种统一的方法让你能够在使用工具渲染 UI 时绕过 iframe(MCP 上的 A2UI),在声明式视图中显示丰富的自定义画布(A2UI 中的 MCP Apps),并轻松将动态 UI 嵌入现有 Web 应用(MCP Apps 中的 A2UI)。

选择合适的架构

A2UI 是一种灵活的消息格式,可以从任意后端传输到任意前端。这种灵活性意味着你可以有很多种使用方式。

table

为了帮助你梳理这些选项,请使用下面的决策树,为你的项目特定的约束条件和需求找到最优架构:

decision_tree_5

选择框架:通过上面的架构决策树,为你的具体智能体需求找到最优的交付模式。

准备好在你自己的技术栈中接入 A2UI 和 MCP Apps 了吗?

来源:Google Developers Blog(RSS) · developers.googleblog.com