1. Présentation
La plupart des applications d'agent renvoient du texte brut. A2UI change la donne. Il s'agit d'un protocole avec 18 primitives d'UI déclaratives qui permettent à votre agent de composer des interfaces interactives enrichies. Le client les affiche de manière native. Aucun nouveau code de frontend n'est nécessaire par mise en page.
Cet atelier de programmation utilise Agent Development Kit (ADK) pour créer l'agent et A2UI pour générer l'UI.
Objectifs de l'atelier
Un tableau de bord d'infrastructure cloud en trois étapes :
- Un agent standard qui renvoie des données de ressources sous forme de texte brut
- Un agent A2UI qui renvoie les mêmes données au format JSON A2UI structuré
- Un agent rendu qui affiche le JSON A2UI sous forme de composants d'UI interactifs dans l'UI de développement ADK

Points abordés
- Fonctionnement d'A2UI : 18 primitives, 3 types de messages, modèle de composant plat
- Utilisation du SDK A2UI pour inviter un agent ADK à générer du JSON A2UI
- Rendu des composants A2UI dans
adk web
Ce dont vous avez besoin
- Un projet Google Cloud avec facturation activée
- Un navigateur Web (par exemple, Chrome)
- Python 3.12 ou version ultérieure
Cet atelier de programmation est destiné aux développeurs intermédiaires qui connaissent Python et Google Cloud.
Cet atelier de programmation prend environ 15 à 20 minutes.
Les ressources créées dans cet atelier de programmation devraient coûter moins de 5 $.
2. Configurer votre environnement
Créer un projet Google Cloud
- Dans la console Google Cloud, sur la page du sélecteur de projet, sélectionnez ou créez un projet Google Cloud.
- Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier si la facturation est activée sur un projet.
Ouvrir l'éditeur Cloud Shell
Pour lancer une session Cloud Shell à partir de la console Google Cloud, cliquez sur Activer Cloud Shell dans votre console Google Cloud.
Une session s'ouvre dans le volet inférieur de votre console Google Cloud.
Pour lancer l'éditeur, cliquez sur Ouvrir l'éditeur dans la barre d'outils de la fenêtre Cloud Shell.
Définir des variables d'environnement
Dans la barre d'outils de l'éditeur Cloud Shell, cliquez sur Terminal , puis sur Nouveau terminal . Exécutez ensuite les commandes suivantes pour définir votre projet et votre emplacement, et configurez ADK pour qu'il utilise Gemini dans Vertex AI.
export GOOGLE_CLOUD_PROJECT=<INSERT_YOUR_GCP_PROJECT_HERE> export GOOGLE_CLOUD_LOCATION=global export GOOGLE_GENAI_USE_VERTEXAI=True
Activer les API
Dans le terminal, exécutez la commande suivante pour activer les API requises :
gcloud services enable aiplatform.googleapis.com
Installer des dépendances
Dans le terminal, exécutez la commande suivante pour installer la dernière version d'Agent Development Kit (ADK) :
pip install -U google-adk a2ui-agent-sdk export PATH="$HOME/.local/bin:$PATH"
3. Créer l'agent
Commencez par un agent ADK standard qui renvoie du texte brut. C'est à quoi ressemblent la plupart des applications d'agent aujourd'hui.
Créer un dossier d'agent
Créez un dossier appelé a2ui_agent qui contiendra le code source de votre agent et de vos outils.
Définir l'outil et les données simulées
Créez a2ui_agent/resources.py avec le contenu suivant. Cet outil renvoie une liste de ressources cloud avec leur état.
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
Définir l'agent
Créez a2ui_agent/agent.py avec le contenu suivant :
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. Tester l'agent
ADK inclut une UI de développement que vous pouvez utiliser pour interagir avec votre agent et lui envoyer des requêtes dans un navigateur à des fins de test.
Démarrer l'UI de développement ADK
Dans le terminal de l'éditeur Cloud Shell, exécutez la commande suivante pour démarrer l'UI de développement ADK :
adk web --port 8080 --allow_origins "*" --reload_agents
Un message semblable au suivant doit s'afficher :
+-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://127.0.0.1:8080. | +-----------------------------------------------------------------------------+
Ouvrir l'UI de développement ADK
Vous pouvez ouvrir l'UI de développement ADK dans votre navigateur en cliquant sur l'URL de test local avec Ctrl ou Cmd, ou en cliquant sur le bouton Aperçu sur le Web et en sélectionnant Prévisualiser sur le port 8080.
Une fois que vous affichez l'UI de développement ADK, sélectionnez a2ui_agent dans le menu déroulant.
Envoyer des exemples de requêtes
Envoyez un exemple de requête à l'agent :
What's running in my project?
Essayez maintenant un autre exemple de requête. Vous obtiendrez plus de texte :
Does anything need my attention?
Votre conversation doit ressembler à ceci :

Vous obtenez un mur de texte. C'est précis, mais l'expérience utilisateur n'est pas optimale.
5. Générer du JSON A2UI
Et si l'agent pouvait décrire une UI au lieu de vider du texte ? A2UI est un protocole qui permet aux agents de composer des interfaces interactives à partir d'un catalogue de 18 primitives. Le client les affiche de manière native.
Le SDK Python A2UI inclut un gestionnaire de schéma qui génère des requêtes système pour vous. Il enseigne au LLM le catalogue complet des composants A2UI, les noms et types de propriétés corrects, ainsi que la structure JSON.
Mettre à jour l'agent
Remplacez le contenu de a2ui_agent/agent.py par le code suivant :
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],
)
La méthode generate_system_prompt() combine la description de votre rôle avec le schéma JSON A2UI complet et quelques exemples de few-shot, afin que le LLM sache exactement comment formater sa sortie. Vous n'avez pas besoin d'écrire le catalogue de composants à la main.
6. Tester la sortie JSON
Si l'UI de développement ADK est toujours en cours d'exécution, elle devrait recharger automatiquement les modifications que vous avez apportées à votre agent.
Sélectionnez a2ui_agent, démarrez une nouvelle session en cliquant sur + Nouvelle session en haut à droite de l'UI de développement ADK, puis envoyez la même requête qu'auparavant :
What's running in my project?
Cette fois, l'agent répond avec du JSON A2UI au lieu de texte brut. Vous verrez des messages structurés contenant beginRendering, surfaceUpdate et dataModelUpdate dans la sortie du chat.

