Discours d'ouverture Next '26 pour les développeurs : améliorer les agents avec la mémoire

1. Introduction

Dans cet atelier de programmation, vous allez faire passer vos agents ADK au niveau supérieur en ajoutant des connaissances persistantes et spécialisées. Vous apprendrez à gérer l'état des conversations avec les sessions Agent Platform, à activer l'apprentissage à long terme avec Memory Bank et à intégrer des données complexes sur les règles de la ville à l'aide de Spark et d'AlloyDB pour la RAG (génération augmentée par récupération).

Objectifs de l'atelier

  • Configurer les sessions Agent Platform pour la persistance des conversations
  • Implémenter une banque de mémoire pour permettre aux agents d'apprendre à partir des interactions précédentes
  • Utiliser Spark Lightning Engine pour ingérer et traiter la documentation sur les règles de la ville
  • Créer un système RAG à l'aide d'AlloyDB et de la recherche vectorielle
  • Déployer l'agent amélioré sur Agent Platform

Ce dont vous avez besoin

  • Un navigateur Web (par exemple, Chrome)
  • Un projet Google Cloud avec facturation activée
  • Connaître les bases de Python et de SQL

Durée estimée : 60 minutes

Les ressources créées dans cet atelier de programmation devraient coûter moins de 5 $.

2. Avant de commencer

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 pour un projet.

Démarrer Cloud Shell

Cloud Shell est un environnement de ligne de commande exécuté dans Google Cloud, qui est préchargé avec les outils nécessaires.

  1. Cliquez sur Activer Cloud Shell en haut de la console Google Cloud.
  2. Une fois connecté à Cloud Shell, vérifiez votre authentification :
    gcloud auth list
    
  3. Vérifiez que votre projet est configuré :
    gcloud config get project
    
  4. Si votre projet n'est pas défini comme prévu, définissez-le :
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

Vérifiez l'authentification :

gcloud auth list

Confirmez votre projet :

gcloud config get project

Définissez-le si nécessaire :

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

Activer les API

Exécutez cette commande pour activer toutes les API requises pour la gestion des sessions, le traitement Spark et AlloyDB :

gcloud services enable \
  aiplatform.googleapis.com \
  run.googleapis.com \
  alloydb.googleapis.com \
  dataproc.googleapis.com \
  documentai.googleapis.com \
  storage.googleapis.com \
  secretmanager.googleapis.com

3. Configurer votre environnement

Pour cet atelier de programmation, vous allez utiliser l'environnement préconfiguré dans le dépôt de la présentation.

  1. Clonez le dépôt et accédez au dossier du projet :
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes
cd next-26-keynotes/devkey/enhancing-agents-with-memory
  1. Configurez un environnement virtuel Python et installez les packages ADK requis :
uv venv
source .venv/bin/activate
uv sync

Configurer les variables d'environnement

L'agent nécessite une configuration spécifique pour se connecter à Agent Platform et à AlloyDB.

  1. Copiez l'exemple de fichier d'environnement :
cp .env.example .env
  1. Ouvrez .env et mettez à jour les champs suivants :
    • GOOGLE_CLOUD_PROJECT : ID du projet.
    • GOOGLE_CLOUD_LOCATION: us-central1.
    • ALLOYDB_CLUSTER_ID: rules-db.
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_REGION=us-central1
ALLOYDB_CLUSTER_ID=rules-db
  1. Exécutez le script d'assistance suivant pour créer une instance Agent Engine à utiliser pour les sessions de conversation et la mémoire à long terme. Cela remplira automatiquement le champ AGENT_ENGINE_ID dans votre fichier .env :
uv run utils/setup_agent_engine.py

Une fois l'opération réussie, vous devriez voir :

Creating Agent Engine instance...
Successfully created Agent Engine. ID: 1234567890
Updated .env with AGENT_ENGINE_ID=1234567890

4. Créer un agent avec la gestion des sessions

Lors de cette étape, vous allez initialiser un agent de planification de marathon qui peut conserver l'historique des conversations sur plusieurs tours. Pour ce faire, utilisez la classe App de l'ADK et les sessions Agent Platform.

Initialiser l'agent et le service de session

Ouvrez planner_agent/agent.py. Vous verrez comment nous ajoutons une classe ADK pour intégrer les sessions Agent Platform. Cela nous permet de rendre nos agents avec état au fil du temps et de modifier le contexte si nécessaire.

from google.adk.agents import LlmAgent
from google.adk.sessions import VertexAiSessionService
from vertexai.agent_engines import AdkApp

PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT")
REGION = os.environ.get("GOOGLE_CLOUD_REGION", "us-central1")

# Initialize Vertex AI for regional services
if PROJECT_ID:
    vertexai.init(project=PROJECT_ID, location=REGION)

# Define the agent logic
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[] # We will add tools in the next steps
)

def session_service_builder():
    """Builder for Agent Platform Sessions."""
    return VertexAiSessionService(project=PROJECT_ID, location=REGION)

# Wrap the agent in an AdkApp to manage stateful context
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder
)

5. Activer l'apprentissage à long terme avec Memory Bank

Alors que la gestion des sessions suit les conversations individuelles, vous pouvez faire de même pour la mémoire à long terme. Lors de cette étape, vous allez associer l'agent à Memory Bank d'Agent Platform, un service de mémoire entièrement géré et prêt à l'emploi.

Initialiser le service Memory Bank

Memory Bank permet à l'agent de rappeler le contexte sur différentes sessions. Mettez à jour planner_agent/agent.py pour inclure le service de mémoire :

from google.adk.memory import VertexAiMemoryBankService

def memory_service_builder():
    """Builder for Agent Platform Memory Bank."""
    return VertexAiMemoryBankService(
        project=PROJECT_ID,
        location=REGION,
        agent_engine_id=AGENT_ENGINE_ID
    )

Implémenter l'ingestion automatique de mémoire

Pour que l'agent apprenne à chaque tour, nous ajoutons un after_agent_callback. Cette fonction est déclenchée une fois que l'agent a terminé une réponse, ce qui lui permet de "digérer" la session et d'enregistrer les souvenirs pertinents dans la banque.

  1. Définissez la fonction de rappel :
async def auto_save_memories(callback_context):
    """Callback to ingest the session into the memory bank after the turn."""
    # In AdkApp, the memory service is available via the invocation context
    if hasattr(callback_context._invocation_context, 'memory_service') and callback_context._invocation_context.memory_service:
        await callback_context._invocation_context.memory_service.add_session_to_memory(
            callback_context._invocation_context.session
        )
  1. Associez le rappel à LlmAgent :
root_agent = LlmAgent(
    # ... other params
    after_agent_callback=[auto_save_memories],
)

6. Configurer AlloyDB pour la RAG

Avant de pouvoir ingérer les données sur les règles de la ville, nous avons besoin d'une base de données hautes performances pour les stocker. Lors de cette étape, vous allez créer un cluster AlloyDB et initialiser le schéma de base de données pour la recherche vectorielle.

1. Créer le cluster AlloyDB et l'instance principale

Exécutez ces commandes dans Cloud Shell pour créer votre cluster et son instance principale :

# Create the cluster
gcloud alloydb clusters create rules-db \
  --password=postgres \
  --region=us-central1

# Create the primary instance with IAM authentication enabled
gcloud alloydb instances create rules-db-primary \
  --instance-type=PRIMARY \
  --cpu-count=2 \
  --region=us-central1 \
  --cluster=rules-db \
  --database-flags=alloydb.iam_authentication=on

2. Accorder les rôles IAM requis

Pour utiliser le serveur MCP AlloyDB géré, votre identité a besoin d'autorisations spécifiques. Exécutez ces commandes pour accorder les rôles requis :

export USER_EMAIL=$(gcloud config get-value account)

