1. Présentation
L'ère des chatbots qui lisent touche à sa fin. Nous entrons dans l'ère de la vision agentique.
Dans cet atelier de programmation, nous allons implémenter l'ingénierie d'IA déterministe, une pratique qui consiste à créer des systèmes d'IA qui ne devinent pas. Les modèles d'IA standards "hallucinent" (devinent) souvent lorsqu'on leur demande de compter des éléments dans une image complexe. Dans une chaîne d'approvisionnement, une supposition est dangereuse. Si une IA estime que vous avez 12 articles alors que vous en avez 15, cela entraîne des erreurs coûteuses.
Nous allons créer un agent de chaîne d'approvisionnement autonome à l'aide de la nouvelle boucle Think, Act, Observe (Penser, Agir, Observer) dans Gemini 3 Flash. Elle ne se contente pas de regarder, elle enquête.
Architecture déterministe
Nous allons commencer par un système "aveugle" et "amnésique". Vous allez "éveiller" manuellement ses sens un par un :

- Les yeux (agent Vision) : nous activons Gemini 3 Flash avec l'exécution de code. Au lieu de prédire des jetons pour deviner un nombre, le modèle écrit du code Python (OpenCV) pour compter les pixels de manière déterministe.
- Mémoire (agent fournisseur) : nous activons AlloyDB AI avec ScaNN (Scalable Nearest Neighbors). Cela permet à l'agent de retrouver le fournisseur exact d'une pièce parmi des millions d'options en quelques millisecondes.
- La poignée de main (protocole A2A) : nous activons la communication Agent-to-Agent à l'aide d'un fichier agent_card.json standardisé , ce qui permet à l'agent Vision de commander des stocks de manière autonome auprès de l'agent Fournisseur.
Ce que vous allez faire
- Un agent Vision qui effectue des "calculs visuels" sur les flux de caméras.
- Un agent fournisseur basé sur AlloyDB ScaNN pour la recherche vectorielle à grande vitesse.
- Interface utilisateur Control Tower avec mises à jour WebSocket en temps réel pour visualiser la boucle autonome.
Points abordés
- Configurer AlloyDB avec des embeddings vectoriels et des index ScaNN
- Comment activer la vision agentique avec gemini-3-flash-preview à l'aide de l'API Gemini.
- Découvrez comment implémenter la recherche vectorielle à l'aide de l'opérateur <=> (distance cosinus) dans AlloyDB.
- Découvrez comment connecter des agents à AlloyDB à l'aide du connecteur Python AlloyDB.
- Découvrez comment utiliser le protocole A2A pour la découverte dynamique d'agents.
Conditions requises
- Un navigateur tel que Chrome ou Firefox
- Un projet Google Cloud avec facturation activée.
- Une clé API Gemini (niveau sans frais disponible sur Google AI Studio) pour l'agent Vision.
2. Avant de commencer
Créer un projet
- 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.
- Vous allez utiliser Cloud Shell, un environnement de ligne de commande exécuté dans Google Cloud. Cliquez sur "Activer Cloud Shell" en haut de la console Google Cloud.

