Expériences frontend avec ADK et A2UI

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 :

  1. Un agent standard qui renvoie des données de ressources sous forme de texte brut
  2. Un agent A2UI qui renvoie les mêmes données au format JSON A2UI structuré
  3. Un agent rendu qui affiche le JSON A2UI sous forme de composants d'UI interactifs dans l'UI de développement ADK

Agent ADK A2UI

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

  1. Dans la console Google Cloud, sur la page du sélecteur de projet, sélectionnez ou créez un projet Google Cloud.
  2. 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 :

Agent de texte ADK

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.

ADK A2UI JSON

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 :

  1. Extrait le JSON A2UI de la sortie de texte de l'agent
  2. 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.

Agent ADK A2UI

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 web lors 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)

@a2ui/react

npm install @a2ui/react

Web (Lit)

@a2ui/lit

npm install @a2ui/lit

Web (Angular)

@a2ui/angular

npm install @a2ui/angular

Mobile/Ordinateur

SDK Flutter GenUI

Premiers pas

Documents de référence