# Role to use MCP tools
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/mcp.toolUser"

# Role to execute SQL in AlloyDB
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.admin"

# Role for IAM database authentication
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.databaseUser"

# Create the IAM-based database user
gcloud alloydb users create "$USER_EMAIL" \
  --cluster=rules-db \
  --region=us-central1 \
  --type=IAM_BASED

3. Créer une base de données et des tables via AlloyDB Studio

Étant donné que les bases de données et les tables AlloyDB sont gérées via SQL, nous allons utiliser AlloyDB Studio dans la console Google Cloud pour finaliser le schéma.

  1. Accédez à AlloyDB > Clusters , puis cliquez sur rules-db.
  2. Dans le menu de navigation de gauche, cliquez sur AlloyDB Studio.
  3. Connectez-vous avec l'utilisateur postgres et le mot de passe que vous avez défini (postgres).
  4. Exécutez le code SQL suivant pour créer la base de données :
    CREATE DATABASE city_rules;
    
  5. Basculez votre connexion à la base de données vers city_rules dans AlloyDB Studio, puis exécutez le code SQL suivant pour installer les extensions et créer la table rules :
    -- Install extensions for vector search and ML
    CREATE EXTENSION IF NOT EXISTS vector;
    CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
    
    -- Create the rules table
    CREATE TABLE IF NOT EXISTS rules (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
        text TEXT NOT NULL,
        city TEXT NOT NULL,
        embedding vector(3072) DEFAULT NULL
    );
    
    -- Grant your IAM user access to the table (replace with your email)
    GRANT ALL PRIVILEGES ON TABLE rules TO "YOUR_EMAIL_ADDRESS";
    

7. Ingérer des données sur les règles de la ville avec Spark Lightning Engine

Pour fournir une planification vraiment précise, un agent a besoin de plus qu'un simple prompt bien conçu. Il doit être ancré dans les données et le contexte organisationnel. Lors de cette étape, vous allez utiliser Spark Lightning Engine sur Dataproc sans serveur pour traiter de grands PDF sur les règles de la ville et les ingérer dans AlloyDB.

Pourquoi utiliser Spark Lightning Engine ?

L'ancrage des agents à grande échelle nécessite le traitement de grandes quantités de données non structurées. Spark Lightning Engine est un moteur d'exécution hautes performances pour Spark qui accélère considérablement ces charges de travail. Nous l'utilisons ici pour effectuer un chunking sémantique sur les documents à l'aide de Document AI de Google.

Explorer le pipeline Spark