- Une fois connecté à Cloud Shell, vérifiez que vous êtes déjà authentifié et que le projet est défini sur votre ID de projet à l'aide de la commande suivante :
gcloud auth list
Configurer la base de données [AlloyDB]
Avant toute chose, provisionnons la base de données. Cette opération prend environ 15 minutes. Nous allons donc commencer par là.
- Cliquez sur le bouton ci-dessous pour ouvrir l'outil de configuration AlloyDB dans Cloud Shell :
- Exécutez la configuration :
Sh run.sh
- Utilisez l'aperçu sur le Web (icône en forme d'œil 👁️ → Aperçu sur le port 8080) pour ouvrir l'interface utilisateur de configuration.
- Saisissez l'ID de votre projet, sélectionnez une région (par exemple, "us-central1") et créez un mot de passe pour la base de données.
⚠️ ENREGISTREZ CE MOT DE PASSE. Vous en aurez besoin lorsque le script de configuration vous le demandera.
- Cliquez sur "Start Deployment" (Démarrer le déploiement) et attendez environ 15 minutes que le cluster soit provisionné.
Obtenir le code
Pendant qu'AlloyDB provisionne (ou une fois que c'est fait), ouvrez le dépôt du tutoriel dans Cloud Shell :
⚠️ IMPORTANT : Lorsque vous cliquez sur le bouton, une boîte de dialogue de sécurité s'affiche. Cochez la case "Faire confiance au dépôt", puis cliquez sur "Confirmer".
Vous pouvez également cloner manuellement :
git clone https://github.com/MohitBhimrajka/visual-commerce-gemini-3-alloydb.git
cd visual-commerce-gemini-3-alloydb
Définir votre projet
Dans ce terminal Cloud Shell, vérifiez que votre projet est défini :
gcloud config set project <YOUR_PROJECT_ID>
Activer les adresses IP publiques sur AlloyDB
Une fois le provisionnement d'AlloyDB terminé, activez l'adresse IP publique pour que le connecteur Python puisse se connecter depuis Cloud Shell :
- Accédez à la console AlloyDB.
- Cliquez sur votre cluster, puis sur votre instance principale.
- Cliquez sur "Modifier".
- Faites défiler la page jusqu'à "Connectivité IP publique", puis cochez "Activer l'adresse IP publique".
- Cliquez sur "Mettre à jour l'instance".
💡 Remarque : Le connecteur Python AlloyDB gère l'authentification et le chiffrement. Vous n'avez pas besoin d'ajouter de réseaux externes autorisés.
Accorder des autorisations Vertex AI
Le compte de service AlloyDB a besoin d'accéder à Vertex AI pour générer des embeddings. Exécutez cette commande dans la même fenêtre Cloud Shell :
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Exécuter le script d'installation
Exécutez maintenant le script d'installation. Il détectera automatiquement votre instance AlloyDB :
sh setup.sh
Fonction du script :
- Valide gcloud CLI, l'authentification, le projet et Python 3
- Vérifie et active les API requises (AlloyDB, Vertex AI, Compute, Service Networking)
- Invite à saisir votre clé API Gemini
- Détecte automatiquement votre instance AlloyDB et extrait la région, le cluster et le nom de l'instance
- Demande le mot de passe de votre base de données
- Génère le fichier de configuration .env
- Installe les dépendances Python
3. Configuration de la base de données
AlloyDB pour PostgreSQL est au cœur de notre application. Nous utiliserons ses puissantes fonctionnalités vectorielles et son index ScaNN pour permettre une recherche sémantique en temps quasi réel. Nos agents pourront ainsi trouver des correspondances d'inventaire parmi des milliers d'enregistrements en quelques millisecondes.
Dans cette section, vous allez provisionner le schéma, amorcer les données et générer des embeddings, le tout depuis AlloyDB Studio.
Se connecter à AlloyDB Studio
- Accédez à votre instance AlloyDB dans la console AlloyDB.
- Cliquez sur AlloyDB Studio dans le panneau de navigation de gauche.
- S'authentifier avec :
- Nom d'utilisateur : postgres
- Base de données : postgres
- Mot de passe : mot de passe que vous avez défini lors de la création du cluster
Activer les extensions
AlloyDB fournit des extensions intégrées pour les vecteurs et l'IA. Exécutez le code SQL suivant dans AlloyDB Studio :
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
- google_ml_integration : active la fonction ai.embedding() pour appeler Vertex AI directement depuis SQL.
- vector : stocke et interroge les embeddings vectoriels de 768 dimensions.
- alloydb_scann : active l'index ScaNN de Google pour une recherche vectorielle ultra-rapide.
Créer la table d'inventaire
DROP TABLE IF EXISTS inventory;
CREATE TABLE inventory (
id SERIAL PRIMARY KEY,
part_name TEXT NOT NULL,
supplier_name TEXT NOT NULL,
description TEXT,
stock_level INT DEFAULT 0,
part_embedding vector(768)
);
La colonne "part_embedding" stocke des vecteurs de 768 dimensions provenant de text-embedding-005. C'est ce qui alimente la recherche sémantique.
Insérer des exemples de données
Insérer 20 éléments d'inventaire d'entrepôt :
INSERT INTO inventory (part_name, supplier_name, description, stock_level) VALUES
('Cardboard Shipping Box Large', 'Packaging Solutions Inc', 'Heavy-duty corrugated cardboard shipping container, 24x18x12 inches', 250),
('Warehouse Storage Container', 'Industrial Supply Co', 'Stackable plastic storage bin with snap-lock lid, blue', 180),
('Product Shipping Boxes', 'Acme Packaging', 'Medium corrugated boxes for warehouse storage, 18x14x10 inches', 320),
('Industrial Widget X-9', 'Acme Corp', 'Heavy-duty industrial coupling for pneumatic systems', 50),
('Precision Bolt M4', 'Global Fasteners Inc', 'Stainless steel M4 allen bolt, 20mm length, grade A2-70', 200),
('Hexagonal Nut M6', 'Metro Supply Co', 'Galvanized steel hex nut M6, DIN 934 standard', 150),
('Phillips Head Screw 3x20', 'Acme Corp', 'Zinc-plated Phillips head wood screw, 3mm x 20mm', 500),
('Wooden Dowel 10mm', 'Craft Materials Ltd', 'Hardwood birch dowel rod, 10mm diameter x 300mm length', 80),
('Rubber Gasket Small', 'SealTech Industries', 'Buna-N rubber gasket, 25mm OD x 15mm ID, oil resistant', 120),
('Spring Tension 5kg', 'Mechanical Parts Co', 'Stainless steel compression spring, 5kg load capacity', 60),
('Bearing 6204', 'Bearings Direct', 'Deep groove ball bearing 6204-2RS, 20x47x14mm sealed', 45),
('Warehouse Shelf Boxes', 'Storage Systems Ltd', 'Standardized warehouse inventory boxes, corrugated, bulk pack', 400),
('Inventory Container Units', 'Supply Chain Pros', 'Modular stackable storage units for warehouse racking', 95),
('Aluminum Extrusion Bar', 'MetalWorks International', 'T-slot aluminum extrusion 20x20mm profile, 1 meter length', 110),
('Cable Tie Pack 200mm', 'ElectroParts Depot', 'Nylon cable ties, 200mm x 4.8mm, UV resistant black, pack of 100', 600),
('Hydraulic Hose 1/2 inch', 'FluidPower Systems', 'High-pressure hydraulic hose, 1/2 inch ID, 3000 PSI rated', 35),
('Safety Goggles Clear', 'WorkSafe Equipment Co', 'ANSI Z87.1 rated clear safety goggles, anti-fog coating', 275),
('Packing Tape Industrial', 'Packaging Solutions Inc', 'Heavy-duty polypropylene packing tape, 48mm x 100m, clear', 450),
('Stainless Steel Sheet 1mm', 'MetalWorks International', '304 stainless steel sheet, 1mm thickness, 300x300mm', 70),
('Silicone Sealant Tube', 'SealTech Industries', 'Industrial-grade RTV silicone sealant, 300ml cartridge, grey', 190);
Accorder des autorisations d'intégration
GRANT EXECUTE ON FUNCTION embedding TO postgres;
Générer des embeddings vectoriels
Cette méthode utilise la fonction ai.embedding() intégrée d'AlloyDB pour appeler le modèle text-embedding-005 de Vertex AI directement depuis SQL, sans avoir besoin de code Python :
UPDATE inventory
SET part_embedding = ai.embedding(
'text-embedding-005',
part_name || '. ' || description
)::vector
WHERE part_embedding IS NULL;
Cela génère des vecteurs de 768 dimensions qui capturent la signification sémantique du nom et de la description de chaque pièce. L'index ScaNN les utilisera pour une recherche de similarité ultra-rapide. [Cela prendra environ trois à cinq minutes]
Créer l'index ScaNN
SET scann.allow_blocked_operations = true;
CREATE INDEX IF NOT EXISTS idx_inventory_scann
ON inventory USING scann (part_embedding cosine)
WITH (num_leaves=5, quantizer='sq8');
Vérifier que tout a fonctionné
SELECT part_name, supplier_name, stock_level,
(part_embedding IS NOT NULL) as has_embedding
FROM inventory
ORDER BY id;
Vous devriez voir 20 lignes, toutes avec la valeur "has_embedding" définie sur "true".
4. Comprendre l'architecture
Avant de modifier le code, comprenons comment le système est construit. L'architecture suit un modèle d'éveil progressif :
Pile d'agents
Agent Vision (agents/vision-agent/)
- agent.py : logique principale de Gemini 3 Flash. Envoie des images au modèle avec l'exécution de code activée afin qu'il écrive du code Python (OpenCV) pour compter les éléments de manière déterministe.
- agent_executor.py : fait le lien entre les requêtes du protocole A2A et la logique de l'agent.
- main.py : serveur Uvicorn A2A qui fournit /.well-known/agent-card.json et gère les requêtes.
Agent fournisseur (agents/supplier-agent/)
- inventory.py : se connecte à AlloyDB via le connecteur Python AlloyDB (aucun proxy d'authentification n'est nécessaire). Contient la fonction find_supplier() qui effectue la recherche vectorielle ScaNN.
- agent_executor.py : fait le lien entre le protocole A2A et la logique de recherche d'inventaire.
- main.py : serveur Uvicorn A2A avec carte d'agent et point de terminaison d'état.
Control Tower (frontend/)
- app.py : serveur FastAPI + WebSocket qui découvre les agents via A2A, orchestre le pipeline vision → recherche → commande et diffuse les mises à jour en temps réel dans le navigateur.
Flux A2A
- Control Tower lit /.well-known/agent-card.json à partir de chaque agent.
- Découvre les fonctionnalités (compétences, points de terminaison) sans URL codées en dur
- Envoi d'une image à l'agent Vision → obtention du nombre d'articles et de la description
- Envoie la description en tant que requête d'intégration à l'agent fournisseur → obtient une correspondance partielle
- Passer une commande de manière autonome
Connexion AlloyDB
L'agent fournisseur utilise le connecteur Python AlloyDB au lieu du proxy d'authentification traditionnel :
from google.cloud.alloydbconnector import Connector
connector = Connector()
conn = connector.connect(
inst_uri, # Full instance URI
"pg8000", # Driver
user="postgres",
password=DB_PASS,
ip_type="PUBLIC", # Cloud Shell uses Public IP
)
Il gère automatiquement l'authentification IAM, SSL/TLS et le routage des connexions. Lorsque vous déployez sur Cloud Run ultérieurement, il vous suffit de remplacer ip_type par "PRIVATE" pour l'accès au VPC.
5. Étape 1 : La mémoire (agent fournisseur)
L'agent fournisseur se souvient de millions de pièces à l'aide d'AlloyDB ScaNN. Pour le moment, il est fourni avec une requête d'espace réservé, une requête amnésique qui renvoie la première ligne qu'elle trouve, quelle que soit la recherche effectuée.
The Audit: The Amnesiac
Si vous interrogez l'agent fournisseur maintenant, il renvoie un résultat aléatoire. Il n'a aucune notion de similarité. Nous allons résoudre ce problème.
Démarrer l'agent fournisseur
Le serveur A2A (main.py) délègue à agent_executor.py, qui fait le lien entre le protocole et la logique métier dans inventory.py.
pkill -f uvicorn #Kill all uvicorn processes
Étape 1 : Accédez au répertoire d'agents.
cd agents/supplier-agent
Étape 2 : Installez les dépendances
pip install -r requirements.txt
Étape 3 : Démarrez le serveur de l'agent
uvicorn main:app --host 0.0.0.0 --port 8082 > /dev/null 2>&1 &
La commande > /dev/null 2>&1 & exécute le serveur en arrière-plan et supprime la sortie pour qu'elle n'interrompe pas votre terminal.
Étape 4 : Vérifiez que l'agent est en cours d'exécution (attendez deux à trois secondes après le démarrage).
curl http://localhost:8082/.well-known/agent-card.json
Résultat attendu : JSON avec la configuration de l'agent (doit être renvoyé sans erreur)
Solution : implémenter l'opérateur <=>
Ouvrez agents/supplier-agent/inventory.py et recherchez la fonction find_supplier() vers la ligne 60-70. L'espace réservé suivant s'affiche :
# TODO: Replace this placeholder query with ScaNN vector search
sql = "SELECT part_name, supplier_name FROM inventory LIMIT 1;"
cursor.execute(sql)
Remplacez ces deux lignes par :
sql = """
SELECT part_name, supplier_name,
part_embedding <=> %s::vector as distance
FROM inventory
ORDER BY part_embedding <=> %s::vector
LIMIT 1;
"""
cursor.execute(sql, (embedding_str, embedding_str))
Ce que cela signifie :
- <=> est l'opérateur de distance cosinus dans PostgreSQL.
- ORDER BY part_embedding <=> %s::vector trouve la correspondance la plus proche (distance la plus faible = signification sémantique la plus proche).
- %s::vector convertit votre tableau d'embedding au type de vecteur PostgreSQL.
- L'index ScaNN accélère automatiquement cette requête.
Étape 4 : Enregistrez le fichier (Ctrl+S ou Cmd+S).
L'agent utilise désormais la recherche sémantique au lieu de renvoyer des résultats aléatoires.
Validation
Testez la découverte A2A et l'inventaire :
curl http://localhost:8082/.well-known/agent-card.json

