【Google Cloud】A2UIを今更ながら触ってみた – エージェントがUIを返す時代

こんにちは。SCSKの島村です。
皆さんは「A2UI(Agent-to-User Interface)」をご存じでしょうか??

A2UIとは2025年12月にGoogleが公開した、AIエージェントがリッチなUIを安全に生成するためのオープンプロトコルです。
A2A(Agent-to-Agent)やADK(Agent Development Kit)と並んで、Googleのエージェントエコシステムを構成する重要な技術のひとつですが、まだまだ情報が少なく、「名前は聞いたことあるけど、実際何ができるの?」という方も多いのではないでしょうか。

本記事では、『A2UI(Agent-to-User Interface)』について調査・整理した内容をご紹介します。
具体的には、以下のような疑問に答えていきます。

– A2UIとは何か?何を解決するのか?
– 既存技術(A2A、MCP Apps)とはどう違うのか?
– 実際に動かすとどうなるのか?
最終的には、実際にA2UIエージェントを触ってみて、「テキスト応答」と「リッチUI応答」の違いを体感するところまでをお伝えできればと思います。
最後までお付き合いいただけますと幸いです。
【掲載内容に関する注意事項】
本ブログの図解やインフォグラフィックスの一部については、視認性向上のため生成AI(Generative AI)を活用して作成しています。
また、記事内の技術的な挙動やデータについては、弊社GoogleC Cloud環境下での検証結果に基づいています。環境の差異やAI生成による細部の解釈については、公式ドキュメントと併せてご確認ください。
対象読者
– AIエージェント開発に興味があるエンジニア
– Google Cloud / Gemini Enterprise / ADKを利用している方
– A2A、ADK、MCP などの関連技術を追いかけている方
 

A2UIとは

一言でいうと、、、、
A2UI(Agent-to-User Interface)は、AIエージェントがリッチなUIを安全に生成するためのオープンプロトコルです。

エージェントはHTMLやJavaScriptを直接生成するのではなく、あらかじめ定義されたUIコンポーネントのカタログから「何を表示したいか」を宣言的に記述します。実際の描画はクライアント側が行います。

なぜ今、A2UIなのか??

AIエージェントの開発が急速に進む中、ひとつ見過ごされがちな問題があります。

「エージェントの応答が、テキストの壁になっている」「答えは正しいのに、全部テキストだから伝わりにくい」
エージェントがどれだけ賢くても、応答がテキストだけだと「読んで、理解して、テキストで返す」を何度も繰り返す羽目になる
例えば、エージェントにレストラン予約を頼んだとしましょう。
“`
ユーザー: 「明日の夜、2人でイタリアンを予約したい」
Agent:   「何時頃をご希望ですか?」
ユーザー: 「19時くらい」
Agent:   「以下のお店が見つかりました:
          1. トラットリア・ベッラ(渋谷/★4.2/19:00空き)
          2. ピッツェリア・ナポリ(恵比寿/★4.5/19:30空き)
          3. オステリア・ルーチェ(代官山/★3.9/19:00空き)
          どちらにしますか?」
ユーザー: 「2番のお店ってどんな感じ?」
Agent:   「ピッツェリア・ナポリは恵比寿駅徒歩3分の…」
ユーザー: 「じゃあそこで」
Agent:   「予約しました。」
“`
実に「7ターン」。。。。。正確な応答ではありますが、これがもしUIだったら——
この「テキストだと何往復もかかるのに、UIなら1画面」という課題を解決するのが、A2UIです。

A2UI の設計哲学 – 3つの柱

A2UIの設計は、以下の3つの原則に基づいています。

  1. Security First(セキュリティ最優先)
    A2UIは実行可能コードではなく、宣言型のデータ形式です。
    従来、リモートエージェントからUIを受け取る場合はHTMLやJavaScriptをiframeでサンドボックス化する方法が一般的でしたが、XSSやUIインジェクションのリスクがありました。
    A2UIでは、クライアント側が「信頼できるコンポーネントのカタログ」を持ち、エージェントはそのカタログの範囲内でしかUIを指定できません。カタログにないコンポーネントは無視されるため、任意コード実行のリスクを排除できます。
  2. LLM-Friendly(LLMに最適化)
    UIはフラットなJSONリストで表現され、LLMがインクリメンタルに生成しやすい構造になっています。
    完璧なJSONを一発で出す必要はなく、ストリーミングで逐次的にUIを組み立てられます(プログレッシブレンダリング)。
  3. Framework-Agnostic(フレームワーク非依存)
    A2UIはUI構造と実装を分離しています。同じA2UI JSONペイロードが、Lit、React、Angular、Flutter、SwiftUIなど異なるフレームワークで同じようにレンダリングできます。エージェント側はクライアントが何を使っているか知る必要がありません。
