Experiências de front-end com ADK e A2UI

1. Visão geral

A maioria dos apps de agente retorna texto simples. A A2UI muda isso. É um protocolo com 18 primitivos declarativos de interface que permite que o agente crie interfaces interativas e avançadas. O cliente as renderiza de forma nativa. Não é necessário um novo código de front-end por layout.

Este codelab usa o Kit de Desenvolvimento de Agente (ADK, na sigla em inglês) para criar o agente e a A2UI para gerar a interface.

O que você vai criar

Um painel de infraestrutura em nuvem simulado em três etapas:

  1. Um agente padrão que retorna dados de recursos como texto simples
  2. Um agente A2UI que retorna os mesmos dados como JSON A2UI estruturado
  3. Um agente renderizado que mostra o JSON A2UI como componentes interativos da interface na interface de desenvolvimento do ADK

Agente A2UI do ADK

O que você vai aprender

  • Como a A2UI funciona: 18 primitivos, 3 tipos de mensagem, modelo de componente simples
  • Como usar o SDK da A2UI para solicitar que um agente do ADK gere JSON A2UI
  • Como renderizar componentes A2UI em adk web

O que é necessário

  • Tenha um projeto na nuvem do Google Cloud com o faturamento ativado.
  • Um navegador da web, como o Chrome
  • Python 3.12 ou mais recente

Este codelab é destinado a desenvolvedores intermediários que têm alguma familiaridade com o Python e o Google Cloud.

Este codelab leva aproximadamente de 15 a 20 minutos para ser concluído.

Os recursos criados neste codelab custam menos de US $5.

2. Configurar o ambiente

Criar um projeto do Google Cloud

  1. No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
  2. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como verificar se o faturamento está ativado em um projeto.

Iniciar o editor do Cloud Shell

Para iniciar uma sessão do Cloud Shell no console do Google Cloud, clique em Ativar o Cloud Shell no console do Google Cloud.

Isso inicia uma sessão no painel inferior do console do Google Cloud.

Para iniciar o editor, clique em Abrir editor na barra de ferramentas da janela do Cloud Shell.

Defina as variáveis de ambiente

Na barra de ferramentas do editor do Cloud Shell, clique em Terminal e Novo terminal e execute os comandos a seguir para definir seu projeto, local e configurar o ADK para usar o Gemini na Vertex AI.

export GOOGLE_CLOUD_PROJECT=<INSERT_YOUR_GCP_PROJECT_HERE>
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_VERTEXAI=True

Ativar APIs

No terminal, execute o comando a seguir para ativar as APIs necessárias:

gcloud services enable aiplatform.googleapis.com

Instalar dependências

No terminal, execute o comando a seguir para instalar a versão mais recente do Kit de Desenvolvimento de Agente (ADK, na sigla em inglês):

pip install -U google-adk a2ui-agent-sdk
export PATH="$HOME/.local/bin:$PATH"

3. Criar o agente

Comece com um agente padrão do ADK que retorna texto simples. É assim que a maioria dos apps de agente se parece hoje.

Criar pasta do agente

Crie uma pasta chamada a2ui_agent que vai conter o código-fonte do agente e das ferramentas.

Definir ferramenta e dados simulados

Crie a2ui_agent/resources.py com o conteúdo a seguir. Essa ferramenta retorna uma lista de recursos de nuvem com o status deles.

RESOURCES = [
    {
        "name": "auth-service",
        "type": "Cloud Run",
        "region": "us-west1",
        "status": "healthy",
        "cpu": "2 vCPU",
        "memory": "1 GiB",
        "instances": 3,
        "url": "https://auth-service-abc123.run.app",
        "last_deployed": "2026-04-18T14:22:00Z",
    },
    {
        "name": "events-db",
        "type": "Cloud SQL",
        "region": "us-east1",
        "status": "warning",
        "tier": "db-custom-8-32768",
        "storage": "500 GB SSD",
        "connections": 195,
        "version": "PostgreSQL 16",
        "issue": "Storage usage at 92%",
    },
    {
        "name": "analytics-pipeline",
        "type": "Cloud Run",
        "region": "us-west1",
        "status": "error",
        "cpu": "2 vCPU",
        "memory": "4 GiB",
        "instances": 0,
        "url": "https://analytics-pipeline-ghi789.run.app",
        "last_deployed": "2026-04-10T16:45:00Z",
        "issue": "CrashLoopBackOff: OOM killed",
    },
]

def get_resources() -> list[dict]:
    """Get all cloud resources in the current project.
    Returns a list of cloud infrastructure resources including their
    name, type, region, status, and type-specific details.
    Status is one of: healthy, warning, error. Resources with
    warning or error status include an 'issue' field describing
    the problem.
    """
    return RESOURCES

