Ao usar o renderizador agente para interface (A2UI) do Jetpack Compose, um agente de IA envia mensagens que descrevem estruturas de interface, propriedades de componentes e atualizações de dados. Para mostrar essas interfaces de forma nativa no app, hospede e renderize uma superfície A2UI na hierarquia do Jetpack Compose do app.
O renderizador A2UI do Compose coordena a análise de mensagens, o gerenciamento de estado de instantâneo reativo e as transições de estado de superfície animadas. Embora o renderizador principal seja independente de qualquer sistema de design específico, ele oferece integração imediata com o Material Design 3 pelo catálogo básico fornecido.
Inicializar a camada de dados com suporte do Compose
O renderizador A2UI oferece suporte a estados com reconhecimento de snapshots na camada de dados do app, o que
permite que a interface do app reaja a atualizações incrementais do agente. Para adicionar esse suporte, inicialize o analisador e o processador usando as funções de fábrica A2uiMessageParser e A2uiMessageProcessor no seu ViewModel, conforme mostrado no snippet de código a seguir:
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)
}
}
Renderizar superfícies usando o catálogo básico (Material 3)
Ao renderizar superfícies usando a implementação do catálogo básico fornecida
(androidx.compose.material3:material3-a2ui), é possível renderizar uma superfície do Material 3 totalmente estilizada,
incluindo suporte integrado para indicadores de carregamento, limites
de erros e transições animadas. Para isso, use o ponto de entrada combinável 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.
)
}
}
}
}
Processar estados de superfície e transições animadas
O A2uiSurface coordena a resolução do estado do componente raiz e aplica
transições AnimatedContent em estados de carregamento, erro e sucesso:
@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))
},
)
}
Renderização de superfície de baixo nível com roteadores personalizados
É possível observar o estado do componente raiz da superfície diretamente com
observeA2uiComponentState e delegar a renderização a 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.
)
}
}
}
}
Detalhes de implementação
O renderizador de agente para interface processa a resolução do estado da superfície e os limites de erros defensivos.
Limites de erros defensivos e tratamento de alucinações do agente
Como as superfícies da A2UI são impulsionadas por agentes de LLM generativos, os payloads recebidos podem estar malformados ou fazer referência a tipos de componentes desconhecidos.
O renderizador estabelece os seguintes limites de defesa para minimizar a probabilidade de falhas:
- Envio de erros para autocorreção do agente: os erros são enviados como mensagens de cliente de saída, permitindo que o agente se autocorrige em interações subsequentes. Há também uma API que permite que implementações de componentes despachem erros para o agente nos casos em que a API detecta erros específicos do componente no tempo de renderização.
- Componentes desconhecidos: quando um tipo de componente não reconhecido é encontrado, ele é interceptado antes de chegar à árvore da interface, marcado como um estado de erro e informado de volta ao agente para autocorreção.
- Falhas na validação de esquema: os payloads são validados em relação aos esquemas de componentes (
A2uiSchema). Propriedades malformadas nunca devem chegar aos layouts da UI do Compose. - Proteção de matriz esparsa: quando índices de lista muito grandes são recebidos, o modelo de dados faz a transição de uma lista densa para um mapa esparso adaptável, evitando erros de falta de memória.