Cours
Gemini 3 Pro est le modèle d’IA de pointe que nous attendions tous, doté d’une fenêtre de contexte d’un million de tokens qui gère sans effort jeux de données, documents, vidéos et bases de code en un seul passage. Il offre un raisonnement de niveau doctorat et excelle dans le traitement multimodal du texte, des images, de l’audio et de la vidéo pour des workflows créatifs fluides.
Dans ce tutoriel basé sur un projet, je vous montre comment utiliser l’API Gemini 3 pour créer des applications multi‑agents capables d’ingérer un fichier CSV fourni par l’utilisateur et de réaliser des analyses de données avancées.
En bref, l’application multi‑agents effectuera :
- Analyses rapides : explorer rapidement la structure et les bases du jeu de données.
- Génération de code : utiliser Gemini 3 Pro pour produire du code d’analyse avancée avec visualisations.
- Exécution sécurisée : exécuter le code dans un environnement isolé et sauvegarder les résultats.
- Raisonnement intelligent : analyser et interpréter les résultats pour en extraire des insights clés.
- Compilation d’un rapport PDF : générer un PDF soigné avec visuels et explications claires, des insights compréhensibles en quelques secondes.
Si vous souhaitez approfondir la construction de workflows d’IA agentique, consultez notre guide sur Google Antigravity, le tutoriel Gemini 3 Flash, et le parcours de compétences AI Agent Fundamentals.
1. Configuration de l’environnement de l’API Gemini 3
1. Exécutez cette commande pour installer tous les packages requis pour notre application multi‑agents :
!pip install -q google-genai langgraph langsmith grandalf pydantic pandas matplotlib markdown2 weasyprint markdown-it-py mdit-py-plugins
Détail des packages :
- google-generativeai : accéder à Gemini 3 Pro via l’API officielle.
- langgraph : orchestrer des workflows d’IA multi‑agents en toute simplicité.
- langsmith : suivre les runs, monitorer les performances et déboguer via des tableaux de bord interactifs.
- grandalf : visualiser des graphes d’agents en diagrammes ASCII lisibles.
- pydantic : gérer les états partagés du graphe avec une validation robuste des données.
- pandas : explorer et analyser rapidement un jeu de données.
- matplotlib : générer des visualisations percutantes.
- markdown2 : convertir du Markdown en HTML pour un formatage de rapport riche.
- weasyprint : transformer HTML/CSS en rapports PDF professionnels.
- markdown-it-py : parseur Markdown avancé pour des formats complexes.
- mdit-py-plugins : étendre markdown-it-py avec des plugins (tables, notes de bas de page, etc.).
Remarque : nous utilisons Jupyter Notebook pour développer ce projet.
2. Rendez‑vous sur Google AI Studio et générez votre clé d’API. Assurez‑vous que la facturation est activée sur votre compte, car le modèle Gemini 3 Pro n’est pas disponible dans l’offre gratuite.
3. Créez ensuite un compte LangSmith gratuit et générez la clé d’API.
4. Enregistrez les deux clés d’API comme variables d’environnement sur votre système local. Définissez LANGSMITH_API_KEY et GEMINI_API_KEY.
5. Importez tous les packages Python nécessaires dans votre notebook :
from google import genai
from google.genai import types
from pydantic import BaseModel
from langgraph.graph import StateGraph, END
import os, json, textwrap, traceback
from pathlib import Path
import pandas as pd
import markdown2
import weasyprint
6. Définissez les variables d’environnement pour préciser le nom du projet LangSmith et activer le suivi LangSmith :
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = os.environ.get("LANGSMITH_API_KEY", "YOUR_LANGSMITH_KEY")
os.environ["LANGSMITH_PROJECT"] = os.environ.get("LANGSMITH_PROJECT", "autolab-gemini3pro")
7. Créez le dossier où seront enregistrées toutes les images et tous les PDF :
ARTIFACTS_DIR = Path("artifacts")
ARTIFACTS_DIR.mkdir(exist_ok=True)
2. Comment initialiser le client API Gemini 3
Dans cette section, nous allons configurer un client Gemini et encapsuler les appels au modèle afin qu’ils puissent être tracés et journalisés dans LangSmith. Nous extrairons également les métadonnées d’usage des tokens et les renverrons dans un format compatible LangSmith.
Commencez par initialiser le client Gemini GenAI en fournissant la clé d’API :
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
MODEL = "gemini-3-pro-preview"
Ensuite, nous écrivons un petit wrapper autour d’un appel au modèle Gemini pour activer le traçage automatique par LangSmith. En utilisant le décorateur @traceable, nous enregistrons la fonction comme un run LLM.
À l’intérieur de cette fonction, le code envoie le prompt à Gemini et extrait les détails d’usage des tokens, indispensables pour un suivi précis dans LangSmith, conformément aux recommandations de traçage.
Enfin, la fonction renvoie la sortie texte du modèle, les statistiques de tokens et la réponse brute dans le format attendu par LangSmith, garantissant un affichage fidèle dans l’interface.
from langsmith import traceable
@traceable(name="gemini_generate_content", run_type="llm")
def gemini_call(prompt: str, thinking_level: str = "high"):
"""
Gemini wrapper that:
- uses correct ThinkingConfig schema
- returns LangSmith LLM-run format so token usage shows in UI
"""
resp = client.models.generate_content(
model=MODEL,
contents=prompt,
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(thinking_level=thinking_level)
),
)
usage = getattr(resp, "usage_metadata", None)
token_usage = None
if usage:
token_usage = {
"prompt_tokens": usage.prompt_token_count,
"completion_tokens": usage.candidates_token_count,
"total_tokens": usage.total_token_count,
"thoughts_tokens": getattr(usage, "thoughts_token_count", None),
}
return {
"generations": [{"text": resp.text}],
"llm_output": {
"model_name": MODEL,
"token_usage": token_usage,
},
"raw_response": resp,
}
3. Créer des outils pour le workflow multi‑agents Gemini 3
Nous allons maintenant créer des outils dédiés à l’inspection du jeu de données, à l’exécution sécurisée de code Python et à la génération d’un rapport Markdown‑vers‑PDF, qui seront utilisés au sein d’un workflow d’agent IA.
Outil 1 : charger le jeu de données
Cet outil prend un chemin de fichier, lit le CSV dans un DataFrame pandas, puis construit un résumé contenant la forme du jeu de données, les noms de colonnes, le type de données de chaque colonne, le pourcentage de valeurs manquantes, les cinq premières lignes et les statistiques descriptives complètes. Il renvoie ce résumé afin qu’un agent comprenne rapidement le dataset.
def load_dataset(path: str):
df = pd.read_csv(path)
summary = {
"shape": df.shape,
"columns": list(df.columns),
"dtypes": {c: str(t) for c, t in df.dtypes.items()},
"missing_pct": df.isna().mean().to_dict(),
"head": df.head(5).to_dict(orient="records"),
"describe": df.describe(include="all").fillna("").to_dict()
}
return summary
Outil 2 : exécuter du code Python en sécurité (bac à sable simple)
Cet outil exécute en toute sécurité du code Python généré dynamiquement dans un environnement restreint. Il prépare un petit environnement local, puis exécute le code fourni avec exec.
Le code exécuté doit renvoyer les chemins d’artefacts (comme les graphiques enregistrés) et des métadonnées.
def run_python(code: str):
"""
Generated code MUST:
- save plots to ARTIFACTS_DIR
- collect paths in _artifacts (list[str])
- collect meta in _charts_meta (list[dict])
- optionally set _stdout (string)
"""
local_env = {"ARTIFACTS_DIR": ARTIFACTS_DIR}
try:
exec(textwrap.dedent(code), {}, local_env)
return {
"ok": True,
"stdout": local_env.get("_stdout", ""),
"artifacts": local_env.get("_artifacts", []),
"charts_meta": local_env.get("_charts_meta", []),
}
except Exception:
return {"ok": False, "traceback": traceback.format_exc()}
Outil 3 : générer un PDF à partir de Markdown
Cet outil convertit du Markdown en un PDF soigneusement mis en forme. Il commence par construire un parseur Markdown prenant en charge les tableaux, listes, checklists et notes de bas de page.
Puis render_pdf convertit le texte Markdown en HTML, l’enveloppe dans un modèle CSS personnalisé (polices, style des tableaux, taille des images, etc.) et utilise WeasyPrint pour générer un fichier PDF.
Enfin, il enregistre le PDF dans le dossier des artefacts et renvoie le chemin.
from markdown_it import MarkdownIt
from mdit_py_plugins.tasklists import tasklists_plugin
from mdit_py_plugins.footnote import footnote_plugin
# Create a strong markdown parser once (supports tables, lists, etc.)
md = (
MarkdownIt("commonmark", {"breaks": True, "html": True})
.enable(["table", "strikethrough"])
.use(tasklists_plugin)
.use(footnote_plugin)
)
def render_pdf(markdown_text: str):
"""
Better Markdown -> HTML -> PDF:
- proper tables
- stable lists
- centered/small images
- clean page breaks
"""
html_body = md.render(markdown_text)
html_template = f"""
<html>
<head>
<meta charset="utf-8">
<style>
body {{
font-family: Arial, sans-serif;
font-size: 12px;
line-height: 1.5;
color: #111;
}}
h1 {{ font-size: 20px; margin-bottom: 6px; }}
h2 {{ font-size: 16px; margin-top: 18px; margin-bottom: 6px; }}
h3 {{ font-size: 13px; margin-top: 12px; margin-bottom: 4px; }}
p {{ margin: 6px 0; }}
ul, ol {{
margin: 6px 0 6px 18px;
}}
li {{ margin: 2px 0; }}
table {{
width: 100%;
border-collapse: collapse;
margin: 8px 0 12px 0;
font-size: 11px;
}}
th, td {{
border: 1px solid #ccc;
padding: 6px;
text-align: left;
}}
th {{ background: #f2f2f2; }}
img {{
display: block;
margin: 8px auto 8px auto;
max-width: 70%;
height: auto;
page-break-inside: avoid;
}}
.chart-block {{
page-break-inside: avoid;
margin-bottom: 12px;
}}
code {{
background: #f6f6f6;
padding: 2px 4px;
border-radius: 4px;
font-size: 11px;
}}
pre code {{
display: block;
padding: 8px;
overflow-x: auto;
}}
</style>
</head>
<body>
{html_body}
</body>
</html>
"""
pdf_path = ARTIFACTS_DIR / "report.pdf"
weasyprint.HTML(
string=html_template,
base_url=str(ARTIFACTS_DIR.parent.resolve())
).write_pdf(str(pdf_path))
return str(pdf_path)
Nous enregistrons simplement ces trois fonctions comme outils disponibles pour l’agent.
TOOLS = [load_dataset, run_python, render_pdf]
4. État partagé du graphe
Cette classe définit un objet state partagé qui contient tout ce que le workflow produit : chemin du dataset, informations de profilage, plan généré, code, résultats d’exécution, insights, rapport final, ainsi que des limites de relance et messages d’erreur pour éviter les boucles infinies.
class State(BaseModel):
dataset_path: str
profile: dict | None = None
plan: dict | None = None
code: str | None = None
exec_result: dict | None = None
charts_meta: list | None = None
insights: str | None = None
report_md: str | None = None
report_pdf: str | None = None
retry_count: int = 0 # NEW: stop infinite loops
last_error: str | None = None # NEW: pass traceback to coder
MAX_RETRIES = 2
5. Créer des agents API Gemini 3 pour l’analyse de données
Nous allons maintenant créer des agents IA qui vont collaborer pour profiler le dataset, écrire et exécuter le code d’analyse, générer des insights et produire un rapport PDF final.
Agent 1 : profilage des données et planification
Cet agent est chargé de comprendre le dataset et de créer un plan d’analyse structuré. Il commence par charger le dataset via l’outil load_dataset, qui renvoie un résumé incluant dimensions, valeurs manquantes, types de colonnes, statistiques descriptives et exemples de lignes.
Il envoie ensuite ce résumé au LLM avec des consignes très explicites : identifier le type de tâche, choisir une colonne cible si pertinent, décider des étapes d’exploration (EDA), proposer les graphiques à générer et esquisser d’éventuelles étapes de modélisation si le dataset s’y prête (classification ou régression).
Le LLM renvoie une structure JSON représentant ce plan, que l’agent parse, en conservant le texte brut si l’analyse JSON échoue.
Enfin, il enregistre le profil du dataset et le plan généré dans l’état partagé, afin que les agents suivants disposent de toutes les informations nécessaires.
@traceable(name="profiler_agent")
def profiler_agent(state: State):
profile = load_dataset(state.dataset_path)
prompt = f"""
You are the Data Profiler Agent.
Produce a JSON analysis plan with:
- task_type: "classification"|"regression"|"eda_only"
- target_column (if any)
- eda_steps (list)
- charts_to_make (list) # 5-10 max, most informative
- baseline_model_steps (list if modeling)
- risks_or_data_issues (list)
Dataset profile:
{json.dumps(profile, indent=2)}
"""
resp = gemini_call(prompt, thinking_level="high")
text = resp["generations"][0]["text"]
try:
plan = json.loads(text)
except:
plan = {"raw_plan": text}
state.profile = profile
state.plan = plan
return state
Agent 2 : génération de code
Cet agent convertit le plan d’analyse en code Python exécutable. Il reçoit le profil du dataset, le plan et toute erreur d’exécution précédente. En s’appuyant sur ce contexte, il demande au LLM de produire uniquement du code Python.
Le prompt inclut des exigences strictes : charger le dataset, suivre le plan à la lettre, générer chaque graphique demandé, enregistrer les figures dans ARTIFACTS_DIR, tracer les chemins et métadonnées, capturer la sortie console, fermer les figures après enregistrement et, si besoin, calculer des métriques de modélisation.
Cela garantit un code reproductible et sûr dans le bac à sable. Le résultat est stocké dans state.code, prêt à être exécuté.
@traceable(name="code_writer_agent")
def code_writer_agent(state: State):
prompt = f"""
You are the Code Writer Agent.
Write Python code ONLY (no markdown).
Previous error to fix (if any):
{state.last_error}
HARD REQUIREMENTS:
1. Load dataset from: {state.dataset_path}
2. Follow the plan exactly.
3. Create ALL charts in charts_to_make.
4. Save every chart in ARTIFACTS_DIR with filenames like:
ARTIFACTS_DIR / "chart_01_<short_name>.png"
5. Track saved plot paths in _artifacts (list[str]).
6. Track chart metadata in _charts_meta (list[dict]) with:
{{
"title": "<human readable chart title>",
"filename": "artifacts/chart_01_x.png",
"description": "<what this plot shows (1-2 sentences)>",
"one_liner": "<ONE line insight from the chart>"
}}
The one_liner MUST be a single sentence, max ~20 words.
7. Store useful console output in _stdout.
IMPORTANT:
- import matplotlib.pyplot as plt
- plt.close() after saving each plot
- ensure _artifacts and _charts_meta exist even if empty
- if modeling, add baseline metrics to _stdout
Dataset profile:
{json.dumps(state.profile, indent=2)}
Analysis plan:
{json.dumps(state.plan, indent=2)}
Return ONLY executable python code.
"""
resp = gemini_call(prompt, thinking_level="high")
state.code = resp["generations"][0]["text"]
return state
Agent 3 : exécution (avec relance automatique)
Cet agent exécute le code Python produit par le générateur de code à l’aide du bac à sable run_python. Il capture les résultats d’exécution, les métadonnées des graphiques, la sortie standard et tous les artefacts créés.
Si le code s’exécute avec succès, les résultats sont sauvegardés et le workflow poursuit son cours. En cas d’échec, l’agent incrémente le compteur de relance et stocke la trace d’erreur, afin que l’agent de génération de code puisse corriger au prochain passage.
Avec MAX_RETRIES pour limiter la boucle, cet agent évite les cycles infinis et fournit les signaux nécessaires à l’auto‑correction.
@traceable(name="executor_agent")
def executor_agent(state: State):
result = run_python(state.code)
state.exec_result = result
state.charts_meta = result.get("charts_meta", [])
if not result["ok"]:
state.retry_count += 1
state.last_error = result.get("traceback", "Unknown error")
return state
Agent 4 : rédaction des insights
Cet agent interprète l’ensemble de l’analyse. Il prend le profil du dataset, la sortie d’exécution et les métadonnées des graphiques, puis produit des insights analytiques lisibles par tous.
Il demande au LLM de générer des insights structurés : pour chaque graphique, deux enseignements et un risque, puis un ensemble limité d’insights globaux.
L’agent doit s’assurer qu’il n’y a pas de puces vides, pas de répétitions, et que les insights sont spécifiques au dataset, pas génériques.
Le rapport d’insights résultant est stocké dans state.insights, et servira à l’étape finale de reporting.
@traceable(name="insights_agent")
def insights_agent(state: State):
prompt = f"""
You are the Insights Agent.
HARD REQUIREMENTS:
- No empty bullets.
- No repeated bullets.
- Be specific to this dataset and these charts.
- Output format:
### Chart Insights
For each chart in charts_meta:
- **<title>**
- Takeaway 1 (one sentence)
- Takeaway 2 (one sentence)
- Caveat/Risk (one sentence)
### Overall Insights
- 3-5 bullets max, each one sentence.
Inputs:
Profile:
{json.dumps(state.profile, indent=2)}
Execution result:
{json.dumps(state.exec_result, indent=2)}
Charts meta:
{json.dumps(state.charts_meta, indent=2)}
"""
resp = gemini_call(prompt, thinking_level="high")
state.insights = resp["generations"][0]["text"]
return state
Agent 5 : création du rapport → PDF
C’est l’agent de synthèse finale. Il exploite toutes les sorties de la chaîne : profil, insights, métadonnées des graphiques, journaux d’exécution, et compose un rapport Markdown clair et complet.
Le prompt impose des règles de formatage strictes : pas de titres répétés, espacement cohérent, chaque graphique affiché une seule fois dans un bloc HTML standardisé, et intégration propre des insights.
Une fois le Markdown produit, l’agent appelle render_pdf pour le convertir en un PDF soigné avec WeasyPrint. Le Markdown et le chemin du PDF sont stockés dans l’état partagé, ce qui clôt l’analyse.
@traceable(name="report_agent")
def report_agent(state: State):
prompt = f"""
You are the Report Agent.
Create a neat Markdown report (HTML allowed).
HARD REQUIREMENTS:
- Do NOT repeat section titles or chart titles.
- Do NOT output empty bullet points. If a bullet would be empty, skip it.
- Keep spacing consistent: one blank line between sections.
- Use charts_meta as the ONLY source of charts.
- Include EVERY chart, exactly once, in the same order as charts_meta.
- For each chart output EXACTLY this block:
<div class="chart-block">
<h3>Chart {{i}}: {{title}}</h3>
<img src="{{filename}}" alt="{{title}}">
<p><b>What it shows:</b> {{one_liner}}</p>
</div>
Where:
- title, filename, one_liner come from charts_meta
- one_liner must be ONE sentence, max ~20 words.
Sections:
1. Dataset Overview (short)
2. Data Quality Notes (bullets)
3. Exploratory Analysis (chart-by-chart blocks only, no extra chart titles)
4. Modeling Results (if any; use a markdown table)
5. Key Insights (use insights text)
6. Recommendations / Next Steps (bullets)
Inputs:
Profile: {json.dumps(state.profile, indent=2)}
Exec stdout: {state.exec_result.get("stdout","")}
Exec ok: {state.exec_result.get("ok")}
Traceback (if any): {state.exec_result.get("traceback","")}
Charts meta:
{json.dumps(state.charts_meta, indent=2)}
Insights:
{state.insights}
Return ONLY the Markdown report.
"""
resp = gemini_call(prompt, thinking_level="low")
state.report_md = resp["generations"][0]["text"]
state.report_pdf = render_pdf(state.report_md)
return state
6. Construire le graphe multi‑agents
Cette dernière étape consiste à assembler le workflow complet en un graphe piloté par l’état, réunissant tous les agents.
Un StateGraph est créé à l’aide d’un modèle d’état partagé, garantissant que chaque agent interagit avec le même objet d’état qui évolue au fil du workflow. Chaque composant—profiler, générateur de code, exécuteur, rédacteur d’insights et créateur de rapport—est ajouté au graphe en tant que nœud distinct représentant une étape précise du pipeline.
Le workflow commence toujours par l’agent de profilage, défini comme point d’entrée. Ainsi, le processus débute par une compréhension solide du dataset et la génération d’un plan d’analyse.
Des arêtes définissent l’enchaînement du processus. Après le profilage, la sortie va vers le générateur de code, puis vers l’exécuteur. La logique clé réside dans le routage conditionnel depuis l’exécuteur.
Une fonction utilitaire, retry_or_continue, examine le résultat d’exécution. Si le code réussit, le workflow passe à l’agent d’insights.
En cas d’échec avec des relances restantes, il reboucle vers le générateur de code pour correction automatique.
S’il n’y a plus de relances disponibles, il contourne l’analyse supplémentaire et passe directement au générateur de rapport, garantissant l’absence de boucle infinie. Les arêtes conditionnelles sont intégrées au nœud exécuteur afin que le workflow s’adapte selon la réussite ou l’échec de l’exécution.
Enfin, le graphe relie l’étape des insights à celle du rapport, puis la sortie du rapport à la fin du workflow. Le graphe est compilé en une structure exécutable et un diagramme ASCII est généré pour visualiser le flux.
Ce graphe multi‑agents orchestre tout le pipeline d’analyse adaptatif, permettant la récupération sur erreur, la coordination pas à pas et des transitions fluides entre agents.
g = StateGraph(State)
g.add_node("profiler", profiler_agent)
g.add_node("code_writer", code_writer_agent)
g.add_node("executor", executor_agent)
g.add_node("insights", insights_agent)
g.add_node("report", report_agent)
g.set_entry_point("profiler")
g.add_edge("profiler", "code_writer")
g.add_edge("code_writer", "executor")
def retry_or_continue(state: State):
# success path
if state.exec_result and state.exec_result.get("ok"):
return "insights"
# stop retrying after MAX_RETRIES
if state.retry_count >= MAX_RETRIES:
return "report"
return "code_writer"
g.add_conditional_edges(
"executor",
retry_or_continue,
{"code_writer": "code_writer", "insights": "insights", "report": "report"}
)
g.add_edge("insights", "report")
g.add_edge("report", END)
graph = g.compile()
print(graph.get_graph().draw_ascii())
+-----------+
| __start__ |
+-----------+
*
*
*
+----------+
| profiler |
+----------+
*
*
*
+-------------+
| code_writer |
+-------------+
.
.
.
+----------+
| executor |
+----------+
.. ..
.. ..
. ..
+----------+ .
| insights | ..
+----------+ ..
** ..
** ..
* .
+--------+
| report |
+--------+
*
*
*
+---------+
| __end__ |
+---------+
7. Exécuter l’ensemble du pipeline d’analyse avec l’API Gemini 3
Pour exécuter le pipeline complet, fournissez simplement le chemin du dataset, créez un objet State initial et invoquez le graphe compilé. Dans notre cas, nous utilisons le dataset Boston Housing.
DATASET_PATH = "/work/housing.csv" # <-- change this
state = State(dataset_path=DATASET_PATH)
out = graph.invoke(state)
Une fois invoqué, le système multi‑agents réalise automatiquement l’analyse complète : profilage du dataset, génération d’un plan, écriture et exécution du code Python, extraction des insights, et production d’un rapport Markdown et d’un PDF.
--- Modeling Baseline Results ---
Dataset Shape: (489, 4)
Linear Regression -> RMSE: 82,395.54, R2: 0.6911
Random Forest -> RMSE: 56,931.38, R2: 0.8525
Observations: Random Forest typically outperforms Linear Regression due to capturing non-linear relationships (e.g., LSTAT).
À la fin de l’exécution, ouvrez votre tableau de bord LangSmith et accédez au projet « autolab-gemini3pro ». Chaque run d’agent y apparaît.