Le JSON décrit une UI enrichie avec des cartes, des icônes et des boutons, mais adk web l'affiche sous forme de texte brut. À l'étape suivante, vous allez le rendre sous forme de composants d'UI réels.
7. Comprendre A2UI
Examinez le JSON que votre agent vient de générer. Vous remarquerez qu'il contient trois types de messages. Chaque réponse A2UI suit la même structure :
1. beginRendering
Crée une surface de rendu et nomme le composant racine :
{"beginRendering": {"surfaceId": "default", "root": "main-column"}}
2. surfaceUpdate
Envoie l'arborescence des composants sous forme de liste plate avec des références d'ID (non imbriquées) :
{"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
Envoie les données séparément de la structure :
{"dataModelUpdate": {"surfaceId": "default", "contents": [
{"key": "service_name", "valueString": "auth-service"},
{"key": "status", "valueString": "healthy"}
]}}
Les composants sont liés aux données à l'aide de {"path": "key"}. Vous pouvez mettre à jour les données sans renvoyer l'arborescence des composants.
Les 18 primitives
Catégorie | Composants |
Disposition | Carte, Colonne, Ligne, Liste, Onglets, Séparateur, Modal |
Écran | Texte, Image, Icône, Vidéo, Lecteur audio |
Entrée | Champ de texte, Entrée de date et d'heure, Choix multiple, Case à cocher, Curseur |
Action | Bouton |
L'agent compose différentes mises en page à partir du même catalogue. Pour en savoir plus sur chaque primitive, consultez la référence des composants. Une vue de navigation, un tableau de bord de priorité et un formulaire de configuration utilisent tous ces 18 primitives. Aucun nouveau composant de frontend n'est nécessaire.
8. Afficher les composants A2UI
L'agent génère un JSON A2UI valide, mais adk web l'affiche sous forme de texte brut. Pour l'afficher sous forme de composants d'UI réels, vous avez besoin d'un petit utilitaire qui convertit la sortie JSON A2UI de l'agent au format attendu par le moteur de rendu intégré d'adk web.
Créer l'utilitaire de rendu A2UI
Créez a2ui_agent/a2ui_utils.py avec le contenu suivant :
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
Cet utilitaire effectue deux opérations :
- Extrait le JSON A2UI de la sortie de texte de l'agent
- Encapsule chaque message A2UI au format attendu par le moteur de rendu A2UI intégré d'
adk web
Mettre à jour l'agent
Remplacez le contenu de a2ui_agent/agent.py par le code suivant. La seule différence par rapport à l'étape précédente est l'importation d'a2ui_callback et le paramètre after_model_callback sur l'agent :
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. Tester l'UI affichée
Si l'UI de développement ADK est toujours en cours d'exécution, elle devrait recharger automatiquement les modifications que vous avez apportées à votre agent.
Actualisez l'onglet du navigateur, sélectionnez a2ui_agent, puis démarrez une nouvelle session en cliquant sur + Nouvelle session en haut à droite de l'UI de développement ADK et envoyez la même requête qu'auparavant :
What's running in my project?
Cette fois, adk web affiche les composants A2UI sous forme d'UI réels : des cartes avec des indicateurs d'état, des détails sur les ressources et des boutons d'action.

Essayez une autre requête pour voir comment l'agent compose une autre UI à partir du même ensemble de primitives :
Does anything need my attention?
Enfin, essayez une autre requête pour générer une autre UI afin de déployer un nouveau service :
I need to deploy a new service
Chaque requête est envoyée au même agent, au même outil et aux mêmes 18 primitives. Toutefois, chaque requête génère une UI différente pour une intention différente.
10. Effectuer un nettoyage
Pour éviter de laisser des serveurs locaux en cours d'exécution, nettoyez les ressources :
- Dans le terminal exécutant
adk web, appuyez sur Ctrl+C pour arrêter le serveur d'agent.
Si vous avez créé un projet spécifiquement pour cet atelier de programmation, vous pouvez le supprimer entièrement :
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
11. Félicitations
Vous avez créé un agent ADK qui génère une UI interactive enrichie à l'aide d'A2UI.
Ce que vous avez appris
- A2UI est un protocole avec 18 primitives déclaratives et 3 types de messages.
- Le SDK A2UI génère des requêtes système qui enseignent au LLM le catalogue de composants.
- Le même agent, le même outil et les mêmes primitives composent différentes UI pour différentes intentions.
- Les composants A2UI peuvent être affichés directement dans
adk weblors du développement.
Créer un frontend de production
Dans cet atelier de programmation, vous avez affiché A2UI dans adk web à des fins de développement et de test.
Pour la production, vous devez créer un frontend à l'aide de l'un des moteurs de rendu A2UI officiels :
Plate-forme | Moteur de rendu | Installer |
Web (React) |
|
|
Web (Lit) |
|
|
Web (Angular) |
|
|
Mobile/Ordinateur | SDK Flutter GenUI |