A2UIのコンポーネントカタログには、18個の宣言型プリミティブが用意されています。

エージェントはこの18個の「部品」を組み合わせてUIを構成します。
重要なのは、同じ18個のプリミティブから、プロンプトの意図に応じて全く異なるUIが動的に生成されるという点です。
まとめると、、、、
A2UIは「エージェントにUIを描かせる仕組み」ではありません。「エージェントが安全にUIと会話するための言語」を定義しています。
  •  エージェントは「何を表示したいか」だけを記述する
  •  「どう表示するか」はクライアントが決める
  •  信頼境界を越えても安全(宣言型データ、カタログ制約)
  •  LLMがストリーミングで生成しやすい構造

A2AとA2UIの違い

A2AとA2UI。名前が似ていて混同しがちですが、役割は全く異なります。

「A2A」  = エージェント同士が「どうやって話すか」のルール(通信プロトコル)
「A2UI」= エージェントが「UIをどう表現するか」のルール(データフォーマット)
A2AとA2UIは競合ではなく補完関係です。
それぞれ独立して使えますが、組み合わせると「リモートエージェントのリッチUIが安全に届く」世界が実現します。
次章では、もうひとつの類似技術「MCP Apps」との違いを整理できればと思います。
 

類似技術との比較(MCP Appsとのとの違い)

A2UIと近い文脈で語られることが多いのが「MCP Apps」だと思います。両者の違いを簡単に整理できればと思います。

MCP Apps は、[Model Context Protocol(MCP)]の拡張機能です。
*(What is the Model Context Protocol (MCP)? – Model Context Protocol)
MCP Apps はその上で、ツールがインタラクティブなUIリソース(`ui://` URI)を宣言し、ホスト側がHTMLをサンドボックス(iframe等)内にレンダリングする仕組みを提供します。                 

そもそもどちらも「エージェントがUIを提供する」技術です。
MCP AppsもA2UIも、「エージェントの応答をテキストだけでなくUIとして提供する」という同じ方向性を持っています。
ただし、「誰がUIの主導権を握るか」という点で設計思想が大きく異なります。
一言で言うと
A2UI: エージェントはUIを「指定する」だけ。描くのはクライアント。
MCP Apps: エージェント(サーバー)がUIを「生成する」。クライアントはそれを表示する。
A2UIが向いているケース
  • 外部エージェント(別組織、別サーバー)をUIに安全に組み込みたい
  • マルチエージェント環境で統一的なUIルック&フィールが必要
  • クライアント側でUIの最終的な見た目を制御したい
MCP Appsが向いているケース
  • エージェントとUIを同じチームで密に設計している
  • 高度なレイアウトや独自表現を素早く試したい
  • 信頼境界を気にしなくてよい環境(社内ツール等)

 

実際にA2UIを触ってみる

冒頭でも説明としてお話しした「レストラン予約アシスタント」を題材に、
3ステージでA2UIを触っていければと思います。実際に「テキスト応答→A2UI JSON→リッチUI」の変化を体験してみようと思います。
【全体の流れ】
Stage 1: テキストで候補を返すだけの標準エージェント(Before)
    ↓ A2UI SDKのinstruction導入
Stage 2: A2UI JSONを生成するエージェント(構造化UI出力)
    ↓ カスタムフロントエンドでレンダリング
Stage 3: リッチUIとして表示(After)

<Stage 1>: テキスト応答の標準エージェント

まずはA2UIなしの通常エージェントです。
確認したこと:
– ツール呼び出し(`search_restaurants`)が正常に動作する
– 検索結果がテキストで返ってくる
from google.adk.agents import Agent 
from .restaurants import search_restaurants, make_reservation 

root_agent = Agent( 
  model="gemini-3.5-flash", 
  name="restaurant_assistant", 
  description="レストラン予約をサポートするアシスタント。", 
  instruction=( """
  あなたはレストラン予約アシスタントです。
  ユーザーがレストランを探している場合は search_restaurants ツールで検索し、"結果をわかりやすく日本語で説明してください。
  ユーザーが予約を希望した場合は make_reservation ツールで予約を実行してください。
  """ ), tools=[search_restaurants, make_reservation], )

候補が文字列で列挙され、写真もなく、選ぶのに追加のやりとりが必要。
 

<Stage 2>: A2UI JSON を生成するエージェント

同じプロンプトに対して、`beginRendering` / `surfaceUpdate` / `dataModelUpdate` の構造化JSONが返ってくる。ことを確認します。
Stage 1からの変更点:
A2UI SDKの `A2uiSchemaManager` を導入し、エージェントのinstructionを差し替えます。ビジネスロジック(ツール)は一切変えません。
– `instruction` を `schema_manager.generate_system_prompt()` に差し替えた
– それだけ。ツールもモックデータも一切変えていない
from google.adk.agents import Agent 
from a2ui.schema.manager import A2uiSchemaManager 
from a2ui.basic_catalog.provider import BasicCatalog 
from .restaurants import search_restaurants, make_reservation 

schema_manager = A2uiSchemaManager( version="0.8", catalogs=[BasicCatalog.get_config("0.8")], ) 
instruction = schema_manager.generate_system_prompt( 
 role_description=( """
  あなたはレストラン予約アシスタントです。
  ユーザーがレストランを探している場合は search_restaurants ツールで検索し、ユーザーが予約を希望した場合は make_reservation ツールで予約を実行してください。
  すべて日本語で応答してください。""" ), 
 workflow_description=( """
  1. ユーザーの希望(ジャンル、エリア、日時、人数)を確認する
  2. search_restaurants で候補を検索する
  3. 結果をリッチUIで表示する(カード形式、画像・評価・空き状況付き)
  4. ユーザーが選択したら make_reservation で予約する
  5. 予約確認をカード形式で表示する""" ), 
 ui_description=( """
  レストラン候補は Card コンポーネントで表示し、各カードに Image(店舗写真)、
  Text(店名・説明)、Icon(星評価)、Button(予約する・地図を見る)を含める。
  予約確認は Card にまとめて表示する。Respond ONLY with the A2UI JSON array. Do NOT include any text outside the JSON.""" ),
 include_schema=True, include_examples=True, ) 


root_agent = Agent( model="gemini-2.5-flash", name="restaurant_assistant", 
description="レストラン予約をサポートするA2UIアシスタント。", instruction=instruction, tools=[search_restaurants, make_reservation], )

開発者がUIカタログのスキーマを手書きする必要はなく、SDKが自動でLLMに教えてくれる。

<Stage 3>: リッチUIレンダリング

Stage 2で生成されたA2UI JSONを、実際のUIコンポーネントとして描画します。
*今回はFastAPI + JavaScript で簡易的なカスタムフロントエンドを作成しました。
確認したこと
– 同じプロンプトに対して、リッチUIがレンダリングされる
– 店舗写真がカード内に表示される
– 評価(星)がアイコンで表示される
– 空き時間が強調表示される
– 予約ボタンが配置される
フロントエンド側(JavaScript)でA2UI JSONをパースし、コンポーネントに変換
同じプロンプトに対して、カード・画像・ボタンがリッチUIとしてレンダリングされることが確認できたのではないでしょうか。
 – A2UI JSONの3種メッセージ(`beginRendering` / `surfaceUpdate` / `dataModelUpdate`)をパース
 – コンポーネントIDをキーにフラットリストから再帰的にDOM要素を構築
 – 18個のプリミティブそれぞれに対応するHTML/CSSマッピングを定義

まとめ

やってみて分かったこと

  • 導入は簡単: SDK(a2ui-agent-sdk)がA2UIカタログ全体をシステムプロンプトとして生成してくれる
  • ロジック変更不要: ツールやビジネスロジックはそのまま。出力形式だけが変わる
  • UIは動的: 同じ18プリミティブから、LLMが文脈に応じて最適なUIを選択
  • 効果は明確: テキスト7往復が、UI1〜2画面に短縮される

一報で、LLMの出力安定性という意味ではA2UI JSONの生成品質はLLMに依存することも確認できました。
– プロンプトの書き方でUIの質が大きく変わる(`ui_description` の設計が重要)
– たまに不正なJSONが出力されることもある(`a2ui_utils.py` でフォールバック処理が必要)

今後とも、AIMLに関する情報やGoogle CloudのAIMLサービスのアップデート情報を掲載していきたいと思います。
最後まで読んでいただき、ありがとうございました!!!
著者について

SCSK株式会社のクラウド専門部隊に所属
Google Cloudの
・AI MLサービス選定/導入コンサルティング/導入サポート/AI 基盤・運用構築まで多く案件を担当
Google Cloud Partner Top Engineer 2024・2025・2026 受賞 カテゴリ:Cloud AI/ML
Google Cloud Next Tokyo 出展
Google Cloud Day ’23 Tour 登壇
「AI は選んで組み込んで実装!最新 AI を道具として有効利用するためには!?」
Google Cloud Next Tokyo 25 登壇
「Gemini がデータサイエンティストに !? 業務データから始める高度なデータ活用」
■好きな Google Cloud サービス:Vertex AI / Dialogflow CX / Cloud Run / BigQuery

島村裕哉をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(Google Cloud)は、Google Cloudの多彩なAIや各種サービスを活用したワンストップソリューションを提供します。SCSKのノウハウや体制を有効活用し、業務課題の解決に必要な全体検討と組み合わせで、最適な業務実装まで支援します。

AI・MLGoogle Cloud未設定
シェアする
×
タイトルとURLをコピーしました