En cliquant sur l’exécution récente et en passant à la vue Waterfall, vous visualisez la chronologie de chaque étape : durée d’exécution des agents et outils utilisés.

Vous pouvez ouvrir n’importe quel agent pour inspecter :
- Le prompt reçu
- La génération exacte du modèle
- Les détails d’exécution des outils
- Les artefacts, graphiques et traces renvoyés

LangSmith a été déterminant pour améliorer l’ensemble du workflow. Ce que vous voyez est la version finale, mais il a fallu de nombreux essais pour aboutir, et LangSmith m’a aidé à déboguer les agents.
8. Afficher le Markdown et le PDF du rapport
Une fois le workflow multi‑agents terminé, vous pouvez inspecter directement le rapport Markdown généré dans votre notebook.
La version Markdown est pratique pour relire rapidement l’analyse, parcourir les insights et vérifier la structure du rapport sans quitter votre environnement de travail.
print(out["report_md"][:2000])
# Housing Price Analysis Report
## 1. Dataset Overview
The dataset consists of **489 records** and **4 features** focusing on housing metrics. The target variable is `MEDV` (Median Value of owner-occupied homes). The features include `RM` (average number of rooms), `LSTAT.............
En plus du Markdown, le workflow produit aussi un PDF soigné. Le PDF est automatiquement enregistré dans le dossier des artefacts, et vous pouvez afficher son chemin ainsi :
print("PDF saved at:", out["report_pdf"])
PDF saved at: artifacts/report.pdf
Le PDF généré est impeccable et contient tous les éléments clés de l’analyse : explications, graphiques rendus, interprétations, synthèse de modélisation et recommandations finales.
Idéal pour le partage avec vos équipes, managers ou clients, notamment quand vous avez besoin d’une version prête à présenter des résultats.

Conclusion
Ce projet montre à quel point les modèles d’IA modernes et les workflows d’agents basés sur des graphes ont progressé. Il n’y a pas si longtemps, construire un seul agent avec plusieurs outils demandait des jours d’ajustements, de débogage et de gestion de comportements imprévisibles.
Aujourd’hui, avec des modèles comme Gemini 3 Pro, le système comprend le dataset, génère un code fiable, exécute les analyses, interprète les visualisations et assemble un rapport soigné avec une fiabilité remarquable.
Dans ce projet, nous avons construit une application d’analyse de données multi‑agents complète, capable d’ingérer n’importe quel CSV, de réaliser une EDA de bout en bout, d’exécuter des modèles de base, de générer des insights et de produire un rapport PDF entièrement formaté.
Ce projet s’appuie sur cinq agents coordonnés : profilage & planification, génération de code, exécution avec relances, génération d’insights et reporting, ainsi que trois outils essentiels pour le chargement du dataset, l’exécution sécurisée du code et le rendu Markdown‑vers‑PDF.
À la clé : un flux d’analyse propre et automatisé qui produit un rapport professionnel, narratif et étayé par des visualisations.
FAQ sur l’API Gemini 3
Quelle est la taille de la fenêtre de contexte de l’API Gemini 3 ?
L’API Gemini 3 prend en charge une fenêtre de contexte allant jusqu’à environ un million de tokens, ce qui lui permet de traiter de gros jeux de données, des documents longs ou des bases de code complètes en un seul appel. Le suivi de l’usage des tokens reste recommandé pour maîtriser les coûts et éviter la troncature.
Comment le paramètre thinking_level impacte‑t‑il les performances de l’API Gemini 3 ?
Le paramètre thinking_level contrôle la profondeur de raisonnement par rapport à la vitesse et au coût dans l’API Gemini 3. Le régler sur high déclenche un raisonnement plus approfondi (idéal pour les workflows complexes), tandis que low privilégie des réponses plus rapides et une consommation de tokens plus faible.
Quels sont les détails de tarification et de limites de requêtes de l’API Gemini 3 ?
Gemini 3 Pro utilise une tarification basée sur les tokens : vous payez pour les tokens d’entrée et de sortie. Des prompts plus volumineux ou des entrées multimodales augmentent le nombre de tokens et donc le coût. Les limites de débit varient selon le palier de compte ; en production, il est essentiel de suivre l’usage et de configurer des alertes.
Quels formats d’entrée sont pris en charge par l’API Gemini 3 ?
L’API Gemini 3 prend en charge plusieurs formats d’entrée—texte, images, audio et vidéo—pour un véritable raisonnement multimodal. Vous pouvez mélanger les formats (par exemple, un dataset plus l’image d’un graphique), mais les entrées non textuelles consomment généralement plus de tokens ; anticipez‑le dans votre budget.
Quelles sont les principales limites de l’API Gemini 3 et comment les gérer ?
Bien que très performante, l’API Gemini 3 présente des limites pratiques : de grands contextes peuvent augmenter la latence et le coût, et les sorties du modèle peuvent nécessiter une validation humaine. N’envoyez pas de données sensibles sans contrôles de conformité, et isolez le code ou les analyses générés dans un bac à sable avant déploiement.
En tant que data scientist certifié, je suis passionné par l'utilisation des technologies de pointe pour créer des applications innovantes d'apprentissage automatique. Avec une solide expérience en reconnaissance vocale, en analyse de données et en reporting, en MLOps, en IA conversationnelle et en NLP, j'ai affiné mes compétences dans le développement de systèmes intelligents qui peuvent avoir un impact réel. En plus de mon expertise technique, je suis également un communicateur compétent, doué pour distiller des concepts complexes dans un langage clair et concis. En conséquence, je suis devenu un blogueur recherché dans le domaine de la science des données, partageant mes idées et mes expériences avec une communauté grandissante de professionnels des données. Actuellement, je me concentre sur la création et l'édition de contenu, en travaillant avec de grands modèles linguistiques pour développer un contenu puissant et attrayant qui peut aider les entreprises et les particuliers à tirer le meilleur parti de leurs données.