La logique d'ingestion est définie dans spark-setup/spark_alloydb_processor.py. Le pipeline suit les étapes suivantes :

  1. Lister les PDF : récupère les URI de documents à partir d'un bucket Cloud Storage Google.
  2. Extraction sémantique : utilise une UDF (fonction définie par l'utilisateur) pour appeler l'API Document AI.
  3. Écrire dans AlloyDB : enregistre les blocs de texte extraits dans la table AlloyDB nommée rules.
# Extract from spark_alloydb_processor.py
def process_document(gcs_uri: str):
    # ... calls Document AI to parse PDF ...
    return chunks

# Parallel processing with Spark Lightning Engine
process_udf = udf(process_document, chunk_schema)
chunked_df = uri_df.withColumn("chunks", process_udf(col("gcs_uri"))) \
                   .select(explode(col("chunks")).alias("chunk")) \
                   .select("chunk.*")

# Save to AlloyDB for Vector Search
chunked_df.write.format("jdbc") \
    .option("url", jdbc_url) \
    .option("dbtable", "rules") \
    .mode("append") \
    .save()

Exécuter le job d'ingestion

Déclenchez le processus d'ingestion à l'aide du script fourni :

./spark-setup/run_dataproc.sh

8. RAG avec AlloyDB

Maintenant que les données sur les règles de la ville se trouvent dans AlloyDB, l'agent peut les utiliser pour effectuer une génération augmentée par récupération (RAG). Cela garantit que le plan du marathon respecte les codes de ville spécifiques.

La puissance d'AlloyDB pour la RAG

AlloyDB excelle dans la recherche vectorielle, ce qui nous permet de stocker à la fois des données structurées et des embeddings vectoriels au même endroit. L'agent peut utiliser la fonction embedding intégrée dans AlloyDB pour trouver les informations les plus pertinentes sur les règles.

Pour donner à l'agent l'accès à ces données, nous fournissons un outil qui interroge AlloyDB à l'aide de la similarité vectorielle. Vous pouvez voir cette logique dans hybrid_recall.sql, qui montre comment calculer la distance entre une requête et nos règles stockées :

SELECT
    text,
    (embedding <=> 
     embedding('gemini-embedding-001', 
               'Restrictions for running a race on the Las Vegas strip')::vector) 
    as distance
FROM
    rules
WHERE city = 'Las Vegas'
ORDER BY
    distance ASC
LIMIT 5;

Ancrer l'agent dans les règles locales avec un outil RAG

Pour mettre l'outil à la disposition de l'agent, vous devez le définir dans planner_agent/tools.py, puis l'enregistrer dans planner_agent/agent.py. Nous allons utiliser le serveur MCP AlloyDB distant géré de Google Cloud pour nous connecter à notre base de données.

  1. Définissez l'outil dans planner_agent/tools.py à l'aide du modèle "Rappel hybride". Nous allons utiliser le protocole streamable_http pour nous connecter au serveur MCP AlloyDB géré :
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def get_local_and_traffic_rules(query: str) -> str:
    """Uses vector search in AlloyDB via managed MCP server."""
    # Vector search query using built-in AlloyDB embedding functions
    sql = f"SELECT text FROM rules WHERE city = 'Las Vegas' ORDER BY embedding <=> google_ml.embedding('gemini-embedding-001', '{query}')::vector ASC LIMIT 5;"
    
    # Establish a streamable HTTP connection to the MCP server
    async with streamablehttp_client(url, headers=get_auth_headers()) as (read_stream, write_stream, _):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()
            result = await session.call_tool(
                "execute_sql",
                arguments={
                    "instance": full_instance_name,
                    "database": "city_rules",
                    "sqlStatement": sql
                }
            )
            return "\n".join([c.text for c in result.content if hasattr(c, 'text')])
  1. Enregistrez l'outil et finalisez planner_agent/agent.py :
# ... imports ...

# Assemble the Agent
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
    ],
    after_agent_callback=[auto_save_memories],
)

# 2. Wrap the agent in an AdkApp to manage the stateful lifecycle
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder,
    memory_service_builder=memory_service_builder
)

9. Conseils d'experts avec les compétences de l'agent

Les compétences de l'agent sont des modules autonomes qui fournissent des instructions, des conseils et des ressources spécifiques pour aider les agents à effectuer des tâches plus efficacement. Au lieu d'encombrer votre prompt système avec des instructions complexes pour chaque outil, vous pouvez encapsuler cette expertise dans une compétence qui n'est chargée que lorsque cela est nécessaire.

Google fournit des compétences prédéfinies pour les produits Google (comme AlloyDB et BigQuery) afin de s'assurer que vos agents suivent les bonnes pratiques du secteur pour interroger les données et gérer les ressources. Vous pouvez explorer ces modèles et d'autres modèles spécialisés dans le dépôt de compétences Google. Vous trouverez les compétences de base d'AlloyDB ici.

1. Explorer le fichier de compétences

Ouvrez le fichier de compétences préconfiguré à l'adresse planner_agent/skills/get-local-and-traffic-rules/SKILL.md. Voici à quoi il ressemble :

---
name: get-local-and-traffic-rules
description: Retrieve local rules and traffic information for a specific jurisdiction.
---
# get_local_and_traffic_rules Skill

