1. Descripción general
La mayoría de las apps de agentes muestran texto sin formato. A2UI cambia eso. Es un protocolo con 18 primitivas de IU declarativas que permiten que tu agente cree interfaces interactivas y enriquecidas. El cliente las renderiza de forma nativa. No se necesita código de frontend nuevo por diseño.
En este codelab, se usa el Kit de desarrollo de agentes (ADK) para compilar el agente y A2UI para generar la IU.
Qué compilarás
Un panel de infraestructura de nube en tres etapas:
- Un agente estándar que devuelve datos de recursos como texto sin formato
- Un agente A2UI que devuelve los mismos datos que el JSON A2UI estructurado
- Un agente renderizado que muestra el JSON A2UI como componentes de IU interactivos en la IU de desarrollo del ADK

Qué aprenderás
- Cómo funciona A2UI: 18 primitivas, 3 tipos de mensajes, modelo de componentes planos
- Cómo usar el SDK de A2UI para solicitarle a un agente del ADK que genere JSON A2UI
- Cómo renderizar componentes A2UI en
adk web
Requisitos
- Un proyecto de Google Cloud con la facturación habilitada.
- Un navegador web, como Chrome
- Python 3.12 o versiones posteriores
Este codelab está destinado a desarrolladores de nivel intermedio que tengan cierta familiaridad con Python y Google Cloud.
Este codelab tarda aproximadamente entre 15 y 20 minutos en completarse.
Los recursos creados en este codelab deberían costar menos de USD 5.
2. Configura tu entorno
Cómo crear un proyecto de Google Cloud
- En la consola de Google Cloud, en la página del selector de proyectos, selecciona o crea un proyecto de Google Cloud.
- Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Obtén información para verificar si la facturación está habilitada en un proyecto.
Inicia el editor de Cloud Shell
Para iniciar una sesión de Cloud Shell desde la consola de Google Cloud, haz clic en Activar Cloud Shell en la consola de Google Cloud.
Esto inicia una sesión en el panel inferior de la consola de Google Cloud.
Para iniciar el editor, haz clic en Abrir editor en la barra de herramientas de la ventana de Cloud Shell.
Configura las variables de entorno
En la barra de herramientas del editor de Cloud Shell, haz clic en Terminal y Terminal nueva y, luego, ejecuta los siguientes comandos para configurar tu proyecto, ubicación y el ADK para usar Gemini en Vertex AI.
export GOOGLE_CLOUD_PROJECT=<INSERT_YOUR_GCP_PROJECT_HERE> export GOOGLE_CLOUD_LOCATION=global export GOOGLE_GENAI_USE_VERTEXAI=True
Habilita las APIs
En la terminal, ejecuta el siguiente comando para habilitar las APIs requeridas:
gcloud services enable aiplatform.googleapis.com
Instala dependencias
En la terminal, ejecuta el siguiente comando para instalar la versión más reciente del Kit de desarrollo de agentes (ADK):
pip install -U google-adk a2ui-agent-sdk export PATH="$HOME/.local/bin:$PATH"
3. Compila el agente
Comienza con un agente estándar del ADK que devuelve texto sin formato. Así es como se ven la mayoría de las apps de agentes en la actualidad.
Crea la carpeta del agente
Crea una carpeta llamada a2ui_agent que contendrá el código fuente de tu agente y las herramientas.
Define la herramienta y los datos simulados
Crea a2ui_agent/resources.py con el siguiente contenido. Esta herramienta devuelve una lista de recursos de la nube con su estado.
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
Define el agente
Crea a2ui_agent/agent.py con el siguiente contenido:
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. Prueba el agente
El ADK incluye una IU de desarrollo que puedes usar para interactuar con tu agente y enviarle instrucciones en un navegador para realizar pruebas.
Inicia la IU de desarrollo del ADK
En la terminal del editor de Cloud Shell, ejecuta el siguiente comando para iniciar la IU de desarrollo del ADK:
adk web --port 8080 --allow_origins "*" --reload_agents
Deberías ver un mensaje similar al siguiente:
+-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://127.0.0.1:8080. | +-----------------------------------------------------------------------------+
Abre la IU de desarrollo del ADK
Para abrir la IU de desarrollo del ADK en tu navegador, presiona Ctrl o Cmd y haz clic en la URL de prueba local, o bien haz clic en el botón Vista previa en la Web y selecciona Vista previa en el puerto 8080.
Una vez que veas la IU de desarrollo del ADK, selecciona a2ui_agent en el menú desplegable.
Envía instrucciones de muestra
Envía una instrucción de muestra al agente:
What's running in my project?
Ahora, prueba con otra instrucción de muestra y obtendrás más texto de salida:
Does anything need my attention?
Tu conversación debería ser similar a la siguiente:

Obtendrás una gran cantidad de texto. Es preciso, pero no es una buena experiencia del usuario.
5. Genera JSON A2UI
¿Qué sucede si el agente puede describir una IU en lugar de volcar texto? A2UI es un protocolo que permite que los agentes creen interfaces interactivas a partir de un catálogo de 18 primitivas. El cliente las renderiza de forma nativa.
El SDK de Python de A2UI incluye un administrador de esquemas que genera instrucciones del sistema por ti. Le enseña al LLM el catálogo completo de componentes de A2UI, los nombres y tipos de propiedades correctos y la estructura JSON.
Actualiza el agente
Reemplaza el contenido de a2ui_agent/agent.py por lo siguiente:
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],
)
El método generate_system_prompt() combina la descripción de tu rol con el esquema JSON A2UI completo y ejemplos de pocas tomas, de modo que el LLM sepa exactamente cómo dar formato a su resultado. No es necesario que escribas el catálogo de componentes a mano.
6. Prueba el resultado JSON
Si aún tienes en ejecución la IU de desarrollo del ADK de antes, debería volver a cargar automáticamente los cambios que realizaste en tu agente.
Selecciona a2ui_agent, inicia una nueva sesión haciendo clic en +Nueva sesión en la parte superior derecha de la IU de desarrollo del ADK y, luego, envía la misma instrucción que antes:
What's running in my project?
Esta vez, el agente responde con JSON A2UI en lugar de texto sin formato. Verás mensajes estructurados que contienen beginRendering, surfaceUpdate y dataModelUpdate en el resultado del chat.

El JSON describe una IU enriquecida con tarjetas, íconos y botones, pero adk web la muestra como texto sin procesar. En el siguiente paso, harás que se renderice como componentes de IU reales.
7. Comprende A2UI
Observa el JSON que acaba de generar tu agente. Notarás que contiene tres tipos de mensajes. Cada respuesta de A2UI sigue esta misma estructura:
1. beginRendering
Crea una superficie de renderización y nombra el componente raíz:
{"beginRendering": {"surfaceId": "default", "root": "main-column"}}
2. surfaceUpdate
Envía el árbol de componentes como una lista plana con referencias de ID (no anidadas):
{"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
Envía los datos por separado de la estructura:
{"dataModelUpdate": {"surfaceId": "default", "contents": [
{"key": "service_name", "valueString": "auth-service"},
{"key": "status", "valueString": "healthy"}
]}}
Los componentes se vinculan a los datos con {"path": "key"}. Puedes actualizar los datos sin volver a enviar el árbol de componentes.
Las 18 primitivas
Categoría | Componentes |
Diseño | Tarjeta, Columna, Fila, Lista, Pestañas, Divisor, Modal |
Pantalla | Texto, Imagen, Ícono, Video, AudioPlayer |
Entrada | TextField, DateTimeInput, MultipleChoice, Casilla de verificación, Slider |
Acción | Botón |
El agente compone diferentes diseños del mismo catálogo. Consulta la referencia de componentes para obtener detalles completos sobre cada primitiva. Una vista de exploración, un panel de prioridad y un formulario de configuración usan estas mismas 18 primitivas. No se necesitan componentes de frontend nuevos.
8. Renderiza componentes A2UI
El agente genera JSON A2UI válido, pero adk web lo muestra como texto sin procesar. Para renderizarlo como componentes de IU reales, necesitas una pequeña utilidad que convierta el resultado JSON A2UI del agente al formato que espera el procesador integrado de adk web.
Crea la utilidad de renderización de A2UI
Crea a2ui_agent/a2ui_utils.py con el siguiente contenido:
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
Esta utilidad hace dos cosas:
- Extrae JSON A2UI del resultado de texto del agente.
- Ajusta cada mensaje A2UI al formato que espera el procesador A2UI integrado de
adk web.
Actualiza el agente
Reemplaza el contenido de a2ui_agent/agent.py por lo siguiente. El único cambio con respecto al paso anterior es la importación de a2ui_callback y el parámetro after_model_callback en el 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. Prueba la IU renderizada
Si aún tienes en ejecución la IU de desarrollo del ADK de antes, debería volver a cargar automáticamente los cambios que realizaste en tu agente.
Actualiza la pestaña del navegador, selecciona a2ui_agent, inicia una nueva sesión haciendo clic en +Nueva sesión en la parte superior derecha de la IU de desarrollo del ADK y, luego, envía la misma instrucción que antes:
What's running in my project?
Esta vez, adk web renderiza los componentes A2UI como IU real: tarjetas con indicadores de estado, detalles de recursos y botones de acción.

Prueba con otra instrucción para ver cómo el agente compone una IU diferente del mismo conjunto de primitivas:
Does anything need my attention?
Por último, prueba con otra instrucción para generar una IU diferente para implementar un servicio nuevo:
I need to deploy a new service
Cada instrucción va al mismo agente, a la misma herramienta y a las mismas 18 primitivas. Sin embargo, cada instrucción genera una IU diferente para una intención diferente.
10. Limpieza
Para evitar dejar servidores locales en ejecución, limpia los recursos:
- En la terminal que ejecuta
adk web, presiona Ctrl+C para detener el servidor del agente.
Si creaste un proyecto específicamente para este codelab, puedes borrar todo el proyecto:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
11. Felicitaciones
Compilaste un agente del ADK que genera una IU interactiva y enriquecida con A2UI.
Qué aprendiste
- A2UI es un protocolo con 18 primitivas declarativas y 3 tipos de mensajes.
- El SDK de A2UI genera instrucciones del sistema que le enseñan al LLM el catálogo de componentes.
- El mismo agente, la misma herramienta y las mismas primitivas componen diferentes IUs para diferentes intenciones.
- Los componentes A2UI se pueden renderizar directamente en
adk webdurante el desarrollo.
Compila un frontend de producción
En este codelab, renderizaste A2UI dentro de adk web para el desarrollo y las pruebas.
Para la producción, compilarías un frontend con uno de los renderizadores A2UI oficiales:
Plataforma | Procesador | Instalar |
Web (React) |
|
|
Web (Lit) |
|
|
Web (Angular) |
|
|
Dispositivos móviles o de escritorio | SDK de GenUI de Flutter |