Introduction au Function Calling
Objectifs
- Comprendre le concept de Function Calling (Tool Use)
- Maitriser le flux model -> function_call -> function_result -> model
- Connaitre les modes AUTO, ANY, NONE
- Definir des fonctions avec JSON Schema
Qu'est-ce que le Function Calling ?
Le Function Calling permet a Gemini de generer des appels de fonctions structures plutot que du texte. Le modele ne execute PAS les fonctions lui-meme - il produit un JSON decrivant quelle fonction appeler et avec quels arguments. C'est votre code qui execute la fonction et renvoie le resultat.
βββββββββββββββββββββ FLUX FUNCTION CALLING βββββββββββββββββββββ
β β
β 1. REQUETE 2. REPONSE MODEL β
β βββββββββββββββ ββββββββββββββββββββ β
β β User: "Quel β βββββββΊ β function_call: β β
β β temps fait-ilβ β name: get_meteo β β
β β a Paris ?" β β args: { β β
β β β β city: "Paris" β β
β β + tools: β β } β β
β β [get_meteo]β ββββββββββ¬ββββββββββ β
β βββββββββββββββ β β
β βΌ β
β 4. REPONSE FINALE 3. VOTRE CODE EXECUTE β
β βββββββββββββββββββ ββββββββββββββββββββ β
β β "Il fait 12Β°C β βββββ β function_response:β β
β β a Paris avec β β result: { β β
β β un ciel couvertβ β temp: 12, β β
β β et du vent." β β cond: "nuageux"β β
β βββββββββββββββββββ β } β β
β ββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Definir une fonction
from google import genai
from google.genai import types
# Definir la fonction avec JSON Schema
get_weather = types.FunctionDeclaration(
name="get_current_weather",
description="Obtient la meteo actuelle d'une ville donnee",
parameters=types.Schema(
type="OBJECT",
properties={
"location": types.Schema(
type="STRING",
description="Nom de la ville, ex: 'Paris, France'"
),
"unit": types.Schema(
type="STRING",
enum=["celsius", "fahrenheit"],
description="Unite de temperature"
)
},
required=["location"]
)
)
# Creer l'outil
weather_tool = types.Tool(function_declarations=[get_weather])
Les 3 modes de function calling
| Mode | Comportement | Cas d'usage |
|---|---|---|
| AUTO (defaut) | Le modele decide s'il appelle une fonction ou repond en texte | Usage general, conversations mixtes |
| ANY | Le modele est FORCE d'appeler une des fonctions | Pipelines structures, routing obligatoire |
| NONE | Function calling desactive, reponse texte uniquement | Desactiver temporairement les outils |
# Configurer le mode
config = types.GenerateContentConfig(
tools=[weather_tool],
tool_config=types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(
mode="ANY", # Force l'appel de fonction
allowed_function_names=["get_current_weather"]
)
)
)
Le function calling est le pont entre l'IA et le monde reel. C'est la capacite la plus importante pour construire des applications utiles. Sans function calling, Gemini est un cerveau sans bras. Avec, il peut interroger des APIs, lire des bases de donnees, envoyer des emails - tout ce que votre code peut faire.
Function Calling en pratique
Objectifs
- Implementer un flux function calling complet
- Gerer le parallel function calling
- Implementer le compositional calling (chaine)
- Gerer les erreurs de function calling
Flux complet avec le SDK
from google import genai
from google.genai import types
import json
client = genai.Client(api_key="VOTRE_CLE_API")
# 1. Definir les fonctions
get_weather = types.FunctionDeclaration(
name="get_weather",
description="Obtient la meteo d'une ville",
parameters=types.Schema(
type="OBJECT",
properties={
"city": types.Schema(type="STRING", description="Nom de la ville")
},
required=["city"]
)
)
get_time = types.FunctionDeclaration(
name="get_time",
description="Obtient l'heure actuelle dans un fuseau horaire",
parameters=types.Schema(
type="OBJECT",
properties={
"timezone": types.Schema(type="STRING", description="ex: Europe/Paris")
},
required=["timezone"]
)
)
tools = types.Tool(function_declarations=[get_weather, get_time])
# 2. Fonctions reelles
def execute_function(name, args):
if name == "get_weather":
# Simuler un appel API meteo
return {"temp": 14, "condition": "ensoleille", "wind": "12 km/h"}
elif name == "get_time":
from datetime import datetime
return {"time": datetime.now().strftime("%H:%M"), "timezone": args["timezone"]}
# 3. Boucle function calling
def chat_with_tools(user_message):
messages = [types.Content(role="user", parts=[types.Part(text=user_message)])]
while True:
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=messages,
config=types.GenerateContentConfig(tools=[tools])
)
# Verifier s'il y a des function calls
candidate = response.candidates[0]
has_function_calls = any(
part.function_call for part in candidate.content.parts
)
if not has_function_calls:
return response.text # Reponse finale texte
# Executer toutes les fonctions (parallel calling)
messages.append(candidate.content)
function_responses = []
for part in candidate.content.parts:
if part.function_call:
result = execute_function(
part.function_call.name,
dict(part.function_call.args)
)
function_responses.append(
types.Part(function_response=types.FunctionResponse(
name=part.function_call.name,
response=result
))
)
messages.append(types.Content(parts=function_responses))
# 4. Test
print(chat_with_tools("Quelle meteo et quelle heure a Paris ?"))
# -> Gemini appelle get_weather ET get_time en parallele !
Parallel Function Calling
Gemini peut retourner plusieurs function_call dans une seule reponse. Par exemple, "Quelle meteo a Paris et a Londres ?" genere 2 appels get_weather simultanement. Votre code doit gerer ce cas en iterant sur toutes les parts.
Compositional Calling (chaine)
Avec Gemini 2.5+ et 3, le modele peut enchainer les fonctions automatiquement. Par exemple : "Quelle meteo dans ma ville ?" -> appelle d'abord get_location(), puis get_weather(city=result).
La boucle while True avec verification des function calls est le pattern fondamental. Memorisez-le. 90% des applications agents suivent ce pattern : envoyer -> verifier si function call -> executer -> renvoyer le resultat -> repeter jusqu'a reponse texte finale.
Code Execution Tool
Objectifs
- Activer le Code Execution Tool
- Comprendre l'environnement sandbox
- Combiner code execution avec du texte
- Connaitre les limites et libraries disponibles
Activer le Code Execution
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE_API")
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Calcule les 20 premiers nombres de Fibonacci "
"et trace un graphique de leur croissance.",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.CodeExecution())]
)
)
# La reponse contient le code execute ET le resultat
for part in response.candidates[0].content.parts:
if part.executable_code:
print(f"CODE:\n{part.executable_code.code}")
if part.code_execution_result:
print(f"RESULTAT:\n{part.code_execution_result.output}")
if part.text:
print(f"TEXTE:\n{part.text}")
Libraries disponibles dans le sandbox
| Library | Usage |
|---|---|
| NumPy | Calcul numerique, matrices, algebre lineaire |
| pandas | Manipulation de donnees, DataFrames |
| matplotlib | Visualisation, graphiques |
| math, statistics | Fonctions mathematiques standard |
| datetime, json, re | Utilitaires Python standard |
Pas d'acces reseau (pas de requests, urllib). Pas de pip install. Pas d'acces au systeme de fichiers. Pas de libraries custom. Le code est execute dans un environnement isole et securise cote Google.
Le Code Execution est ideal pour : calculs mathematiques precis, generation de graphiques, transformation de donnees, validation d'hypotheses. Ne l'utilisez pas pour des taches qui necessitent des APIs externes - utilisez le function calling pour ca.
Google Search Tool (API)
Objectifs
- Utiliser le grounding Google Search programmatiquement
- Exploiter les groundingMetadata et citations
- Comprendre le Dynamic Retrieval
- Evaluer le cout ($35/1K requetes)
Activation via API
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE_API")
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Quels sont les derniers modeles Gemini sortis en 2026 "
"et leurs performances sur les benchmarks ?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())]
)
)
print(response.text)
# Acceder aux sources et citations
grounding = response.candidates[0].grounding_metadata
if grounding:
print("\n--- SOURCES ---")
if grounding.grounding_chunks:
for chunk in grounding.grounding_chunks:
if chunk.web:
print(f" [{chunk.web.title}]({chunk.web.uri})")
# Requetes de recherche utilisees par le modele
if grounding.web_search_queries:
print("\n--- REQUETES ---")
for query in grounding.web_search_queries:
print(f" - {query}")
Quand utiliser le Search Grounding
| Utiliser Search | Ne PAS utiliser Search |
|---|---|
| Questions factuelles sur l'actualite | Raisonnement logique/math |
| Verification de faits | Generation creative |
| Donnees en temps reel (prix, cours, meteo) | Analyse de documents internes |
| Recherche technique a jour | Conversations generales |
Google Search Grounding : $35 par 1 000 requetes via API. Gratuit dans AI Studio pour les tests. En production, filtrez les requetes qui necessitent vraiment le grounding pour maitriser les couts.
URL Context Tool
Objectifs
- Extraire du contenu depuis des URLs avec Gemini
- Combiner URL Context avec Structured Output
- Cas d'usage : scraping intelligent, analyse de pages
URL Context en action
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE_API")
# Gemini 3 supporte l'URL Context comme outil integre
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Analyse la page https://ai.google.dev/gemini-api/docs/pricing "
"et extrais un tableau comparatif des prix par modele.",
config=types.GenerateContentConfig(
tools=[types.Tool(url_context=types.UrlContext())],
response_mime_type="application/json",
response_schema={
"type": "array",
"items": {
"type": "object",
"properties": {
"model": {"type": "string"},
"input_price": {"type": "string"},
"output_price": {"type": "string"},
"context_window": {"type": "string"}
}
}
}
)
)
import json
data = json.loads(response.text)
for model in data:
print(f"{model['model']}: {model['input_price']} / {model['output_price']}")
L'URL Context combine le meilleur du scraping web et de l'extraction IA. Avec le structured output, vous obtenez des donnees propres et structurees depuis n'importe quelle page web. C'est un outil puissant pour le competitive intelligence, la veille technologique et l'enrichissement de donnees.
Combinaison multi-outils
Objectifs
- Combiner Search + Code Execution + Function Calling
- Comprendre les priorites et l'orchestration
- Patterns multi-outils avances
Combiner tous les outils
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE_API")
# Fonction custom
save_report = types.FunctionDeclaration(
name="save_report",
description="Sauvegarde un rapport d'analyse dans le systeme",
parameters=types.Schema(
type="OBJECT",
properties={
"title": types.Schema(type="STRING"),
"content": types.Schema(type="STRING"),
"format": types.Schema(type="STRING", enum=["pdf", "html", "md"])
},
required=["title", "content"]
)
)
# Combiner : Search + Code Execution + Custom Function
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Recherche les dernieres stats d'adoption de Kubernetes en 2026, "
"calcule les tendances de croissance avec un graphique, "
"puis sauvegarde le rapport en PDF.",
config=types.GenerateContentConfig(
tools=[
types.Tool(google_search=types.GoogleSearch()),
types.Tool(code_execution=types.CodeExecution()),
types.Tool(function_declarations=[save_report])
]
)
)
# Gemini orchestre automatiquement :
# 1. Google Search -> donnees actuelles
# 2. Code Execution -> calcul + graphique
# 3. save_report() -> sauvegarde du resultat
ββββββββββββ ORCHESTRATION MULTI-OUTILS ββββββββββββ β β β User: "Analyse + Calcule + Sauvegarde" β β β β β βΌ β β ββββ Gemini decide l'ordre ββββ β β β β β β β 1. Google Search β β β β -> donnees fraiches β β β β β β β β 2. Code Execution β β β β -> calcul + graphique β β β β β β β β 3. Function Call β β β β -> save_report(...) β β β ββββββββββββββββββββββββββββββββ β β β β β βΌ β β Reponse finale avec resume β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Nouveaute Gemini 3 : vous pouvez combiner Structured Output (response_schema) avec les outils integres. Le modele utilise Search/Code Execution et formate le resultat en JSON conforme a votre schema.
Lab : Agent meteo & actualites
Objectif : Agent conversationnel avec function calling + Google Search
Etape 1 : Definir les outils
import os, json, requests
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
# Outil meteo (simule)
get_weather_fn = types.FunctionDeclaration(
name="get_weather",
description="Obtient la meteo actuelle pour une ville",
parameters=types.Schema(
type="OBJECT",
properties={
"city": types.Schema(type="STRING"),
"country": types.Schema(type="STRING", description="Code pays ISO")
},
required=["city"]
)
)
# Outil conversion
convert_unit_fn = types.FunctionDeclaration(
name="convert_temperature",
description="Convertit une temperature entre Celsius et Fahrenheit",
parameters=types.Schema(
type="OBJECT",
properties={
"value": types.Schema(type="NUMBER"),
"from_unit": types.Schema(type="STRING", enum=["celsius", "fahrenheit"]),
"to_unit": types.Schema(type="STRING", enum=["celsius", "fahrenheit"])
},
required=["value", "from_unit", "to_unit"]
)
)
custom_tools = types.Tool(function_declarations=[get_weather_fn, convert_unit_fn])
Etape 2 : Implementer les fonctions
def execute(name, args):
if name == "get_weather":
# Simuler une API meteo
meteo_db = {
"paris": {"temp": 14, "condition": "Nuageux", "humidity": 72, "wind": "15 km/h"},
"london": {"temp": 9, "condition": "Pluvieux", "humidity": 85, "wind": "22 km/h"},
"tokyo": {"temp": 18, "condition": "Ensoleille", "humidity": 55, "wind": "8 km/h"},
}
city = args["city"].lower()
return meteo_db.get(city, {"error": f"Ville '{args['city']}' non trouvee"})
elif name == "convert_temperature":
v = args["value"]
if args["from_unit"] == "celsius" and args["to_unit"] == "fahrenheit":
return {"result": round(v * 9/5 + 32, 1), "unit": "fahrenheit"}
elif args["from_unit"] == "fahrenheit" and args["to_unit"] == "celsius":
return {"result": round((v - 32) * 5/9, 1), "unit": "celsius"}
return {"result": v, "unit": args["to_unit"]}
Etape 3 : Boucle agent conversationnel
SYSTEM = """Tu es un assistant meteo et actualites. Tu utilises tes outils pour:
- get_weather: obtenir la meteo d'une ville
- convert_temperature: convertir des temperatures
- Google Search: rechercher des actualites
Tu reponds toujours en francais de maniere claire et concise."""
def agent_loop(user_msg, history):
history.append(types.Content(role="user", parts=[types.Part(text=user_msg)]))
while True:
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=history,
config=types.GenerateContentConfig(
system_instruction=SYSTEM,
tools=[
custom_tools,
types.Tool(google_search=types.GoogleSearch())
]
)
)
candidate = response.candidates[0]
history.append(candidate.content)
fn_calls = [p for p in candidate.content.parts if p.function_call]
if not fn_calls:
return response.text
responses = []
for part in fn_calls:
result = execute(part.function_call.name, dict(part.function_call.args))
responses.append(types.Part(function_response=types.FunctionResponse(
name=part.function_call.name, response=result
)))
history.append(types.Content(parts=responses))
# Test
history = []
print(agent_loop("Quel temps fait-il a Paris et Tokyo ?", history))
print(agent_loop("Convertis la temperature de Tokyo en Fahrenheit", history))
print(agent_loop("Quelles sont les actualites tech du jour ?", history))
Quiz - Module 2.1 : Function Calling & Tools
Testez vos connaissances
1. En mode ANY, que fait le modele ?
2. Qui execute reellement les fonctions dans le function calling ?
3. Quelles libraries sont disponibles dans le Code Execution sandbox ?
4. Combien coute le Google Search Grounding via API ?
5. Que permet le compositional function calling de Gemini 2.5+ ?
Introduction aux agents IA Google
Objectifs
- Comprendre le paradigme agent : perceive-reason-act
- Decouvrir l'ecosysteme Google pour les agents
- Differencier chatbot, agent et systeme multi-agents
- Connaitre Agent Builder, ADK et Agent Engine
Qu'est-ce qu'un Agent IA ?
Un agent IA est un systeme autonome qui percoit son environnement, raisonne sur les actions a entreprendre, et agit en utilisant des outils pour atteindre un objectif. Contrairement a un chatbot qui se contente de repondre a des questions, un agent peut planifier, executer des actions, et s'adapter en fonction des resultats.
βββββββββββββββββββ BOUCLE AGENT βββββββββββββββββββ β β β βββββββββββββ βββββββββββββ ββββββββββββ β β β PERCEVOIR βββββΊβ RAISONNER βββββΊβ AGIR β β β β β β β β β β β β - Input β β - Gemini β β - Tools β β β β - Context β β - Planningβ β - APIs β β β β - Memory β β - Decisionβ β - Search β β β βββββββββββββ βββββββββββββ ββββββ¬ββββββ β β β² β β β β βββββββββββββ β β β βββββββββββ OBSERVER ββββββββββββββ β β β le result β β β βββββββββββββ β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
L'ecosysteme Google pour les Agents
Google propose une stack complete pour construire des agents, du framework open-source jusqu'au deploiement enterprise :
| Composant | Description | Usage |
|---|---|---|
| ADK | Agent Development Kit - Framework open-source Python | Developpement local d'agents |
| Agent Builder | Interface visuelle dans Vertex AI | Creation no-code/low-code |
| Agent Engine | Runtime manage pour deployer des agents | Production et scaling |
| Agentspace | Hub enterprise pour les agents | Partage et decouverte d'agents |
Chatbot vs Agent vs Multi-Agent
| Caracteristique | Chatbot | Agent | Multi-Agent |
|---|---|---|---|
| Outils | Aucun | Function calling, search, code | Outils specialises par agent |
| Memoire | Contexte de session | Sessions + Memory Bank | Memoire partagee entre agents |
| Autonomie | Repond aux questions | Planifie et execute | Delegation et collaboration |
| Complexite | Faible | Moyenne | Elevee |
En 2026, la tendance est claire : on passe du chatbot a l'agent. Google a investi massivement dans ADK et Agent Builder. Mon conseil ? Commencez par un agent simple avec ADK, puis evoluez vers le multi-agents quand le besoin se presente. Ne sur-architecturez pas des le depart.
Agent Development Kit (ADK)
Objectifs
- Installer et configurer ADK
- Creer un agent avec LlmAgent
- Definir des outils custom (FunctionTool)
- Tester un agent avec adk web
Installation et Setup
ADK (Agent Development Kit) est le framework open-source de Google pour construire des agents IA. Il fournit une structure claire pour definir des agents, leurs outils, leur memoire et leur orchestration.
# Installation pip install google-adk # Structure de projet recommandee my_agent/ βββ __init__.py βββ agent.py # Definition de l'agent βββ tools.py # Outils custom βββ .env # GOOGLE_API_KEY=...
Premier Agent avec LlmAgent
from google.adk.agents import LlmAgent
from google.adk.tools import FunctionTool, google_search
# Definir un outil custom
def get_current_time(timezone: str = "UTC") -> dict:
"""Retourne l'heure actuelle dans le fuseau horaire donne."""
from datetime import datetime
import pytz
tz = pytz.timezone(timezone)
now = datetime.now(tz)
return {"time": now.strftime("%H:%M:%S"), "timezone": timezone}
# Creer l'agent
agent = LlmAgent(
name="assistant_agent",
model="gemini-2.5-flash",
instruction="""Tu es un assistant intelligent.
Utilise tes outils pour repondre aux questions.
Sois precis et concis dans tes reponses.""",
tools=[
FunctionTool(get_current_time),
google_search, # Outil built-in
],
)
Lancer l'agent en local
# Lancer l'interface de test web adk web # Ou executer directement en Python adk run my_agent
βββββββββββββ ARCHITECTURE ADK βββββββββββββββ β β β LlmAgent β β βββ name: "assistant_agent" β β βββ model: "gemini-2.5-flash" β β βββ instruction: "Tu es un..." β β βββ tools: β β β βββ FunctionTool(get_current_time) β β β βββ google_search β β β βββ code_execution β β βββ sub_agents: [] β β βββ callbacks: β β βββ before_tool_callback β β βββ after_model_callback β β β ββββββββββββββββββββββββββββββββββββββββββββββββ
Types d'outils ADK
| Type | Import | Usage |
|---|---|---|
| FunctionTool | from google.adk.tools import FunctionTool | Wrapper pour vos fonctions Python |
| google_search | from google.adk.tools import google_search | Recherche Google integree |
| code_execution | from google.adk.tools import code_execution | Sandbox Python du modele |
| AgentTool | from google.adk.tools import AgentTool | Encapsule un agent comme outil |
ADK est le futur du developpement d'agents chez Google. La commande adk web lance une interface de test locale tres pratique pour debugger vos agents. Utilisez-la systematiquement pendant le developpement avant de deployer sur Agent Engine.
Sessions & Memory Bank
Objectifs
- Gerer la memoire court terme avec les Sessions
- Utiliser InMemorySessionService et DatabaseSessionService
- Implementer la memoire long terme avec Memory Bank
- Persister le contexte entre les interactions
Sessions : Memoire Court Terme
Les Sessions dans ADK gerent la memoire d'une conversation en cours. Chaque session contient l'historique des messages et un state (dictionnaire) pour stocker des variables persistantes pendant la conversation.
from google.adk.sessions import InMemorySessionService
# Service de sessions en memoire (dev/test)
session_service = InMemorySessionService()
# Creer une session
session = await session_service.create_session(
app_name="my_agent",
user_id="user_123",
)
# Acceder au state de la session
session.state["user_preferences"] = {"language": "fr", "theme": "dark"}
session.state["interaction_count"] = 0
print(f"Session ID: {session.id}")
print(f"State: {session.state}")
Persistence avec DatabaseSessionService
from google.adk.sessions import DatabaseSessionService
# Session persistante en base de donnees
session_service = DatabaseSessionService(
db_url="sqlite:///sessions.db"
# Ou PostgreSQL: "postgresql://user:pass@host/db"
)
# Les sessions survivent aux redemarrages
session = await session_service.get_session(
app_name="my_agent",
user_id="user_123",
session_id="existing_session_id"
)
Memory Bank : Memoire Long Terme
Le Memory Bank (GA en 2026) va au-dela des sessions. Il stocke des informations a long terme entre les sessions, permettant a l'agent de "se souvenir" d'interactions passees.
from google.adk.memory import InMemoryMemoryService
# Service de memoire long terme
memory_service = InMemoryMemoryService()
# L'agent avec memoire
agent = LlmAgent(
name="memory_agent",
model="gemini-2.5-flash",
instruction="Tu te souviens des preferences de l'utilisateur.",
tools=[google_search],
)
# Executer avec session + memoire
from google.adk.runners import Runner
runner = Runner(
agent=agent,
app_name="my_agent",
session_service=session_service,
memory_service=memory_service,
)
# Le runner gere automatiquement la memoire
response = await runner.run(
user_id="user_123",
session_id=session.id,
new_message="Rappelle-toi que j'aime le Python"
)
βββββββββββββ MEMOIRE ADK βββββββββββββββββ
β β
β SESSION (court terme) β
β βββββββββββββββββββββββββββββββββββ β
β β Messages: [user, model, ...] β β
β β State: {prefs: {}, count: 3} β β
β β TTL: duree de la conversation β β
β βββββββββββββββββββββββββββββββββββ β
β β
β MEMORY BANK (long terme) β
β βββββββββββββββββββββββββββββββββββ β
β β Faits: "Aime Python et FastAPI" β β
β β Preferences: "Theme dark, FR" β β
β β Historique: resume interactions β β
β β TTL: indefini β β
β βββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββ
Multi-Agent Systems avec ADK
Objectifs
- Comprendre les patterns d'orchestration multi-agents
- Utiliser SequentialAgent, ParallelAgent et LoopAgent
- Deleguer des taches entre agents avec sub_agents
- Communiquer entre agents via le session state
Patterns d'Orchestration
ADK propose trois types d'agents orchestrateurs pour combiner plusieurs agents specialises :
| Pattern | Classe | Comportement | Cas d'usage |
|---|---|---|---|
| Sequentiel | SequentialAgent | Execute les agents un par un, dans l'ordre | Pipeline ETL, workflow lineaire |
| Parallele | ParallelAgent | Execute tous les agents simultanement | Recherche multi-sources, analyses independantes |
| Boucle | LoopAgent | Repete un agent jusqu'a condition de sortie | Raffinement iteratif, validation |
βββββββββββββ MULTI-AGENT HIERARCHY βββββββββββββββ β β β ββββββββββββββββ β β β Orchestrator β β β β (Sequential) β β β ββββββββ¬ββββββββ β β β β β βββββββββββββΌββββββββββββ β β βΌ βΌ βΌ β β ββββββββββββββ βββββββββββ ββββββββββββ β β β Researcher β β Analyst β β Writer β β β β β β β β β β β β Tools: β β Tools: β β Tools: β β β β - search β β - code β β - none β β β β - url_ctx β β exec β β β β β ββββββββββββββ βββββββββββ ββββββββββββ β β β β Communication via session.state : β β researcher -> state["research_data"] β β analyst -> state["analysis_results"] β β writer -> state["final_report"] β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Exemple : Systeme 3 agents
from google.adk.agents import LlmAgent, SequentialAgent, ParallelAgent
from google.adk.tools import FunctionTool, google_search
# Agent 1 : Chercheur
researcher = LlmAgent(
name="researcher",
model="gemini-2.5-flash",
instruction="""Recherche des informations sur le sujet demande.
Stocke tes resultats dans state['research_data'].""",
tools=[google_search],
output_key="research_data", # Auto-save dans state
)
# Agent 2 : Analyste
analyst = LlmAgent(
name="analyst",
model="gemini-2.5-flash",
instruction="""Analyse les donnees de recherche dans state['research_data'].
Produis une analyse structuree avec points cles et tendances.""",
output_key="analysis_results",
)
# Agent 3 : Redacteur
writer = LlmAgent(
name="writer",
model="gemini-2.5-flash",
instruction="""A partir de state['analysis_results'],
redige un rapport professionnel en francais.
Structure : resume, points cles, recommandations.""",
output_key="final_report",
)
# Orchestrateur sequentiel
pipeline = SequentialAgent(
name="research_pipeline",
sub_agents=[researcher, analyst, writer],
)
AgentTool : Agent comme outil
from google.adk.tools import AgentTool
# Wrapper un agent specialise comme outil
expert_tool = AgentTool(agent=analyst)
# L'agent principal peut appeler l'expert
supervisor = LlmAgent(
name="supervisor",
model="gemini-2.5-pro",
instruction="Tu supervises et delegues aux experts.",
tools=[expert_tool, google_search],
sub_agents=[researcher, writer], # Delegation directe
)
Le pattern le plus courant en production est le SequentialAgent avec 2-3 agents specialises. N'abusez pas du multi-agent : chaque agent ajoute de la latence et des couts. Utilisez ParallelAgent uniquement quand les taches sont vraiment independantes (ex: recherche sur 3 sources differentes).
Interactions API & MCP
Objectifs
- Comprendre l'Interactions API pour les agents
- Maitriser le Model Context Protocol (MCP)
- Connecter un agent ADK a un serveur MCP
- Configurer des outils externes via MCP
Interactions API
L'Interactions API est le mecanisme natif de Google pour permettre aux agents d'utiliser des outils externes de maniere standardisee. Elle fournit un framework pour definir, decouvrir et invoquer des outils a travers des services.
Model Context Protocol (MCP)
Le MCP (Model Context Protocol) est un standard ouvert (propose par Anthropic, adopte par Google) qui permet a n'importe quel agent de se connecter a des serveurs d'outils distants. C'est le "USB-C des agents IA" : un connecteur universel.
ββββββββββββββ MCP ARCHITECTURE βββββββββββββββββββ β β β βββββββββββ ββββββββββββββββ β β β Agent ββββMCPβββΊβ MCP Server β β β β (ADK) β β β β β βββββββββββ β Tools: β β β β - database β β β βββββββββββ β - file_ops β β β β Agent ββββMCPβββΊβ - api_calls β β β β (autre) β ββββββββ¬ββββββββ β β βββββββββββ β β β βββββββΌβββββββ β β β External β β β β Services β β β β - DB β β β β - APIs β β β β - Files β β β ββββββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Connecter un agent ADK a MCP
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import MCPToolset
from google.adk.tools.mcp_tool import SseServerParams, StdioServerParams
# Option 1 : Serveur MCP distant (SSE)
mcp_tools_remote = MCPToolset(
connection_params=SseServerParams(
url="https://my-mcp-server.example.com/sse",
headers={"Authorization": "Bearer TOKEN"}
)
)
# Option 2 : Serveur MCP local (stdio)
mcp_tools_local = MCPToolset(
connection_params=StdioServerParams(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/data"]
)
)
# Agent avec outils MCP
agent = LlmAgent(
name="mcp_agent",
model="gemini-2.5-flash",
instruction="Utilise les outils MCP pour acceder aux donnees.",
tools=[mcp_tools_remote], # Ou mcp_tools_local
)
Serveurs MCP populaires
| Serveur MCP | Outils fournis | Transport |
|---|---|---|
| filesystem | Lecture/ecriture de fichiers, navigation dossiers | stdio |
| github | Issues, PRs, repos, fichiers | SSE |
| postgres | Requetes SQL, schema, tables | stdio |
| slack | Messages, channels, users | SSE |
| google-drive | Documents, partage, recherche | SSE |
Gemini CLI & Firebase Studio
Objectifs
- Utiliser Gemini CLI comme assistant en terminal
- Configurer MCP dans Gemini CLI
- Decouvrir Firebase Studio pour le prototypage
- Deployer rapidement depuis Firebase Studio
Gemini CLI
Gemini CLI est un outil en ligne de commande qui apporte la puissance de Gemini directement dans votre terminal. Il supporte MCP, le contexte de fichiers locaux, et l'execution de commandes.
# Installation npm install -g @anthropic-ai/gemini-cli # Ou via Google npm install -g @google/gemini-cli # Utilisation basique gemini "Explique ce fichier" --file main.py # Mode interactif gemini chat # Avec contexte de projet gemini "Corrige les bugs" --dir ./src
Configuration MCP dans Gemini CLI
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxx"
}
}
}
}
Firebase Studio
Firebase Studio (anciennement Project IDX) est un IDE cloud de Google avec IA integree. Son atout majeur : l'App Prototyping agent qui genere des applications completes a partir d'une description en langage naturel.
| Fonctionnalite | Description |
|---|---|
| App Prototyping | Genere une app complete (frontend + backend) depuis un prompt |
| Gemini Integration | Gemini 2.5 Pro integre dans l'editeur pour code assist |
| Nix Templates | Environnements preconfigures (Next.js, Flutter, Python, Go...) |
| Preview | Previsualisation web en temps reel dans l'IDE |
| Deploy | Deploiement one-click vers Firebase Hosting ou Cloud Run |
# Exemple de prompt pour App Prototyping : "Cree une application web de gestion de taches avec : - Interface React avec Material UI - Backend Firebase avec Firestore - Authentification Google - CRUD complet sur les taches - Filtres par statut et priorite" # Firebase Studio genere automatiquement : # - Code frontend React complet # - Configuration Firebase # - Rules Firestore # - Deploiement configure
Firebase Studio est un outil formidable pour le prototypage rapide. En 5 minutes, vous pouvez avoir une app fonctionnelle deployee. Mais pour la production enterprise, preferez un workflow CI/CD classique. Gemini CLI, en revanche, est un outil quotidien indispensable - configurez-le avec MCP pour booster votre productivite.
Lab : Systeme multi-agents
Objectifs
- Construire un systeme multi-agents complet avec ADK
- Implementer recherche, analyse et redaction automatisees
- Orchestrer avec SequentialAgent et session state
- Tester et valider le pipeline complet
Projet : Pipeline Recherche-Analyse-Rapport
Construisez un systeme de 3 agents qui recherche un sujet, analyse les resultats et produit un rapport structure.
Etape 1 : Setup du projet
# Creer la structure mkdir research_system && cd research_system pip install google-adk # Structure research_system/ βββ __init__.py βββ agent.py βββ .env # GOOGLE_API_KEY=votre_cle
Etape 2 : Definir le ResearchAgent
from google.adk.agents import LlmAgent, SequentialAgent
from google.adk.tools import google_search, code_execution
# Agent 1 : Recherche
research_agent = LlmAgent(
name="researcher",
model="gemini-2.5-flash",
instruction="""Tu es un chercheur expert.
Pour chaque sujet demande :
1. Effectue 3-5 recherches Google pertinentes
2. Synthetise les informations cles
3. Identifie les sources fiables
4. Stocke les resultats structures dans ta reponse.
Format: points cles avec sources.""",
tools=[google_search],
output_key="research_data",
)
Etape 3 : Definir l'AnalysisAgent
# Agent 2 : Analyse avec code execution
analysis_agent = LlmAgent(
name="analyst",
model="gemini-2.5-flash",
instruction="""Tu es un analyste de donnees.
A partir des donnees de recherche dans state['research_data'] :
1. Identifie les tendances principales
2. Classe les informations par importance
3. Utilise code_execution pour creer des stats si pertinent
4. Produis une analyse structuree.""",
tools=[code_execution],
output_key="analysis_results",
)
Etape 4 : Definir le ReportAgent
# Agent 3 : Redaction du rapport
report_agent = LlmAgent(
name="writer",
model="gemini-2.5-flash",
instruction="""Tu es un redacteur professionnel.
A partir de state['analysis_results'] :
1. Redige un rapport structure en francais
2. Sections : Resume executif, Analyse, Recommandations
3. Utilise un ton professionnel et factuel
4. Limite : 500 mots maximum.""",
output_key="final_report",
)
Etape 5 : Orchestrateur SequentialAgent
# Pipeline sequentiel
root_agent = SequentialAgent(
name="research_pipeline",
sub_agents=[research_agent, analysis_agent, report_agent],
)
Etape 6 : Executer le systeme
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
import asyncio
async def main():
session_service = InMemorySessionService()
runner = Runner(
agent=root_agent,
app_name="research_system",
session_service=session_service,
)
session = await session_service.create_session(
app_name="research_system",
user_id="demo_user",
)
response = await runner.run(
user_id="demo_user",
session_id=session.id,
new_message="Analyse les tendances de l'IA generative en 2026"
)
# Afficher le rapport final
print("=== RAPPORT ===")
print(session.state.get("final_report", "Pas de rapport"))
asyncio.run(main())
Etape 7 : Tester avec adk web
# Lancer l'interface de test adk web # Ouvrir http://localhost:8000 # Selectionner "research_pipeline" # Tester avec differents sujets # Observer l'execution sequentielle des 3 agents
Quiz Module 2.2 - Agents & ADK
Testez vos connaissances sur les Agents & ADK
1. Quelle est la difference principale entre un chatbot et un agent IA ?
2. Quelle commande lance l'interface de test locale d'ADK ?
3. Quel service fournit la memoire long terme dans ADK ?
4. Quel agent orchestrateur execute les sous-agents un par un dans l'ordre ?
5. Quel protocole standardise l'integration d'outils externes pour les agents ?
6. Quelle fonctionnalite de Firebase Studio genere des apps depuis un prompt ?
7. Comment les agents communiquent-ils dans un systeme multi-agents ADK ?
Live API : Streaming temps reel
Objectifs
- Comprendre l'architecture WebSocket de la Live API
- Implementer un streaming bidirectionnel audio/video
- Gerer les sessions et la reconnexion
- Comparer REST API vs Live API
Qu'est-ce que la Live API ?
La Live API de Gemini est une API basee sur WebSocket qui permet des interactions bidirectionnelles en temps reel avec une latence inferieure a la seconde. Contrairement a l'API REST classique (requete/reponse), la Live API maintient une connexion persistante pour envoyer et recevoir de l'audio, de la video et du texte simultanement.
βββββββββββββ LIVE API ARCHITECTURE βββββββββββββββ β β β CLIENT SERVEUR GEMINI β β ββββββββββββ WebSocket ββββββββββββββββ β β β ββββββββββββββββββΊβ β β β β Audio β bidirectionnelβ Gemini β β β β input ββββββββββββββββββΊβ 2.5 Flash β β β β (micro) β β β β β β βββββββββββββββββββ Processing β β β β Audio β audio chunks β + Tools β β β β output β β + Grounding β β β β (HP) β β β β β β ββββββββββββββββββΊβ β β β β Video β video frames β β β β β input β β β β β ββββββββββββ ββββββββββββββββ β β β β Latence : < 500ms (TTFT) β β Modeles : gemini-2.5-flash, gemini-2.0-flash β β Duree max session : 15 minutes β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Connexion WebSocket
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE")
# Configuration Live API
config = types.LiveConnectConfig(
response_modalities=["AUDIO"], # ou ["TEXT"], ["AUDIO", "TEXT"]
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Puck" # Voix disponible
)
)
),
tools=[
types.Tool(google_search_retrieval=
types.GoogleSearchRetrieval()),
],
)
# Connexion live
async with client.aio.live.connect(
model="gemini-2.5-flash",
config=config
) as session:
# Envoyer du texte
await session.send_client_content(
turns=types.Content(
role="user",
parts=[types.Part(text="Bonjour, quel temps fait-il ?")]
)
)
# Recevoir la reponse en streaming
async for response in session.receive():
if response.text:
print(response.text, end="", flush=True)
if response.data:
# Audio bytes a jouer
play_audio(response.data)
REST API vs Live API
| Critere | REST API | Live API |
|---|---|---|
| Protocole | HTTP/HTTPS | WebSocket |
| Direction | Requete β Reponse | Bidirectionnel continu |
| Latence | 1-5 secondes | < 500ms |
| Input | Texte, images, fichiers | Audio, video, texte en temps reel |
| Duree | Par requete | Session jusqu'a 15 min |
| Cas d'usage | Traitement batch, chatbot texte | Voix, video, assistant temps reel |
Native Audio & Voice
Objectifs
- Utiliser le modele native audio pour la parole
- Configurer les voix disponibles (Puck, Kore, Charon...)
- Implementer text-to-speech et speech-to-text
- Construire des conversations audio bidirectionnelles
Native Audio : Comprehension naturelle
Le modele gemini-2.5-flash-native-audio-preview comprend nativement la parole humaine - intonation, emotion, pauses, hesitations. Ce n'est pas une simple transcription : le modele traite l'audio comme une modalite de premiere classe.
Voix disponibles
| Voix | Genre | Style | Langues |
|---|---|---|---|
| Puck | Masculin | Energique, jeune | Multi-langue |
| Charon | Masculin | Grave, professionnel | Multi-langue |
| Kore | Feminin | Clair, articule | Multi-langue |
| Fenrir | Masculin | Chaleureux, narratif | Multi-langue |
| Aoede | Feminin | Doux, melodique | Multi-langue |
| Leda | Feminin | Neutre, informatif | Multi-langue |
| Orus | Masculin | Autoritaire, expert | Multi-langue |
| Zephyr | Non-binaire | Leger, amical | Multi-langue |
Text-to-Speech avec Gemini
from google import genai
from google.genai import types
import wave, struct
client = genai.Client(api_key="VOTRE_CLE")
# Generation audio depuis du texte
response = client.models.generate_content(
model="gemini-2.5-flash-native-audio-preview",
contents="Bonjour ! Je suis votre assistant vocal Gemini.",
config=types.GenerateContentConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Kore"
)
)
),
),
)
# Sauvegarder l'audio en WAV
audio_data = response.candidates[0].content.parts[0].inline_data.data
with wave.open("output.wav", "wb") as wf:
wf.setnchannels(1)
wf.setsampwidth(2) # 16-bit PCM
wf.setframerate(24000) # 24kHz
wf.writeframes(audio_data)
Conversation audio bidirectionnelle
# Via Live API pour le bidirectionnel
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Charon"
)
)
),
)
async with client.aio.live.connect(
model="gemini-2.5-flash",
config=config
) as session:
# Envoyer de l'audio du microphone
while True:
audio_chunk = capture_microphone(duration_ms=200)
await session.send_realtime_input(
media=types.Blob(
data=audio_chunk,
mime_type="audio/pcm;rate=16000"
)
)
# Recevoir et jouer la reponse
async for msg in session.receive():
if msg.data:
play_speaker(msg.data)
Les voix Gemini sont impressionnantes en qualite. Pour une application francophone, je recommande Kore ou Charon qui offrent une excellente prononciation francaise. Testez toujours avec votre audience cible - la perception des voix IA varie selon les cultures.
Embeddings API
Objectifs
- Generer des embeddings avec gemini-embedding-001
- Comprendre Matryoshka Representation Learning (MRL)
- Choisir les dimensions (768, 1536, 3072)
- Utiliser les task types pour optimiser la qualite
Qu'est-ce qu'un Embedding ?
Un embedding est une representation vectorielle d'un texte - un tableau de nombres qui capture le sens semantique. Deux textes similaires auront des vecteurs proches. C'est la brique fondamentale du RAG (Retrieval-Augmented Generation) et de la recherche semantique.
ββββββββββββ WORKFLOW EMBEDDINGS ββββββββββββββββ β β β INDEXATION RECHERCHE β β ββββββββββββ ββββββββββββ β β β Document β β Query β β β β "Gemini β β "modele β β β β est un β β Google" β β β β modele" β ββββββ¬ββββββ β β ββββββ¬ββββββ β β β β β β β βΌ βΌ β β ββββββββββββ ββββββββββββ β β β Embed β β Embed β β β β [0.12, β β [0.11, β β β β 0.85, β β 0.83, β β β β ...] β β ...] β β β ββββββ¬ββββββ ββββββ¬ββββββ β β β β β β βΌ βΌ β β ββββββββββββ ββββββββββββββ β β β Vector βββββcosineβββ Similarite β β β β Database β similarity β = 0.95 β β β ββββββββββββ ββββββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Generer des Embeddings
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE")
# Embedding simple
result = client.models.embed_content(
model="gemini-embedding-001",
contents="Gemini est le modele IA de Google",
config=types.EmbedContentConfig(
task_type="RETRIEVAL_DOCUMENT",
output_dimensionality=768, # MRL : 768, 1536 ou 3072
),
)
vector = result.embeddings[0].values
print(f"Dimensions: {len(vector)}") # 768
print(f"Premiers: {vector[:5]}") # [0.012, -0.034, ...]
Batch Embeddings
# Embeddings par lot (plus efficace)
texts = [
"Gemini 2.5 Flash est rapide et economique",
"Le RAG combine retrieval et generation",
"Les agents utilisent des outils pour agir",
"Le context caching reduit les couts de 90%",
]
result = client.models.embed_content(
model="gemini-embedding-001",
contents=texts,
config=types.EmbedContentConfig(
task_type="RETRIEVAL_DOCUMENT",
output_dimensionality=1536,
),
)
for i, emb in enumerate(result.embeddings):
print(f"Text {i}: {len(emb.values)} dimensions")
Task Types & Dimensions
| Task Type | Usage |
|---|---|
| RETRIEVAL_DOCUMENT | Indexer des documents pour la recherche |
| RETRIEVAL_QUERY | Encoder les requetes de recherche |
| SEMANTIC_SIMILARITY | Comparer la similarite entre textes |
| CLASSIFICATION | Classifier des textes par categories |
| CLUSTERING | Regrouper des textes similaires |
| CODE_RETRIEVAL | Recherche semantique dans du code |
| QUESTION_ANSWERING | Trouver des reponses dans une base |
| Dimensions | Stockage | Performance | Recommandation |
|---|---|---|---|
| 768 | Minimal | Bonne | Prototypage, gros volumes |
| 1536 | Moyen | Tres bonne | Production standard |
| 3072 | Maximum | Excellente | Precision maximale requise |
Batch API
Objectifs
- Comprendre le traitement batch asynchrone
- Economiser 50% sur les couts API
- Creer et monitorer des batch jobs
- Utiliser le format JSONL pour les lots
Pourquoi utiliser le Batch API ?
Le Batch API permet de soumettre des lots de requetes a traiter de maniere asynchrone, avec une reduction de 50% sur les couts. Ideal pour le traitement en masse ou les taches non urgentes qui n'ont pas besoin de reponse immediate.
βββββββββββββ BATCH API WORKFLOW ββββββββββββββββββ β β β 1. PREPARATION 2. SOUMISSION β β ββββββββββββ βββββββββββββββββ β β β Fichier ββββββββββΊβ batches.createβ β β β JSONL β β β β β β (N req) β β Status: β β β ββββββββββββ β PENDING β β β βββββββββ¬ββββββββ β β β β β 4. RESULTATS 3. PROCESSING β β ββββββββββββ βββββββββββββββββ β β β Output βββββββββββ Gemini traite β β β β JSONL β β en background β β β β (N resp) β β (jusqu'a 24h) β β β ββββββββββββ β -50% cout β β β βββββββββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Creer un Batch Job
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE")
# Methode 1 : Inline requests
batch_job = client.batches.create(
model="gemini-2.5-flash",
requests=[
types.BatchRequest(
custom_id="req-001",
request=types.GenerateContentRequest(
contents="Resume cet article en 3 points : ...",
config=types.GenerateContentConfig(
max_output_tokens=500,
),
),
),
types.BatchRequest(
custom_id="req-002",
request=types.GenerateContentRequest(
contents="Traduis en anglais : ...",
),
),
# ... jusqu'a des milliers de requetes
],
)
print(f"Batch ID: {batch_job.name}")
print(f"Status: {batch_job.state}") # PENDING
Monitorer et recuperer les resultats
import time
# Verifier le statut
while True:
batch = client.batches.get(name=batch_job.name)
print(f"Status: {batch.state}")
if batch.state == "JOB_STATE_SUCCEEDED":
break
elif batch.state == "JOB_STATE_FAILED":
print(f"Erreur: {batch.error}")
break
time.sleep(30) # Verifier toutes les 30s
# Recuperer les resultats
for result in client.batches.list_results(name=batch_job.name):
print(f"ID: {result.custom_id}")
print(f"Reponse: {result.response.text[:100]}...")
# Lister tous les batch jobs
for job in client.batches.list():
print(f"{job.name}: {job.state}")
N'utilisez pas : interactions utilisateur temps reel, chatbots, taches urgentes.
Le Batch API est un levier d'optimisation majeur. Si vous avez des taches qui peuvent attendre quelques heures, vous economisez 50% automatiquement. Je l'utilise systematiquement pour les evaluations de prompts, le processing de datasets d'entrainement, et les analyses de logs.
Safety Settings & Content Filtering
Objectifs
- Comprendre les 5 categories de contenus nocifs
- Configurer les seuils de filtrage
- Lire les safety ratings dans les reponses
- Connaitre les filtres non-configurables
Categories de contenus nocifs
Gemini classe les contenus en 5 categories de danger. Pour les modeles 2.5 et 3.x, le filtrage est desactive par defaut (BLOCK_NONE), vous donnant le controle total.
| Categorie | Constante | Description |
|---|---|---|
| Harcelement | HARM_CATEGORY_HARASSMENT | Intimidation, menaces, bullying |
| Discours haineux | HARM_CATEGORY_HATE_SPEECH | Discrimination, stereotypes nocifs |
| Sexuellement explicite | HARM_CATEGORY_SEXUALLY_EXPLICIT | Contenu sexuel explicite |
| Contenu dangereux | HARM_CATEGORY_DANGEROUS_CONTENT | Instructions pour se blesser ou blesser |
| Integrite civique | HARM_CATEGORY_CIVIC_INTEGRITY | Desinformation electorale, manipulation |
Seuils de blocage
| Seuil | Comportement |
|---|---|
| BLOCK_NONE | Aucun blocage (defaut pour 2.5+) |
| BLOCK_ONLY_HIGH | Bloque uniquement les contenus a haute probabilite |
| BLOCK_MEDIUM_AND_ABOVE | Bloque medium et high |
| BLOCK_LOW_AND_ABOVE | Bloque tout sauf negligeable (le plus restrictif) |
Configuration des Safety Settings
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE")
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Explique les risques de cybersecurite",
config=types.GenerateContentConfig(
safety_settings=[
types.SafetySetting(
category="HARM_CATEGORY_DANGEROUS_CONTENT",
threshold="BLOCK_MEDIUM_AND_ABOVE",
),
types.SafetySetting(
category="HARM_CATEGORY_HARASSMENT",
threshold="BLOCK_ONLY_HIGH",
),
# Les categories non specifiees restent a BLOCK_NONE
],
),
)
Lire les Safety Ratings
# Verifier les ratings de la reponse
for candidate in response.candidates:
if candidate.safety_ratings:
for rating in candidate.safety_ratings:
print(f"Categorie: {rating.category}")
print(f"Probabilite: {rating.probability}")
print(f"Bloque: {rating.blocked}")
# Verifier si la reponse a ete bloquee
if candidate.finish_reason == "SAFETY":
print("ATTENTION: Reponse bloquee par les filtres de securite")
print(f"Raison: {candidate.safety_ratings}")
Fine-Tuning dans Google AI Studio
Objectifs
- Comprendre quand le fine-tuning est pertinent
- Preparer un dataset au format JSONL
- Lancer un job de fine-tuning via l'API
- Evaluer et utiliser le modele ajuste
Quand faire du Fine-Tuning ?
Le fine-tuning (Supervised Fine-Tuning / SFT) consiste a re-entrainer un modele de base sur vos propres donnees pour l'adapter a un style, un format ou un domaine specifique. C'est un outil puissant, mais pas toujours necessaire.
| Approche | Quand l'utiliser | Cout |
|---|---|---|
| Prompt Engineering | La plupart des cas, premier reflexe | Gratuit |
| Few-Shot Examples | Format specifique, style particulier | Tokens input |
| Context Caching | Grande base de connaissances fixe | Cache storage |
| RAG | Connaissances dynamiques, references | Embeddings + DB |
| Fine-Tuning | Style tres specifique, domaine pointu, haute perf requise | Training + hosting |
Preparer les donnees d'entrainement
{"text_input": "Quel est le statut de la commande #12345 ?", "output": "Commande #12345 : En cours de livraison. Estimation : 2 jours ouvrables. Transporteur : Colissimo."}
{"text_input": "Je veux retourner mon produit", "output": "Procedure de retour initiee. Vous recevrez un email avec l'etiquette de retour sous 24h. Remboursement sous 5-7 jours apres reception."}
{"text_input": "Probleme avec ma facture de janvier", "output": "J'ai identifie une anomalie sur votre facture de janvier. Montant corrige : 45.90 EUR. Un avoir sera emis sous 48h."}
{"text_input": "Changer mon adresse de livraison", "output": "Adresse mise a jour avec succes. Prochaine livraison a la nouvelle adresse. Confirmation envoyee par email."}
Recommande : 100-500 exemples pour des resultats robustes.
Optimal : 500-1000 exemples diversifies et de haute qualite.
Lancer le Fine-Tuning via l'API
from google import genai
from google.genai import types
client = genai.Client(api_key="VOTRE_CLE")
# Preparer les exemples d'entrainement
training_data = [
types.TuningExample(
text_input="Quel est le statut de la commande #12345 ?",
output="Commande #12345 : En cours de livraison..."
),
types.TuningExample(
text_input="Je veux retourner mon produit",
output="Procedure de retour initiee..."
),
# ... au moins 20 exemples
]
# Creer le job de tuning
tuning_job = client.tunings.create(
base_model="models/gemini-2.5-flash-001-tuning",
training_dataset=types.TuningDataset(
examples=types.TuningExamples(
examples=training_data
)
),
config=types.CreateTuningJobConfig(
epoch_count=5,
learning_rate=0.001,
tuned_model_display_name="support-client-v1",
),
)
print(f"Job: {tuning_job.name}")
print(f"Status: {tuning_job.state}")
Utiliser le modele fine-tune
# Une fois le tuning termine
response = client.models.generate_content(
model=tuning_job.tuned_model.model, # ex: tunedModels/support-client-v1-xxxxx
contents="Le client veut modifier sa commande",
)
print(response.text)
# Lister vos modeles fine-tunes
for model in client.tunings.list():
print(f"{model.tuned_model.model}: {model.state}")
En 30 ans d'experience, j'ai vu beaucoup de gens se precipiter sur le fine-tuning alors que du bon prompt engineering suffisait. Ma regle : essayez d'abord le prompt engineering + few-shot, puis le RAG, et ne fine-tunez que si ces approches ne donnent pas les resultats souhaites. Le fine-tuning coute en temps, en donnees et en maintenance.
Lab : Application voix interactive
Objectifs
- Construire une application voix complete avec Live API
- Implementer le streaming audio bidirectionnel
- Ajouter function calling et grounding en temps reel
- Gerer les evenements de session et les erreurs
Projet : Assistant Vocal avec Outils
Construisez un assistant vocal interactif qui repond en voix, peut chercher sur Google, et executer des fonctions custom.
Etape 1 : Setup et dependances
# Installation des dependances pip install google-genai pyaudio numpy # Structure du projet voice_assistant/ βββ main.py # Point d'entree βββ audio_handler.py # Capture/lecture audio βββ tools.py # Outils custom βββ .env # GOOGLE_API_KEY=...
Etape 2 : Definir les outils
from google.genai import types
import datetime
# Outil meteo (simule)
get_weather_decl = types.FunctionDeclaration(
name="get_weather",
description="Obtient la meteo actuelle d'une ville",
parameters=types.Schema(
type="OBJECT",
properties={
"city": types.Schema(type="STRING", description="Nom de la ville"),
},
required=["city"],
),
)
# Outil heure
get_time_decl = types.FunctionDeclaration(
name="get_current_time",
description="Retourne l'heure actuelle",
parameters=types.Schema(type="OBJECT", properties={}),
)
def handle_function_call(name, args):
"""Execute la fonction appelee par le modele."""
if name == "get_weather":
city = args.get("city", "Paris")
return {"temperature": 15, "condition": "nuageux", "city": city}
elif name == "get_current_time":
return {"time": datetime.datetime.now().strftime("%H:%M")}
Etape 3 : Configurer la connexion Live API
from google import genai
from google.genai import types
from tools import get_weather_decl, get_time_decl, handle_function_call
client = genai.Client(api_key="VOTRE_CLE")
# Configuration avec outils et voix
live_config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Kore" # Voix feminine claire
)
)
),
tools=[
types.Tool(function_declarations=[get_weather_decl, get_time_decl]),
types.Tool(google_search_retrieval=types.GoogleSearchRetrieval()),
],
)
Etape 4 : Boucle principale audio
import asyncio
import pyaudio
import numpy as np
CHUNK = 4096
FORMAT = pyaudio.paInt16
RATE = 16000
async def voice_assistant():
p = pyaudio.PyAudio()
# Stream d'entree (microphone)
input_stream = p.open(format=FORMAT, channels=1, rate=RATE,
input=True, frames_per_buffer=CHUNK)
# Stream de sortie (haut-parleur)
output_stream = p.open(format=FORMAT, channels=1, rate=24000,
output=True, frames_per_buffer=CHUNK)
async with client.aio.live.connect(
model="gemini-2.5-flash",
config=live_config
) as session:
print("Assistant vocal pret ! Parlez...")
async def send_audio():
"""Envoie l'audio du micro en continu."""
while True:
data = input_stream.read(CHUNK, exception_on_overflow=False)
await session.send_realtime_input(
media=types.Blob(
data=data,
mime_type="audio/pcm;rate=16000"
)
)
await asyncio.sleep(0.01)
async def receive_responses():
"""Recoit et joue les reponses."""
async for msg in session.receive():
# Audio du modele
if msg.data:
output_stream.write(msg.data)
# Function call
if msg.tool_call:
for fc in msg.tool_call.function_calls:
result = handle_function_call(fc.name, fc.args)
await session.send_tool_response(
function_responses=[
types.FunctionResponse(
name=fc.name,
response=result,
)
]
)
# Executer envoi et reception en parallele
await asyncio.gather(send_audio(), receive_responses())
asyncio.run(voice_assistant())
Etape 5 : Gestion des erreurs et reconnexion
async def resilient_assistant():
"""Assistant avec reconnexion automatique."""
max_retries = 3
for attempt in range(max_retries):
try:
await voice_assistant()
except Exception as e:
print(f"Erreur (tentative {attempt+1}): {e}")
if "session expired" in str(e).lower():
print("Session expiree (15 min max). Reconnexion...")
elif attempt < max_retries - 1:
await asyncio.sleep(2 ** attempt) # Backoff
else:
print("Echec apres 3 tentatives.")
raise
asyncio.run(resilient_assistant())
Etape 6 : Tester l'application
# Lancer l'assistant python main.py # Tests a effectuer : # 1. "Bonjour" -> Reponse vocale # 2. "Quel temps fait-il a Lyon ?" -> Function call meteo # 3. "Quelle heure est-il ?" -> Function call heure # 4. "Quelles sont les dernieres nouvelles en France ?" -> Google Search # 5. Attendre 15 min -> Test reconnexion automatique
Examen Final Phase 2
Objectifs
- Valider les connaissances des Modules 2.1, 2.2 et 2.3
- Couvrir function calling, agents, ADK, Live API et plus
- Obtenir la certification Phase 2
Examen Final - Outils Avances & Agents (10 questions)
1. Quels sont les 3 modes de function calling dans Gemini ?
2. Quel outil fournit un sandbox Python dans Gemini ?
3. Quel est le cout du Google Search Grounding par API ?
4. A quoi sert le framework ADK de Google ?
5. Quel protocole standardise l'integration d'outils pour les agents ?
6. Quel est le protocole de transport de la Live API ?
7. Quelle technique permet de choisir la dimension des embeddings apres entrainement ?
8. Quelle reduction de cout offre le Batch API ?
9. Combien de categories de contenus nocifs existent dans les Safety Settings ?
10. Quel est le nombre minimum d'exemples pour le fine-tuning ?
Felicitations si vous avez obtenu plus de 70% ! Vous maitrisez maintenant les outils avances de Gemini : function calling, agents ADK, Live API, embeddings, batch processing et safety. La Phase 3 vous attend pour construire des architectures RAG et des systemes distribues.