コンポーネント カタログを作成してカスタマイズする

A2UI アーキテクチャでは、すべてのサーフェスがコンポーネント カタログによって駆動されます。カタログは、AI エージェントが利用できる UI コンポーネント、プロパティ スキーマ、ローカル クライアント関数を定義する正式な契約です。エージェントは、任意のコードを生成したり、未知の要素を考案したりするのではなく、カタログで宣言されたコンポーネントのみを使用してユーザー インターフェースを構築する必要があります。

つまり、カタログでコンポーネントを宣言し、エージェントがそれらを使用してアプリの UI を構築します。

Jetpack Compose A2UI レンダラを使用して Android アプリをビルドする場合、カタログの提供方法には柔軟なオプションがあります。

  • 基本カタログ: A2UI プロジェクトでは、基本カタログと呼ばれる標準化された汎用仕様を定義します。これには、ボタン、テキスト、テキスト フィールド、カード、リストなどの一般的な要素が含まれます。AndroidX ライブラリ androidx.compose.material3:material3-a2ui は、ネイティブの マテリアル デザイン 3 コンポーネントを使用して、この基本カタログ仕様のすぐに使える実装を提供します。androidx.a2ui.compose:compose-ui ライブラリには、Basic Catalog の汎用スキーマ定義も用意されています。これは、独自のデザイン システムに Basic Catalog を実装するのに役立ちます。
  • カスタム カタログ: 独自の明確なデザイン システムを備えた本番環境アプリケーションの場合は、カスタム カタログをゼロから構築できます。これにより、エージェントはアプリのコンポーネント、スタイル設定トークン、ビジュアル言語に限定されます。
  • サブセットまたはハイブリッド: 提供された基本カタログの特定のコンポーネント実装を独自のカスタム コンポーネントと組み合わせたり、基本カタログ スイート内の個々のコンポーネント実装をオーバーライドしたりできます。

提供された基本カタログを使用する

コンポーネント スキーマをゼロから作成せずにすぐに始めるには、A2UI 基本カタログ仕様の提供された実装を使用します。androidx.compose.material3:material3-a2ui ライブラリは、マテリアル デザイン 3 コンポーネントを使用して Basic Catalog を実装します。

materialA2uiBasicCatalogV1 をインスタンス化するときに、次のレンダラとハンドラを指定します。

  • 画像、動画、音声プレーヤーなどのメディア コンポーネント
  • URL オープナー
  • ローカライズされたメッセージの書式設定

A2UI ライブラリは、Coil、Glide、Media3 などの外部メディアとネットワークの依存関係を意図的にバンドルしていません。代わりに、独自のレンダラを提供します。これにより、一意のライブラリを提供することで依存関係の競合を防ぐことができます。たとえば、アプリですでに画像の読み込みに Coil を使用している場合や、再生に Media3 を使用している場合は、既存のライブラリをカタログに直接接続できます。

次の例は、基本的なカタログをインスタンス化し、優先するメディア ライブラリ、URL オープナー、メッセージ フォーマッタを接続する方法を示しています。

// Instantiate the provided Basic Catalog (implemented with Material 3)
val basicCatalog = materialA2uiBasicCatalogV1(
    // Example: Wire up Coil for image loading (via AsyncImage)
    image = MaterialA2uiBasicCatalogV1Defaults.image {
            url, description, scale, modifier, onError ->
        AsyncImage(
            model = url,
            contentDescription = description,
            contentScale = scale,
            modifier = modifier,
            onError = { state -> onError(state.result.throwable) },
        )
    },

    // Example: Use ExoPlayer/Media3 for video
    video = MaterialA2uiBasicCatalogV1Defaults.video { url, modifier, onError ->
        // Custom ExoPlayer video integration here
    },

    // Example: Use an audio player
    audioPlayer = MaterialA2uiBasicCatalogV1Defaults.audioPlayer {
            url, description, modifier, onError ->
        // Custom audio integration here
    },

    // Handle outbound URLs, such as using an app navigator or context intents.
    urlOpener = { url ->
        appNavigator.openUrl(url)
    },

    // Handle localized message formatting
    messageFormatter = { pattern, locale, args ->
        MessageFormat.format(context, locale, pattern, args)
    },
    localeProvider = A2uiLocaleProvider.Default,
)

カスタム コンポーネント カタログをゼロから組み立てる

アプリでカスタム デザイン システムを使用している場合は、独自の カスタム A2uiComponent 実装を含む独自のカタログを定義できます。このアプローチでは、エージェントに公開されるコンポーネント スキーマと、出力されるネイティブ Compose UI を完全に制御できます。