Definir o agente

Crie a2ui_agent/agent.py com o conteúdo a seguir:

from google.adk.agents import Agent
from .resources import get_resources

root_agent = Agent(
    model="gemini-3-flash-preview",
    name="cloud_dashboard",
    description="A cloud infrastructure assistant that reports on project resources.",
    instruction=(
        "You are a cloud infrastructure assistant. When users ask about their "
        "cloud resources, use the get_resources tool to fetch the current state. "
        "Summarize the results clearly in plain text."
    ),
    tools=[get_resources],
)

4. Testar o agente

O ADK inclui uma interface de desenvolvimento que pode ser usada para interagir e enviar comandos ao agente em um navegador para testes.

Iniciar a interface de desenvolvimento do ADK

No terminal do editor do Cloud Shell, execute o comando a seguir para iniciar a interface de desenvolvimento do ADK:

adk web --port 8080 --allow_origins "*" --reload_agents

Você verá uma mensagem semelhante a esta:

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://127.0.0.1:8080.                         |
+-----------------------------------------------------------------------------+

Abrir a interface de desenvolvimento do ADK

É possível abrir a interface de desenvolvimento do ADK no navegador clicando em Ctrl ou Cmd no URL de teste local ou clicando no botão Visualização da Web e selecionando Visualizar na porta 8080.

Depois de abrir a interface de desenvolvimento do ADK, selecione a2ui_agent no menu suspenso.

Enviar comandos de amostra

Envie um comando de amostra para o agente:

What's running in my project?

Agora tente outro comando de amostra e você vai receber mais saída de texto:

Does anything need my attention?

Sua conversa será semelhante a esta:

Agente de texto do ADK

Você vai receber um bloco de texto. Preciso, mas não é uma ótima experiência do usuário.

5. Gerar JSON A2UI

E se o agente pudesse descrever uma interface em vez de despejar texto? A A2UI é um protocolo que permite que os agentes criem interfaces interativas a partir de um catálogo de 18 primitivos. O cliente as renderiza de forma nativa.

O SDK da A2UI para Python inclui um gerenciador de esquemas que gera comandos do sistema para você. Ele ensina ao LLM o catálogo completo de componentes da A2UI, os nomes e tipos de propriedades corretos e a estrutura JSON.

Atualizar o agente

Substitua o conteúdo de a2ui_agent/agent.py pelo seguinte:

from google.adk.agents import Agent
from a2ui.schema.manager import A2uiSchemaManager
from a2ui.basic_catalog.provider import BasicCatalog
from .resources import get_resources

schema_manager = A2uiSchemaManager(
    version="0.8",
    catalogs=[BasicCatalog.get_config("0.8")],
)

instruction = schema_manager.generate_system_prompt(
    role_description=(
        "You are a cloud infrastructure assistant. When users ask about "
        "their cloud resources, use the get_resources tool to fetch the "
        "current state."
    ),
    workflow_description=(
        "Analyze the user's request and return structured UI when appropriate."
    ),
    ui_description=(
        "Use cards for resource summaries, rows and columns for comparisons, "
        "icons for status indicators, and buttons for drill-down actions. "
        "Do NOT use markdown formatting in text values. Use the usageHint "
        "property for heading levels instead. "
        "Respond ONLY with the A2UI JSON array. Do NOT include any text "
        "outside the JSON. Put all explanations into Text components."
    ),
    include_schema=True,
    include_examples=True,
)

root_agent = Agent(
    model="gemini-3-flash-preview",
    name="cloud_dashboard",
    description="A cloud infrastructure assistant that renders rich A2UI interfaces.",
    instruction=instruction,
    tools=[get_resources],
)

O método generate_system_prompt() combina a descrição do papel com o esquema JSON completo da A2UI e exemplos de poucos disparos para que o LLM saiba exatamente como formatar a saída. Não é necessário escrever o catálogo de componentes manualmente.

6. Testar a saída JSON

Se você ainda tiver a interface de desenvolvimento do ADK em execução, ela vai recarregar automaticamente as mudanças feitas no agente.

Selecione a2ui_agent, inicie uma nova sessão clicando em +Nova sessão no canto superior direito da interface de desenvolvimento do ADK e envie o mesmo comando de antes:

What's running in my project?

Desta vez, o agente responde com JSON A2UI em vez de texto simples. Você vai ver mensagens estruturadas contendo beginRendering, surfaceUpdate e dataModelUpdate na saída do chat.

JSON da A2UI do ADK

O JSON descreve uma interface avançada com cards, ícones e botões, mas adk web a mostra como texto bruto. Na próxima etapa, você vai fazer com que ela seja renderizada como componentes reais da interface.

7. Entender a A2UI

Confira o JSON que o agente acabou de gerar. Você vai notar que ele contém três tipos de mensagens. Cada resposta da A2UI segue a mesma estrutura:

1. beginRendering

Cria uma superfície de renderização e nomeia o componente raiz:

{"beginRendering": {"surfaceId": "default", "root": "main-column"}}

2. surfaceUpdate

Envia a árvore de componentes como uma lista simples com referências de ID (não aninhadas):

{"surfaceUpdate": {"surfaceId": "default", "components": [
  {"id": "main-column", "component": {"Column": {"children": {"explicitList": ["title", "card1"]}}}},
  {"id": "title", "component": {"Text": {"text": {"literalString": "My Resources"}, "usageHint": "h1"}}},
  {"id": "card1", "component": {"Card": {"child": "card1-content"}}},
  {"id": "card1-content", "component": {"Text": {"text": {"path": "service_name"}}}}
]}}

3. dataModelUpdate

Envia os dados separadamente da estrutura:

{"dataModelUpdate": {"surfaceId": "default", "contents": [
  {"key": "service_name", "valueString": "auth-service"},
  {"key": "status", "valueString": "healthy"}
]}}

Os componentes são vinculados aos dados usando {"path": "key"}. É possível atualizar os dados sem reenviar a árvore de componentes.

Os 18 primitivos

Categoria

Componentes

Layout

Card, Column, Row, List, Tabs, Divider, Modal

Display

Text, Image, Icon, Video, AudioPlayer

Entrada

TextField, DateTimeInput, MultipleChoice, CheckBox, Slider

Ação

Botão

O agente compõe layouts diferentes do mesmo catálogo. Consulte a referência de componentes para conferir todos os detalhes de cada primitivo. Uma visualização de navegação, um painel de prioridade e um formulário de configuração usam esses mesmos 18 primitivos. Não são necessários novos componentes de front-end.

8. Renderizar componentes A2UI

O agente gera JSON A2UI válido, mas adk web o mostra como texto bruto. Para renderizá-lo como componentes reais da interface, é necessário um pequeno utilitário que converta a saída JSON A2UI do agente no formato esperado pelo renderizador integrado do adk web.

Criar o utilitário de renderização da A2UI

Crie a2ui_agent/a2ui_utils.py com o conteúdo a seguir:

import json
import re
from google.genai import types
from google.adk.agents.callback_context import CallbackContext
from google.adk.models.llm_response import LlmResponse

def _wrap_a2ui_part(a2ui_message: dict) -> types.Part:
    """Wrap a single A2UI message for rendering in adk web."""
    datapart_json = json.dumps({
        "kind": "data",
        "metadata": {"mimeType": "application/json+a2ui"},
        "data": a2ui_message,
    })
    blob_data = (
        b"<a2a_datapart_json>"
        + datapart_json.encode("utf-8")
        + b"</a2a_datapart_json>"
    )
    return types.Part(
        inline_data=types.Blob(
            data=blob_data,
            mime_type="text/plain",
        )
    )

def a2ui_callback(
    callback_context: CallbackContext,
    llm_response: LlmResponse,
) -> LlmResponse | None:
    """Convert A2UI JSON in text output to rendered components."""
    if not llm_response.content or not llm_response.content.parts:
        return None
    for part in llm_response.content.parts:
        if not part.text:
            continue
        text = part.text.strip()
        if not text:
            continue
        if not any(k in text for k in ("beginRendering", "surfaceUpdate", "dataModelUpdate")):
            continue
        # Strip markdown fences
        if text.startswith("```"):
            text = text.split("\n", 1)[-1]
            if text.endswith("```"):
                text = text[:-3].strip()
        # Find where JSON starts (skip conversational prefix)
        json_start = None
        for i, ch in enumerate(text):
            if ch in ("[", "{"):
                json_start = i
                break
        if json_start is None:
            continue
        json_text = text[json_start:]
        # raw_decode parses JSON and ignores trailing text
        try:
            parsed, _ = json.JSONDecoder().raw_decode(json_text)
        except json.JSONDecodeError:
            # Handle concatenated JSON objects: {"a":1} {"b":2}
            try:
                fixed = "[" + re.sub(r'\}\s*\{', '},{', json_text) + "]"
                parsed, _ = json.JSONDecoder().raw_decode(fixed)
            except json.JSONDecodeError:
                continue
        if not isinstance(parsed, list):
            parsed = [parsed]
        a2ui_keys = {"beginRendering", "surfaceUpdate", "dataModelUpdate", "deleteSurface"}
        a2ui_messages = [msg for msg in parsed if isinstance(msg, dict) and any(k in msg for k in a2ui_keys)]
        if not a2ui_messages:
            continue
        new_parts = [_wrap_a2ui_part(msg) for msg in a2ui_messages]
        return LlmResponse(
            content=types.Content(role="model", parts=new_parts),
            custom_metadata={"a2a:response": "true"},
        )
    return None

Esse utilitário faz duas coisas:

  1. Extrai o JSON A2UI da saída de texto do agente
  2. Encapsula cada mensagem A2UI no formato esperado pelo renderizador A2UI integrado do adk web

Atualizar o agente

Substitua o conteúdo de a2ui_agent/agent.py pelo seguinte. A única mudança em relação à etapa anterior é a importação de a2ui_callback e o parâmetro after_model_callback no agente:

from google.adk.agents import Agent
from a2ui.schema.manager import A2uiSchemaManager
from a2ui.basic_catalog.provider import BasicCatalog
from .resources import get_resources
from .a2ui_utils import a2ui_callback

schema_manager = A2uiSchemaManager(
    version="0.8",
    catalogs=[BasicCatalog.get_config("0.8")],
)

instruction = schema_manager.generate_system_prompt(
    role_description=(
        "You are a cloud infrastructure assistant. When users ask about "
        "their cloud resources, use the get_resources tool to fetch the "
        "current state."
    ),
    workflow_description=(
        "Analyze the user's request and return structured UI when appropriate."
    ),
    ui_description=(
        "Use cards for resource summaries, rows and columns for comparisons, "
        "icons for status indicators, and buttons for drill-down actions. "
        "Do NOT use markdown formatting in text values. Use the usageHint "
        "property for heading levels instead. "
        "Respond ONLY with the A2UI JSON array. Do NOT include any text "
        "outside the JSON. Put all explanations into Text components."
    ),
    include_schema=True,
    include_examples=True,
)

root_agent = Agent(
    model="gemini-3-flash-preview",
    name="cloud_dashboard",
    description="A cloud infrastructure assistant that renders rich A2UI interfaces.",
    instruction=instruction,
    tools=[get_resources],
    after_model_callback=a2ui_callback,
)

9. Testar a interface renderizada

Se você ainda tiver a interface de desenvolvimento do ADK em execução, ela vai recarregar automaticamente as mudanças feitas no agente.

Atualize a guia do navegador, selecione a2ui_agent, inicie uma nova sessão clicando em +Nova sessão no canto superior direito da interface de desenvolvimento do ADK e envie o mesmo comando de antes:

What's running in my project?

Desta vez, adk web renderiza os componentes A2UI como interface real: cards com indicadores de status, detalhes de recursos e botões de ação.

Agente A2UI do ADK

Tente um comando diferente para conferir como o agente compõe uma interface diferente do mesmo conjunto de primitivos:

Does anything need my attention?

Por fim, tente outro comando para gerar uma interface diferente para implantar um novo serviço:

I need to deploy a new service

Cada comando vai para o mesmo agente, a mesma ferramenta e os mesmos 18 primitivos. No entanto, cada comando resulta em uma interface diferente para uma intent diferente.

10. Limpeza

Para evitar que os servidores locais permaneçam em execução, limpe os recursos:

  • No terminal que executa adk web, pressione Ctrl+C para interromper o servidor do agente.

Se você criou um projeto especificamente para este codelab, exclua o projeto inteiro:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}

11. Parabéns

Você criou um agente do ADK que gera uma interface interativa e avançada usando a A2UI.

O que você aprendeu

  • A A2UI é um protocolo com 18 primitivos declarativos e 3 tipos de mensagem
  • O SDK da A2UI gera comandos do sistema que ensinam o catálogo de componentes ao LLM
  • O mesmo agente, ferramenta e primitivos compõem interfaces diferentes para intents diferentes
  • Os componentes A2UI podem ser renderizados diretamente em adk web durante o desenvolvimento

Criar um front-end de produção

Neste codelab, você renderizou a A2UI dentro de adk web para desenvolvimento e testes.

Para produção, você criaria um front-end usando um dos renderizadores oficiais da A2UI:

Plataforma

Renderizador

Instalar

Web (React)

@a2ui/react

npm install @a2ui/react

Web (Lit)

@a2ui/lit

npm install @a2ui/lit

Web (Angular)

@a2ui/angular

npm install @a2ui/angular

Dispositivo móvel/computador

SDK do Flutter GenUI

Primeiros passos

Documentos de referência