在應用程式中算繪 A2UI 介面

使用 Jetpack Compose 代理程式對 UI (A2UI) 轉譯器時,AI 代理程式會傳送描述 UI 結構、元件屬性和資料更新的訊息。如要在應用程式中以原生方式顯示這些介面,請在應用程式的 Jetpack Compose 階層中代管及算繪 A2UI 介面。

Compose A2UI 算繪器會協調訊息剖析、反應式快照狀態管理,以及動畫式介面狀態轉換。雖然核心算繪器與任何特定設計系統無關,但透過提供的基本目錄,可與 Material Design 3 進行整合。

初始化以 Compose 為基礎的資料層

A2UI 算繪器支援應用程式資料層中的快照感知狀態,可讓應用程式的 UI 對代理程式的漸進式更新做出反應。如要新增這項支援,請在 ViewModel 中使用 A2uiMessageParserA2uiMessageProcessor 工廠函式初始化剖析器和處理器,如下列程式碼片段所示:

class AgenticUiViewModel : ViewModel() {
    // Create a parser that leverages the built-in JSON parser.
    private val parser = A2uiMessageParser()

    // Create an A2UI message processor with your catalog and optional
    // action interceptor (implementing A2uiActionInterceptor).
    private val processor = A2uiMessageProcessor(
        // You can also use the provided Material catalog instead of
        // a custom one.
        catalogs = listOf(CustomDesignSystemCatalog)
    )

    // Expose active surfaces to the UI as a StateFlow.
    val a2uiSurfaces: StateFlow<List<A2uiSurfaceModel>> =
        processor.activeSurfaces

    init {
        // Collect messages on a background thread tied to the ViewModel lifecycle.
        viewModelScope.launch(Dispatchers.Default) {
            processor.collectMessages()
        }

        // Add support for two-way communication with the agent.
        viewModelScope.launch(start = CoroutineStart.UNDISPATCHED) {
            processor.outboundEvents.collect(::handleOutboundA2uiEvent)
        }
    }

    // Called by your app's networking layer or business logic whenever
    // a new A2UI protocol message arrives from the AI agent.
    fun onNetworkMessage(json: String) {
        processor.processInput(parser, json)
    }
}

使用基本目錄 (Material 3) 算繪介面

使用提供的 Basic Catalog 實作項目 (androidx.compose.material3:material3-a2ui) 轉譯介面時,您可以轉譯完整樣式的 Material 3 介面,包括內建的載入指標、錯誤界線和動畫轉場效果。如要這麼做,請使用 A2uiSurface 可組合項進入點:

@Composable
fun AgenticUiScreen(viewModel: AgenticUiViewModel) {
    // Observe active surfaces managed by the data layer.
    val surfaces by viewModel.a2uiSurfaces.collectAsStateWithLifecycle()

    Column(Modifier.fillMaxSize()) {
        surfaces.forEach { surface ->
            key(surface.id) {
                A2uiSurface(
                    surfaceModel = surface,
                    // Add your surface's custom modifiers here.
                )
            }
        }
    }
}

處理介面狀態和動畫轉場效果

A2uiSurface 會協調根元件狀態解析,並在載入、錯誤和成功狀態之間套用 AnimatedContent 轉場效果:

@Composable
fun CustomStyledSurface(surface: A2uiSurfaceModel) {
    A2uiSurface(
        surfaceModel = surface,
        modifier = Modifier.fillMaxSize(),
        loadingContent = {
            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                CircularProgressIndicator()
            }
        },
        errorContent = { exception ->
            Text(
                text = "Failed to load: ${exception.message}",
                color = MaterialTheme.colorScheme.error,
                // Add your custom error styling, such as modifiers, here.
            )
        },
        transitionSpec = {
            (fadeIn(animationSpec = tween(600)) togetherWith
                    fadeOut(animationSpec = tween(600)))
                .using(SizeTransform(clip = false))
        },
    )
}

使用自訂路由器進行低階表面算繪

您可以直接使用 observeA2uiComponentState 觀察介面根元件狀態,並將算繪作業委派給 A2uiComponent

@Composable
fun RawSurfaceCoordinator(surface: A2uiSurfaceModel) {
    // Extract the catalog to provide its readiness evaluator to the
    // composition. This lets components wait for their dynamic data bindings
    // before they're rendered.
    val coreSurface = surface as? A2uiCoreSurfaceModel
        ?: throw IllegalArgumentException(
            "Surface must implement A2uiCoreSurfaceModel")
    val composeCatalog = coreSurface.catalog as? A2uiCatalog
        ?: throw IllegalArgumentException("Catalog must implement A2uiCatalog")
    val readinessEvaluator = remember(composeCatalog) {
        composeCatalog.asReadinessEvaluator() }

    CompositionLocalProvider(
        LocalA2uiReadinessEvaluator provides readinessEvaluator
    ) {
        val rootState = observeA2uiComponentState(surface = surface)
        when (rootState) {
            is A2uiComponentState.Loading -> {
                LoadingSpinner()
            }
            is A2uiComponentState.Error -> {
                ErrorBanner(rootState.exception)
            }
            is A2uiComponentState.Success -> {
                // Delegate component routing to the Compose A2UI router.
                A2uiComponent(
                    component = rootState.component,
                    // Add your custom modifiers here.
                )
            }
        }
    }
}

實作詳細資料

代理程式到 UI 的算繪器會處理介面狀態解析和防禦性錯誤界線。

防禦性錯誤邊界和代理程式幻覺處理

由於 A2UI 介面是由生成式 LLM 代理程式驅動,因此傳入的酬載可能格式錯誤,或參照不明的元件類型。

為盡量避免當機,Renderer 會建立下列防禦界線:

  • 代理程式自我修正的錯誤調度:錯誤會調度為外送用戶端訊息,讓代理程式在後續互動回合中自我修正。此外,API 也允許元件實作在 API 於轉譯時間偵測到元件專屬錯誤時,將錯誤分派給代理程式。
  • 不明元件:如果遇到無法辨識的元件類型,系統會在該類型到達 UI 樹狀結構之前攔截,並標示為錯誤狀態,然後回報給代理程式進行自我修正。
  • 結構定義驗證失敗:系統會根據元件結構定義 (A2uiSchema) 驗證酬載。格式錯誤的屬性絕不會傳送至 Compose UI 版面配置。
  • 稀疏陣列保護:收到非常大的清單索引時,資料模型會從密集清單轉換為適應性稀疏對映,防止記憶體不足錯誤。