This skill provides guidelines on how to effectively use the `get_local_and_traffic_rules` tool.

## Overview
The `get_local_and_traffic_rules` tool interfaces with an AlloyDB database to perform vector similarity searches on a corpus of rules and traffic information using a provided natural language query.

## Usage Guidelines
1. **Query Specificity**: When calling the tool, provide specific details in the `query` argument. For example, instead of querying "food rules", use "rules regarding food vendors during public events".
2. **Contextual Use**: Use the tool when planning events or activities that require adherence to local municipal or state rules (e.g., street closures, noise ordinances, environmental rules).
3. **Handling Results**: The tool returns a string containing the text of the top 5 most relevant rules. If no error occurs, parse the returned string to inform your planning tasks.
4. **Error Handling**: If an error string is returned (e.g., "Error querying rules: ..."), you must report this failure or attempt an alternative approach if applicable.

## Underlying Mechanism
- The tool uses `google_ml.embedding` to convert the query into a vector representation.
- It calculates distance (`<=>`) against the `embedding` column in the `rules` table on an AlloyDB instance.
- Results are fetched in descending order of similarity, limited to 5 results.

2. Comment la compétence est-elle enregistrée ?

Dans planner_agent/agent.py, la compétence est chargée à partir du répertoire et ajoutée aux outils de l'agent. Voici à quoi ressemble le code :

import pathlib
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset

# Load the AlloyDB skill from its directory
alloydb_skill = load_skill_from_dir(pathlib.Path(__file__).parent / "skills" / "get-local-and-traffic-rules")

# Assemble the Agent with the Skill Toolset
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
        skill_toolset.SkillToolset(skills=[alloydb_skill])
    ],
    after_agent_callback=[auto_save_memories],
)

10. Tester l'agent

  1. Démarrez l'agent localement :
uv run adk run planner_agent
  1. Posez une question sur les règles de la ville : [user]: What are the rules for running a race on the Las Vegas strip?

L'agent appellera l'outil get_local_and_traffic_rules, effectuera une recherche vectorielle dans AlloyDB et renverra une réponse basée sur les blocs de règles officiels traités par Spark.

11. Déployer l'agent

Déployer sur Agent Platform

uv run adk deploy agent_engine \
  --env_file .env \
  planner_agent

12. Libérer de l'espace

Pour éviter des frais récurrents, supprimez les ressources créées lors de cet atelier de programmation.

Supprimer le cluster AlloyDB

# Delete the AlloyDB Cluster
gcloud alloydb clusters delete rules-db --region=us-central1 --force

Supprimer l'application d'exécution de l'agent

Vous pouvez supprimer l'instance Reasoning Engine via la console ou à l'aide de la commande gcloud (si vous disposez du nom de la ressource). Pour plus de simplicité, utilisez la console :

  1. Accédez à la page Agent Runtime.
  2. Sélectionnez planner_agent -> cliquez sur le bouton à trois points à droite.
  3. Cliquez sur Supprimer.

13. Félicitations

Félicitations ! Vous avez amélioré un agent ADK avec des fonctionnalités avancées de mémoire et d'ancrage des données.

Connaissances acquises

  • Agents avec état : intégration des sessions Agent Platform pour conserver le contexte de la conversation.
  • Apprentissage à long terme : rattachement d'une banque de mémoire Agent Platform pour permettre à l'agent d'apprendre à partir des interactions utilisateur.
  • Ingestion de données : utilisation de Spark Lightning Engine et de Document AI pour traiter des documents non structurés.
  • RAG : création d'un système de recherche vectorielle dans AlloyDB pour ancrer l'agent dans les règles du monde réel.

Étapes suivantes

  • Consultez la documentation d'Agent Platform pour en savoir plus sur le déploiement géré.
  • Découvrez en détail la recherche vectorielle de AlloyDB pour les modèles RAG avancés.
  • Faites évoluer vos pipelines d'ingestion avec Dataproc sans serveur.