python3 -c "
from inventory import find_supplier
import json
vec = [0.1]*768
r = find_supplier(vec)
if r:
result = {'part': r[0], 'supplier': r[1]}
if len(r) > 2:
result['distance'] = float(r[2]) if r[2] else None
print(json.dumps(result))
else:
print('No result found')
"
Résultat attendu : agent-card.json renvoie la fiche de l'agent. L'extrait de code Python renvoie une pièce et un fournisseur à partir des données initiales.
6. Étape 2 : Les yeux (agent Vision)
Bien que la base de données soit accessible, réveillons les yeux à l'aide de Gemini 3 Flash. L'agent Vision effectue des "calculs visuels" via l'exécution de code.
L'audit : l'hallucination
Si vous demandez à un modèle multimodal standard "Combien de boîtes y a-t-il sur cette image désordonnée ?", il traite l'image comme un instantané statique et fait une estimation.
- Le modèle répond : "Je vois environ 12 boîtes."
- Réalité : il y a 15 boîtes.
- Résultat : Échec de la chaîne d'approvisionnement.
La solution : éveiller la boucle Réfléchir-Agir-Observer
Nous activons Code Execution et ThinkingConfig pour que le modèle écrive du code Python (OpenCV) afin d'effectuer un comptage déterministe.
- Ouvrez agents/vision-agent/agent.py .
- Recherchez la section GenerateContentConfig (vers les lignes 68 à 78).
- Décommentez le bloc thinking_config=types.ThinkingConfig(...) et tools=[types.Tool(code_execution=...)].
- Le client est déjà configuré pour utiliser votre GEMINI_API_KEY à partir de l'environnement.
Fichier : agents/vision-agent/agent.py
config = types.GenerateContentConfig(
temperature=0,
# CODELAB STEP 1: Uncomment to enable reasoning
thinking_config=types.ThinkingConfig(
thinking_level="MINIMAL", # Valid: "MINIMAL", "LOW", "MEDIUM", "HIGH"
include_thoughts=False # Set to True for debugging
),
# CODELAB STEP 2: Uncomment to enable code execution
tools=[types.Tool(code_execution=types.ToolCodeExecution)]
)
Pourquoi thinking_level="MINIMAL" ?
Pour cette tâche (comptage d'éléments par exécution de code), le niveau "MINIMAL" fournit un raisonnement suffisant pour planifier le script et vérifier le nombre. Si vous choisissez "ÉLEVÉE", la latence sera multipliée par deux ou trois, sans que la précision des tâches déterministes soit améliorée. Optimisation des coûts et des performances : adaptez la profondeur du raisonnement à la complexité de la tâche.
L'optimisation du rapport coût/performances est une compétence clé pour l'ingénierie de l'IA de production : faites correspondre la profondeur du raisonnement à la complexité de la tâche.
Démarrer l'agent Vision
🔄 Vérification du chemin d'accès : si vous êtes toujours dans agents/supplier-agent/, revenez d'abord à la racine du dépôt avec cd ../..
Étape 1 : Accédez au répertoire des agents Vision
cd agents/vision-agent
Étape 2 : Installez les dépendances
pip install -r requirements.txt
Étape 3 : Démarrez le serveur de l'agent Vision
uvicorn main:app --host 0.0.0.0 --port 8081 > /dev/null 2>&1 &
La commande > /dev/null 2>&1 & exécute le serveur en arrière-plan et supprime la sortie pour qu'elle n'interrompe pas votre terminal.
Validation
Test de la découverte A2A :
curl http://localhost:8081/.well-known/agent-card.json
Résultat attendu : JSON avec le nom et les compétences de l'agent. Vous testerez le comptage de vision réel avec l'interface utilisateur de la tour de contrôle à l'étape 8.

7. Étape 3 : La poignée de main (carte d'agent A2A)
Notre agent voit le problème (Vision) et connaît le fournisseur (Mémoire). Le protocole A2A permet la découverte dynamique : le frontend apprend à communiquer avec chaque agent en lisant sa carte.
A2A vs API REST traditionnelles
Aspect | REST traditionnel | Protocole A2A |
Découverte des points de terminaison | URL codées en dur dans la configuration | Dynamique via /.well-known/agent-card.json |
Description de la fonctionnalité | Documentation de l'API (pour les humains) | Compétences (lisibles par une machine) |
Intégration | Code manuel par service | Correspondance sémantique : "J'ai besoin d'une recherche d'inventaire" → découverte de la skill |
Nouvel agent ajouté | Mettre à jour les configurations de tous les clients | Aucune configuration requise : découverte automatique |
Avantage concret : dans un microservice traditionnel, si vous ajoutez un troisième "agent logistique", vous devez mettre à jour le code de la tour de contrôle avec son URL et son contrat d'API. Avec A2A, la Control Tower le découvre automatiquement et comprend ses capacités grâce à des descriptions de compétences en langage naturel.
C'est pourquoi A2A permet la composition d'agents plug-and-play, le modèle architectural pour les systèmes autonomes.
Créer la fiche de l'agent
🔄 Vérification du chemin d'accès : si vous êtes toujours dans agents/vision-agent/, revenez d'abord à la racine du dépôt avec cd ../..
La carte d'agent est déjà incluse dans agents/supplier-agent/agent_card.json. Ouvrez-le et examinez :
{
"name": "Acme Supplier Agent",
"description": "Autonomous fulfillment for industrial parts via AlloyDB ScaNN.",
"version": "1.0.0",
"skills": [{
"id": "search_inventory",
"name": "Search Inventory",
"description": "Searches the warehouse database for semantic matches using AlloyDB ScaNN vector search.",
"tags": ["inventory", "search", "alloydb"],
"examples": ["Find stock for Industrial Widget X-9", "Who supplies ball bearings?"]
}]
}
N'hésitez pas à personnaliser le nom, la description ou les exemples pour les adapter à votre cas d'utilisation.
Redémarrez l'agent fournisseur pour charger la carte :
Étape 1 : Arrêtez l'agent en cours d'exécution
pkill -f "uvicorn main:app.*8082"
Étape 2 : Accédez au répertoire de l'agent
cd agents/supplier-agent
Étape 3 : Redémarrez l'agent
uvicorn main:app --host 0.0.0.0 --port 8082 > /dev/null 2>&1 &
La commande > /dev/null 2>&1 & exécute le serveur en arrière-plan et supprime la sortie pour qu'elle n'interrompe pas votre terminal.
Étape 4 : Vérifiez la nouvelle fiche d'agent (attendez deux à trois secondes après le démarrage).
curl http://localhost:8082/.well-known/agent-card.json
Résultat attendu : JSON avec votre nom, votre description et vos compétences renseignés.

8. Étape 4 : La tour de contrôle
Exécutez l'interface utilisateur Control Tower avec FastAPI et WebSockets. Il découvre les agents via A2A et orchestre la boucle complète avec des mises à jour en temps réel.
Démarrer tous les services
La méthode la plus simple pour démarrer tous les services :
Vérifier que vous êtes à la racine du dépôt
pwd # Should end with: visual-commerce-gemini-3-alloydb
Ensuite,
sh run.sh
Cette commande unique démarre :
- Agent Vision sur le port 8081
- Agent fournisseur sur le port 8082
- Control Tower sur le port 8080
Attendez environ 10 secondes que tous les services s'initialisent.
Tester le système
Accéder à Control Tower :
- Cliquez sur le bouton Aperçu sur le Web (icône en forme d'œil 👁️) dans la barre d'outils Cloud Shell.
- Sélectionnez Prévisualiser sur le port 8080.
- Le tableau de bord Control Tower s'ouvre dans un nouvel onglet.
Exécuter la démo :
- En haut à droite : état de la connexion (point vert "En ligne"), bouton bascule du mode DÉMO/AUTO et commandes audio
- Centre : canevas principal du workflow avec importation d'images et visualisation de l'analyse
- Panneaux latéraux (qui s'affichent pendant l'analyse) : chronologie du workflow (à gauche), suivi de la progression et visionneuse de code (à droite)
Option 1 : Démarrage rapide (recommandé)
- Sur la page d'accueil, vous trouverez une section Démarrage rapide avec des exemples d'images.
- Cliquez sur une image exemple pour lancer automatiquement l'analyse.
- Regardez le workflow autonome (environ 30 à 45 secondes).
Option 2 : Importer votre propre fichier
- Glissez-déposez une image d'entrepôt/d'étagère (PNG, JPG, jusqu'à 10 Mo) ou cliquez pour parcourir.
- Cliquez sur Initiate Autonomous Workflow (Lancer le workflow autonome).
- Observer le pipeline en quatre étapes
Ce qui se passe :
- Découverte d'agents : les modaux du protocole A2A affichent les cartes de l'agent Vision et de l'agent Fournisseur avec leurs compétences et leurs points de terminaison.
- Analyse de la vision : Gemini 3 Flash génère et exécute du code Python (OpenCV) pour compter les éléments. La barre de progression affiche les sous-étapes. Des cadres de délimitation sont superposés aux éléments détectés. Le badge de résultat indique "✓ Code vérifié" ou "~ Estimation".
- Correspondance des fournisseurs : animation de la recherche vectorielle ScaNN AlloyDB. La requête de recherche s'affiche (par exemple, "boîtes métalliques industrielles"). La fiche de résultat indique la pièce correspondante, le fournisseur et le score de confiance.
- Commande passée : carte de reçu avec l'ID de commande, la quantité et les détails
Conseil : Laissez le mode DÉMO activé (en haut à droite) pour mettre en pause chaque étape lors des présentations. En mode AUTO, le workflow s'exécute en continu.

Que s'est-il passé ?
La tour de contrôle a utilisé le protocole A2A pour découvrir les deux agents via /.well-known/agent-card.json, orchestrer l'analyse de vision (Gemini 3 Flash avec exécution de code), effectuer la recherche vectorielle (AlloyDB ScaNN) et passer une commande autonome, le tout avec des mises à jour WebSocket en temps réel. Chaque agent expose ses capacités via la norme A2A, ce qui permet une composition plug-and-play sans SDK personnalisés. En savoir plus : Protocole A2A
Dépannage
Erreurs liées au chemin d'accès :
- Message d'erreur "No such file or directory" (Fichier ou répertoire inexistant) lors de l'exécution de commandes : vous n'êtes pas à la racine du dépôt.
# Check where you are
pwd
# If you're lost, navigate to home and back to repo
cd
cd visual-commerce-gemini-3-alloydb
Erreurs de service :
- "Adresse déjà utilisée" : les processus des exécutions précédentes sont toujours actifs.
# Kill all services and restart
pkill -f uvicorn
sh run.sh # Or manually restart individual agents
- Les services ne démarrent pas : vérifiez si les ports sont occupés :
# Check which processes are using the ports
lsof -i :8080 # Control Tower
lsof -i :8081 # Vision Agent
lsof -i :8082 # Supplier Agent
- "Connexion refusée" à AlloyDB : vérifiez que l'adresse IP publique est activée sur votre instance AlloyDB.
9. 🎁 Bonus : Déployer sur Cloud Run
Facultatif : tout fonctionne en local. Toutefois, si vous souhaitez partager votre création avec une URL publique :
# From repo root
sh deploy/deploy.sh
Ce qui se passe :
- Lit votre configuration .env
- Demande votre nom (affiché dans l'application déployée)
- Déploie les trois services en tant que conteneur Cloud Run unique
- Accorde des rôles IAM pour l'accès à AlloyDB
- Génère une URL partageable
Les visiteurs qui ouvrent votre URL verront un pop-up :
10. Nettoyage
Pour éviter des frais, détruisez toutes les ressources à l'aide du script de nettoyage automatique :
# From repo root
sh deploy/cleanup.sh
Les éléments suivants sont supprimés de manière sécurisée :
- Cluster AlloyDB (principal facteur de coût)
- Services Cloud Run (si déployés)
- Comptes de service associés
Le script vous demandera de confirmer l'opération avant de supprimer quoi que ce soit.
11. Références et lectures complémentaires
Toutes les affirmations techniques de cet atelier de programmation sont vérifiées à partir de la documentation officielle de Google Cloud et de Google IA.
Documentation officielle
Gemini 3 Flash :
- API Code Execution : https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-execution-api
- Guide du développeur : https://ai.google.dev/gemini-api/docs/gemini-3
- Documentation sur le modèle : https://docs.cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-flash
- Fiche du modèle : https://deepmind.google/models/gemini/flash/
AlloyDB AI et ScaNN :
- Benchmarks de performances ScaNN : https://cloud.google.com/blog/products/databases/how-scann-for-alloydb-vector-search-compares-to-pgvector-hnsw
- Comprendre l'index ScaNN : https://cloud.google.com/blog/products/databases/understanding-the-scann-index-in-alloydb
- Présentation détaillée d'AlloyDB/AI : https://cloud.google.com/blog/products/databases/alloydb-ais-scann-index-improves-search-on-all-kinds-of-data
- Bonnes pratiques pour le réglage : https://docs.cloud.google.com/alloydb/docs/ai/best-practices-tuning-scann
- Documentation AlloyDB : https://cloud.google.com/alloydb/docs
MCP Toolbox for Databases (approche alternative) :
- Boîte à outils MCP : https://googleapis.github.io/genai-toolbox/getting-started/introduction/
Informations tarifaires :
- Tarifs de l'API Gemini : https://ai.google.dev/gemini-api/docs/pricing
- Tarifs d'AlloyDB : https://cloud.google.com/alloydb/pricing
- Tarification de Vertex AI : https://cloud.google.com/vertex-ai/pricing
Affirmations vérifiées sur les performances
Fonctionnalité | Demander | Source |
ScaNN vs HNSW (filtré) | 10 fois plus rapide | Blog Google Cloud (validé) |
ScaNN vs HNSW (standard) | 4 fois plus rapide | Blog Google Cloud (validé) |
Espace mémoire utilisé par ScaNN | 3 à 4 fois plus petit | Blog Google Cloud (validé) |
Temps de création d'un index ScaNN | 8 fois plus rapide | Blog Google Cloud (validé) |
Délai d'exécution du code | 30 secondes maximum | Documentation Google Cloud (vérifiée) |
E/S de fichier d'exécution de code | Non compatible | Documentation Google Cloud (vérifiée) |
Comportement avec une température de 0 | Résultat déterministe | Validé par la communauté |
Autres ressources
Protocole Agent-to-Agent (A2A) :
- A2A normalise la découverte et la communication des agents
- Cartes d'agent diffusées sur
/.well-known/agent-card.json - Norme émergente pour la collaboration entre agents autonomes
Recherche ScaNN :
- Basé sur 12 ans de recherche Google
- Alimente la recherche Google et YouTube à l'échelle du milliard
- Disponibilité générale : octobre 2024
- Premier index vectoriel PostgreSQL adapté aux millions à milliards de vecteurs
12. Mode Défi : améliorez vos compétences d'agent
Vous avez créé une chaîne d'approvisionnement autonome fonctionnelle. Prêt à aller plus loin ? Ces défis appliquent les modèles que vous avez appris à de nouveaux problèmes.
Défi 1 : Recherche basée sur des images (embeddings multimodaux)
Flux actuel : l'agent Vision compte les articles → génère une requête textuelle → l'agent Fournisseur intègre le texte → effectue une recherche dans AlloyDB
Défi : contournez complètement le texte et envoyez l'image recadrée directement à l'agent fournisseur.
Conseils :
- L'exécution de code de l'agent Vision peut recadrer des éléments individuels à partir de l'image de l'étagère.
- Le modèle multimodalembedding@001 de Vertex AI peut intégrer directement des images.
- Modifier inventory.py pour accepter les octets d'image au lieu du texte
- Mise à jour de la description de la compétence A2A pour indiquer "Accepte : image/jpeg ou texte"
Pourquoi est-ce important ? La recherche visuelle est plus précise pour les pièces dont l'apparence est complexe (variations de couleur, dommages, différences d'emballage).
Défi 2 : Observabilité – Confiance grâce à la transparence
État actuel : le système fonctionne, mais vous ne pouvez pas voir "sous le capot"
Défi : Inspectez les journaux de requêtes d'AlloyDB pour prouver que la recherche vectorielle est en cours d'exécution.
Étapes :
- Les insights sur les requêtes sont activés par défaut sur AlloyDB. Pour le vérifier, exécutez la commande suivante :
gcloud alloydb instances describe INSTANCE_NAME \
--cluster=CLUSTER_NAME \
--region=us-central1 \
--format="value(queryInsightsConfig.queryPlansPerMinute)"
- Effectuer une recherche de fournisseurs dans l'UI
- Affichez le code SQL réellement exécuté :
gcloud logging read \
'resource.type="alloydb.googleapis.com/Instance" AND textPayload:"ORDER BY part_embedding"' \
--limit 5 \
--format=json
Résultat attendu : Vous verrez la requête ORDER BY part_embedding <= > $1::vector LIMIT 1 exacte avec le temps d'exécution.
Pourquoi est-ce important ? L'observabilité renforce la confiance. Lorsque les parties prenantes demandent "Comment cet agent prend-il des décisions ?", vous pouvez leur montrer le plan de requête, et pas seulement le résultat.
Problème 3 : Composition multi-agents
Défi : Ajoutez un troisième agent (agent logistique) qui calcule les frais de port en fonction de l'emplacement de l'entrepôt et du poids de l'article.
Architecture :
- Sorties de l'agent Vision : nombre d'articles
- Sorties de l'agent fournisseur : emplacement du fournisseur
- Entrées de l'agent de logistique (NOUVEAU) : destination, poids → sorties : frais de port + heure d'arrivée estimée
Conseil : Le protocole A2A facilite cette tâche. Créez une carte d'agent avec une compétence calculate_shipping. La Control Tower le détectera automatiquement.
Schéma d'apprentissage : il s'agit du cœur de l'architecture orientée agent, qui consiste à créer des systèmes complexes à partir de petits spécialistes composables.
13. Conclusion
Vous êtes bien passé de IA générative à IA agentique.
Ce que nous avons créé :
- Vision : nous avons remplacé la "devinette" par l'exécution de code (Gemini 3 Flash via clé API).
- Mémoire : nous avons remplacé "recherche lente" par AlloyDB ScaNN (via GCP).
- Action : nous avons remplacé "Intégration de l'API" par le protocole A2A.
Avantages de l'architecture hybride :
Cet atelier de programmation a présenté une approche hybride :
- Agent Vision : utilise l'API Gemini (clé API), niveau simple et sans frais disponible, aucune facturation GCP requise
- Agent fournisseur : utilise GCP (Vertex AI + AlloyDB), conforme et de niveau entreprise
Voici l'architecture de l'économie autonome. Vous pouvez conserver le code.
Étapes suivantes