Le même agent avec Google ADK
Pourquoi un framework, maintenant ?
Vous savez ce qu'il y a sous le capot. Un framework vous évite de réécrire la plomberie (sessions, streaming, interface de test, traces, déploiement) et vous laisse vous concentrer sur les outils et les instructions.
| Ce que vous avez codé | Équivalent ADK |
|---|---|
SYSTEM | instruction= de l'agent |
TOOLS + TOOLS_PY | tools=[fonction_python, ...] : schéma déduit de la signature et de la docstring |
agent() et sa boucle | le Runner, fourni |
max_steps | RunConfig(max_llm_calls=...) |
Conversation.messages | une session gérée par un SessionService |
lire_faits / ajouter_fait | l'état de session (tool_context.state) et le MemoryService |
agent_mcp.py | McpToolset |
call_llm | model="gemini-2.5-flash" (ou d'autres modèles via LiteLLM) |
flowchart TB U["Utilisateur"] --> R["Runner ADK"] R --> S["SessionService : historique + état"] R --> A["Agent : instruction + modèle"] A --> F["Outil Python : memoriser_preference"] A --> M["McpToolset"] M <-->|"stdio"| SC["serveur_catalogue.py"]
Installation et structure
python -m venv .venv && source .venv/bin/activate
pip install google-adkADK attend un dossier par agent, avec un __init__.py et un agent.py qui définit root_agent :
projet/
└── assistant_commandes/
├── __init__.py # contient : from . import agent
├── agent.py
├── serveur_catalogue.py # le serveur MCP de la leçon précédente
└── .env# Avec une clé Gemini (Google AI Studio)
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=votre-cle
# Ou avec Vertex AI sur votre projet Google Cloud :
# GOOGLE_GENAI_USE_VERTEXAI=TRUE
# GOOGLE_CLOUD_PROJECT=mon-projet
# GOOGLE_CLOUD_LOCATION=europe-west1L'agent complet
import sys
from pathlib import Path
from google.adk.agents import Agent
from google.adk.tools import ToolContext
from google.adk.tools.mcp_tool import McpToolset, StdioConnectionParams
from mcp import StdioServerParameters
SERVEUR = str(Path(__file__).with_name("serveur_catalogue.py"))
def memoriser_preference(preference: str, tool_context: ToolContext) -> dict:
"""Retient une préférence durable du client (ex. 'livraison le samedi')."""
prefs = tool_context.state.get("user:preferences", [])
tool_context.state["user:preferences"] = prefs + [preference]
return {"ok": True}
root_agent = Agent(
name="assistant_commandes",
model="gemini-2.5-flash",
description="Aide les clients à trouver un produit et vérifier le stock.",
instruction=(
"Tu es l'assistant de commandes d'une boutique. Utilise les outils, "
"n'invente jamais un prix ni un stock. "
"Préférences connues du client : {user:preferences?}"
),
tools=[
McpToolset(connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command=sys.executable, args=[SERVEUR]))),
memoriser_preference,
],
)Lancez l'interface de développement depuis le dossier parent :
cd projet
adk web # interface web locale : conversation, événements, état, traces
# ou
adk run assistant_commandes # en ligne de commandeÉtat et mémoire dans ADK
tool_context.stateest un dictionnaire attaché à la session. Le préfixe de la clé fixe sa portée : sans préfixe pour la session,user:pour toutes les sessions du même utilisateur,app:pour toute l'application,temp:pour l'invocation en cours.{user:preferences?}dans l'instruction est remplacé par la valeur de l'état ; le?évite une erreur si la clé n'existe pas encore.- La persistance dépend du
SessionService: en mémoire pour le développement, une base de données ou Vertex AI en production. Avec le service en mémoire, tout disparaît au redémarrage.
Dans ADK, comment le modèle sait-il que memoriser_preference attend un paramètre preference de type texte ?
Comme FastMCP, ADK inspecte la fonction : preference: str devient un paramètre string obligatoire, la docstring devient la description. Le paramètre tool_context est reconnu par ADK et masqué au modèle.
Vous stockez le panier en cours sous la clé "user:panier". Quel est le problème ?
Le préfixe user: rend la donnée commune à toutes les sessions de l'utilisateur. Un panier en cours relève de la session (clé sans préfixe). user: convient aux préférences durables.
Exercice : un outil ADK qui écrit dans l'état
Ajoutez à l'agent ADK un outil ajouter_au_panier(ref: str, quantite: int, tool_context: ToolContext) qui ajoute une ligne dans tool_context.state["panier"] et renvoie le panier complet. Mettez à jour l'instruction pour que le modèle voie le panier.
Voir la solution
def ajouter_au_panier(ref: str, quantite: int, tool_context: ToolContext) -> dict:
"""Ajoute une ligne au panier de la conversation en cours."""
if quantite < 1:
return {"erreur": "La quantité doit être au moins 1"}
panier = tool_context.state.get("panier", [])
panier = panier + [{"ref": ref, "quantite": quantite}]
tool_context.state["panier"] = panier # réassigner : ADK enregistre le changement
return {"panier": panier}Dans l'agent : ajoutez ajouter_au_panier à tools=[...] et la phrase "Panier actuel : {panier?}" à l'instruction.
On réassigne une nouvelle liste plutôt que de faire .append() sur la liste existante : c'est l'affectation dans state qui permet à ADK de détecter et d'enregistrer la modification. Et la clé panier, sans préfixe, limite le panier à la session.
Je sais faire
- Faire correspondre chaque morceau de mon agent « fait main » à un concept ADK
- Créer un agent ADK avec des outils Python et un
McpToolset - Lancer
adk webet lire les événements d'une conversation - Choisir la bonne portée d'état : session,
user:,app:,temp: