Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Dec 29, 2025 - 日記

A2UI: AIエージェントが安全にUIを生成するGoogleの新プロトコル

A2UI: AIエージェントが安全にUIを生成するGoogleの新プロトコル cover image

AIエージェントがリッチなユーザーインターフェースを生成する際、セキュリティと表現力のトレードオフに直面します。テキストのみの応答では物足りず、かといって任意のコードを実行させるのは危険です。Google が主導するA2UI (Agent-to-User Interface)は、この問題を「データのように安全、コードのように表現力豊か」なアプローチで解決する新しいオープンソースプロトコルです。

本記事では、v0.8 Public Previewとして公開されたばかりのA2UIの概要、技術的特徴、そして実装例について紹介します。

A2UIとは

A2UIは、AI エージェントがリッチなUIを安全に生成するための宣言的JSONフォーマットとレンダラーのセットです。2025年12月にGoogleを中心とした開発チームによって公開され、GitHub では既に7,000以上のスターを獲得し、活発に開発が進んでいます。

従来のアプローチでは、AIエージェントは以下のいずれかの方法でユーザーとやり取りしていました:

  • テキストのみの応答: 安全だが、フォームやダッシュボードなど複雑なUIには不向き
  • コード生成と実行: 表現力は高いが、LLM が生成したコードを実行するセキュリティリスクがある

A2UIは、この両極端の間に位置する第三の選択肢を提供します。

主要な特徴

セキュリティファースト設計

A2UIは実行可能なコードではなく、宣言的なデータフォーマットです。クライアント側は事前承認されたコンポーネントのカタログ(Card、Button、TextFieldなど)を持ち、エージェントはそのカタログに含まれるコンポーネントのみを要求できます。

{
  "id": "search_form",
  "type": "text-field",
  "properties": {
    "label": "検索キーワード",
    "placeholder": "例: レストラン 渋谷"
  }
}

この設計により、未知のコードが実行されるリスクを完全に排除しています。

LLMフレンドリーな構造

A2UIはフラットなリスト構造(Adjacency List Model)を採用しており、LLMが段階的に生成しやすくなっています。

graph LR
    A[エージェント] -->|surfaceUpdate| B[JSONメッセージ]
    B -->|ストリーミング| C[クライアント]
    C -->|レンダラー| D[ネイティブUI]
    D -->|ユーザー操作| A

従来のネストされたツリー構造とは異なり、コンポーネントはIDで参照されます。これにより、LLMは完璧なJSONを一度に生成する必要がなく、プログレッシブレンダリング(段階的な表示)が可能になります。

フレームワーク非依存

同じA2UI JSONペイロードを、異なるフレームワークで実装されたクライアントで描画できます:

  • Web: Lit、Angular、React(開発中)
  • モバイル: Flutter(GenUI SDK 経由)、Jetpack Compose(開発中)
  • デスクトップ: 任意のネイティブフレームワーク

エージェントはUIの抽象的な「意図」を記述し、各クライアントは自身のネイティブコンポーネントを使って実装します。

技術アーキテクチャ

A2UIの動作フローは以下の通りです:

  1. ユーザー入力: ユーザーがエージェントにメッセージを送信
  2. UI生成: エージェント(Gemini等)がA2UI JSONを生成
  3. 転送: メッセージがクライアントにストリーム配信(SSE、WebSocket、A2A Protocol 等)
  4. レンダリング: クライアントのレンダラーがネイティブコンポーネントにマッピング
  5. ユーザー操作: UIイベントがエージェントに送り返される
  6. 更新: エージェントが更新されたA2UIメッセージを返す

メッセージタイプ

A2UIは4種類のメッセージタイプを使用します:

  • surfaceUpdate: UIコンポーネントを定義・更新
  • dataModelUpdate: アプリケーション状態を更新
  • beginRendering: クライアントにレンダリング開始を指示
  • deleteSurface: UI画面を削除

データバインディング

A2UIはJSON Pointerを使用して、UIの構造とアプリケーション状態を分離します。これにより、リアクティブな更新が可能になります。

{
  "id": "restaurant_name",
  "type": "text",
  "properties": {
    "text": "{{ /restaurants/0/name }}"
  }
}

この例では、/restaurants/0/nameというパスのデータが変更されると、テキストコンポーネントが自動的に更新されます。

実装例

公式リポジトリには実用的なデモが用意されています。

Restaurant Finder Demo

レストラン検索のデモでは、エージェントが以下のようなUIを生成します:

  1. 検索フォーム(地域、料理タイプ、予算のスライダー)
  2. 検索結果のカードリスト
  3. 予約フォーム

すべてのUIコンポーネントは、エージェントがユーザーとの会話に基づいて動的に生成します。

カスタムコンポーネント

A2UIはオープンレジストリパターンをサポートしており、開発者は独自のコンポーネントを登録できます:

  • インタラクティブチャート: 数値データの可視化
  • 地図コンポーネント: Google Maps等の統合
  • セキュアiframe: レガシーコンテンツの安全な埋め込み

試してみる

クイックスタート

公式デモを動かすには、以下の手順を実行します:

# リポジトリをクローン
git clone https://github.com/google/A2UI.git
cd A2UI

# Gemini API Keyを設定
export GEMINI_API_KEY="your_api_key"

# エージェント(バックエンド)を起動
cd samples/agent/adk/restaurant_finder
uv run .

# 別ターミナルでクライアント(フロントエンド)を起動
cd renderers/lit
npm install && npm run build

cd ../../samples/client/lit/shell
npm install && npm run dev

Gemini API KeyはAI Studio から取得できます。

CopilotKit Widget Builder

CopilotKit が提供するA2UI Widget Builder で、ブラウザ上ですぐに試せます。

既存技術との比較

React Server Componentsとの違い

以前紹介したReact2Shell脆弱性 では、React Server Componentsにおけるクライアント・サーバー境界の曖昧さが問題となりました。A2UIは以下の点で異なります:

  • 明確な境界: エージェントはデータのみを送信、クライアントが実行を制御
  • コンポーネントカタログ: 事前承認されたコンポーネントのみ使用可能
  • フレームワーク非依存: 特定のフレームワークに依存しない

従来のRPC/API方式との違い

従来のREST APIやgRPCでは、エージェントはデータを返し、クライアントがUIロジックを実装する必要がありました。A2UIでは、エージェントが「どのようなUIを表示すべきか」という意図も伝えられます。

今後の展望

A2UIプロジェクトのロードマップには以下が含まれています:

  • v1.0仕様の策定: 現在v0.8のPublic Previewから正式版へ
  • 追加レンダラー: React、Jetpack Compose、SwiftUI対応
  • 追加トランスポート: REST API等のサポート
  • エージェントフレームワーク統合: Genkit、LangGraph等への対応

まとめ

A2UIは、AIエージェントが安全かつ表現力豊かなUIを生成するための実用的なソリューションです。宣言的なJSONフォーマット、LLMフレンドリーな構造、フレームワーク非依存の設計により、従来のテキストのみの応答やコード実行の問題を解決しています。

v0.8のPublic Preview段階ではありますが、GoogleとCopilotKitを中心とした活発なコミュニティ開発により、AIエージェント時代のUI標準となる可能性を秘めています。

興味のある方は、ぜひ公式デモ を試してみてください。

参考リンク