// Define a custom catalog that mirrors your app's design system
val CustomDesignSystemCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-design-system/v1/catalog.json",
    components = listOf(
        CustomButtonComponent,
        CustomCardComponent,
        CustomTextFieldComponent,
    ),
    functions = listOf(MyCustomLocalFunction()),
)

個々のコンポーネント スキーマとその Compose UI レンダリング ロジックを定義する手順については、カスタム A2UI コンポーネントを実装するをご覧ください。

基本カタログ コンポーネントのサブセットをカスタム コンポーネントで使用する

すべてをゼロから構築するか、基本カタログ全体を採用するかを厳密に選択する必要はありません。提供された基本カタログ実装から選択したコンポーネントと独自のカスタム コンポーネントを組み合わせて、カタログを組み立てることができます。

// Assemble a catalog using select Basic Catalog components alongside custom components
val hybridCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-app/v1/catalog.json",
    components = listOf(
        // Use provided Basic Catalog components (built with Material 3)
        MaterialA2uiBasicCatalogV1Defaults.text,
        MaterialA2uiBasicCatalogV1Defaults.card,

        // Add proprietary components from your app's design system
        CustomChartComponent,
        CustomProductCardComponent,
    ),
    functions = createBasicCatalogFunctions(...),
)

また、特定のコンポーネント スロットをオーバーライドして、提供された基本カタログ スイートをカスタマイズすることもできます。

// Override specific components within the Basic Catalog suite
val customizedBasicCatalog = materialA2uiBasicCatalogV1(
    // Supply required renderers (such as Coil or ExoPlayer) as shown earlier
    image = MaterialA2uiBasicCatalogV1Defaults.image(myImageRenderer),
    video = MaterialA2uiBasicCatalogV1Defaults.video(myVideoRenderer),
    audioPlayer = MaterialA2uiBasicCatalogV1Defaults
        .audioPlayer(myAudioRenderer),
    urlOpener = { url -> /* Open URL */ },
    messageFormatter = { pattern, _, _ -> pattern },
    localeProvider = A2uiLocaleProvider.Default,
    // Replaces the default button. If you use this, implement the
    // A2uiBasicCatalogV1.Button interface.
    button = MyCustomBrandButtonComponent,
    
)

カタログのバージョン管理とスキーマの進化を管理する

A2UI カタログは、JSON スキーマ コントラクトに基づいて明示的にバージョン管理されます。スキーマの破壊的な変更を導入する場合は、バージョン アップが必要です。

// Original component (v1 catalog)
object CustomButtonComponent : A2uiComponent { ... }

// Unchanged component across versions
object CustomTextComponent : A2uiComponent { ... }

// Future breaking schema change (v2 catalog)
object CustomButtonComponentV2 : A2uiComponent { ... }

// Assembles the v1 catalog
fun customCatalogV1(
    button: A2uiComponent = CustomButtonComponent,
    text: A2uiComponent = CustomTextComponent,
): A2uiCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-app/v1/catalog.json",
    components = listOf(button, text),
)

// Assembles the v2 catalog
fun customCatalogV2(
    button: A2uiComponent = CustomButtonComponentV2,
    text: A2uiComponent = CustomTextComponent,
): A2uiCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-app/v2/catalog.json",
    components = listOf(button, text),
)

ダウンタイムなしでシームレスな移行を可能にするには、クライアントは複数のサポートされているカタログ バージョンをメッセージ プロセッサに同時に登録できます。

private val processor = A2uiMessageProcessor(
    catalogs = listOf(
        customCatalogV1(),
        customCatalogV2(),
    ),
)

カタログ ネゴシエーション中、エージェントはサポートされているすべてのカタログ ID を検出し、各サーフェスに適したバージョンをターゲットにします。

実装の詳細

以降のセクションでは、内部カタログの検証とスキーマ ネゴシエーションについて説明します。

カタログ管理のユーザー ジャーニーでは、次の主要な API が導入されています。

  • A2uiCatalog: コンポーネント カタログを定義するためのインターフェースと最上位のファクトリ関数。
  • materialA2uiBasicCatalogVX: 標準の A2UI Basic Catalog 仕様の Material 3 実装を提供する、バージョン管理されたファクトリ関数(materialA2uiBasicCatalogV1 など)。
  • A2uiReadinessEvaluatorasReadinessEvaluator(): A2uiReadinessEvaluator は、コンポーネントの準備状況を評価するためのインターフェースです。asReadinessEvaluator() 拡張関数は、カタログに登録されているコンポーネントを使用して準備完了状態を解決します。

A2UI バージョン カタログとコンポーネント スキーマ

カタログ スキーマ定義は、特定のプロトコル バージョンに関連付けられています。プロトコルが進化すると、カタログ定義のバージョンが上がります。この次のバージョンのコンポーネント実装では、更新されたレンダラ API を使用できます。下位バージョンは引き続き並行して動作します。