0Pricing
AI Engineering Academy · Leçon

Créer un agent d’analyse de données

Créez un agent d’analyse de données de bout en bout qui accepte un fichier CSV et une question en langage naturel, écrit itérativement du code pandas et matplotlib, puis produit un rapport soigné.

Créer un agent d’analyse de données est une leçon AI Engineering Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Engineering Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Engineering Academy comprend 4 leçons au total.

Vision de l’agent d’analyse de données

Un agent d’analyse de données accepte un fichier CSV et une question en langage naturel, puis explore et nettoie les données de manière autonome, calcule des statistiques, génère des visualisations et produit un rapport soigné, le tout grâce à la génération et à l’exécution itératives de code. Il s’agit de l’une des applications les plus concrètes des agents de code : elle reproduit directement le flux de travail d’un analyste de données, sans l’effort humain.

Architecture globale de l’agent

L’agent d’analyse de données comporte quatre phases conceptuelles : Exploration (comprendre la forme, les types et la qualité des données), Nettoyage (gérer les valeurs manquantes, les valeurs aberrantes et les conversions de type), Analyse (calculer les indicateurs et statistiques qui répondent à la question) et Rapport (générer des graphiques et résumer les résultats en prose). Chaque phase correspond à 1 à 5 itérations d’exécution du code.

DATA_AGENT_SYSTEM_PROMPT = '''
You are a data analysis agent. Given a CSV file and a question, answer it through iterative Python code.

Phases to follow:
1. EXPLORE: Load the data, print shape, dtypes, head(), describe(), and check for nulls.
2. CLEAN: Handle missing values, fix dtypes, remove outliers.
3. ANALYZE: Compute statistics, groupbys, correlations - whatever answers the question.
4. REPORT: Generate a matplotlib chart saved to /workspace/chart.png and write a text summary.

Rules:
- Write code in ```python ... ``` blocks.
- Save intermediate results to /workspace/ for use in later steps.
- Print key findings after each computation so you can observe them.
- When all phases are done, say TASK COMPLETE and summarize the answer.
'''

Phase 1 : code d’exploration des données

La phase d’exploration charge les données et affiche immédiatement toutes les informations nécessaires à la planification de l’analyse : dimensions, noms et types des colonnes, lignes d’exemple, statistiques récapitulatives et nombre de valeurs nulles. Le LLM lit cette sortie et s’en sert pour prendre des décisions éclairées concernant le nettoyage et l’analyse lors des itérations suivantes.

import pandas as pd
import numpy as np

# Load dataset
df = pd.read_csv('/workspace/data.csv')

# Basic exploration
print('=== SHAPE ===' )
print(df.shape)

print('\n=== DTYPES ===')
print(df.dtypes)

print('\n=== HEAD ===')
print(df.head())

print('\n=== DESCRIBE ===')
print(df.describe(include='all'))

print('\n=== NULL COUNTS ===')
print(df.isnull().sum())

print('\n=== UNIQUE VALUES (categorical) ===')
for col in df.select_dtypes(include='object').columns:
    print(f'{col}: {df[col].nunique()} unique values: {df[col].unique()[:5]}')

# Save for next iteration
df.to_parquet('/workspace/raw.parquet')
print('\nData saved to workspace.')

Phase 2 : nettoyage des données

Après l’exploration, l’agent écrit du code de nettoyage ciblé en fonction de ce qu’il a observé. La stratégie de nettoyage est dynamique : si le LLM a constaté 15 % de valeurs nulles dans une colonne, il décide de les supprimer ou de les imputer. S’il a observé des valeurs négatives dans une colonne qui devrait être non négative, il les filtre. Ce nettoyage adaptatif fondé sur les observations rend l’agent réellement utile, au lieu de lui faire exécuter simplement un pipeline fixe.

import pandas as pd
import numpy as np

# Load from previous iteration
df = pd.read_parquet('/workspace/raw.parquet')

# Fill numeric nulls with median (robust to outliers)
for col in df.select_dtypes(include='number').columns:
    if df[col].isnull().sum() > 0:
        median_val = df[col].median()
        df[col] = df[col].fillna(median_val)
        print(f'Filled nulls in {col} with median {median_val:.2f}')

# Drop rows where categorical key columns are null
df = df.dropna(subset=['category', 'date'])

# Fix date column type
df['date'] = pd.to_datetime(df['date'], errors='coerce')
df = df.dropna(subset=['date'])  # drop unparseable dates

# Remove clear outliers: revenue > 3 std deviations from mean
if 'revenue' in df.columns:
    z_scores = (df['revenue'] - df['revenue'].mean()) / df['revenue'].std()
    df = df[z_scores.abs() < 3]
    print(f'Removed outliers, rows remaining: {len(df)}')

df.to_parquet('/workspace/cleaned.parquet')
print('Cleaning complete:', df.shape)

Phase 3 : répondre à la question

Lors de la phase d’analyse, l’agent se concentre sur le calcul de la réponse précise à la question de l’utilisateur. Si la question est « quelle catégorie de produits a généré le chiffre d’affaires le plus élevé au dernier trimestre ? », l’agent écrit du code pour filtrer par date, regrouper par catégorie, additionner le chiffre d’affaires et trier les résultats. Le code d’analyse est généré spécifiquement à partir de la question et de ce que l’agent a observé durant l’exploration : il ne s’agit pas d’un modèle générique.

import pandas as pd
import matplotlib
matplotlib.use('Agg')  # non-interactive backend for server use
import matplotlib.pyplot as plt

df = pd.read_parquet('/workspace/cleaned.parquet')

# Analysis: revenue by category for last quarter
df['date'] = pd.to_datetime(df['date'])
last_quarter = df[df['date'] >= '2024-10-01']

revenue_by_category = (
    last_quarter
    .groupby('category')['revenue']
    .sum()
    .sort_values(ascending=False)
)
print('Revenue by category (last quarter):')
print(revenue_by_category)
print(f'\nTop category: {revenue_by_category.index[0]} (${revenue_by_category.iloc[0]:,.0f})')

# Save analysis result
revenue_by_category.to_json('/workspace/analysis_result.json')

Phase 4 : générer des graphiques

Les visualisations rendent les résultats analytiques clairs et convaincants. L’agent d’analyse de données génère des graphiques matplotlib et les enregistre sous forme de fichiers PNG dans l’espace de travail. Les principales décisions de conception du graphique — type de graphique, palette de couleurs, étiquettes des axes, titre et annotations — sont prises par le LLM en fonction de la nature des données. L’agent enregistre toujours les graphiques dans /workspace/ afin de pouvoir les inclure dans le rapport final.

import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import json

with open('/workspace/analysis_result.json') as f:
    data = json.load(f)

categories = list(data.keys())
values = [data[k] / 1e6 for k in categories]  # convert to millions

fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.barh(categories, values, color='steelblue', edgecolor='white')

# Add value labels on bars
for bar, val in zip(bars, values):
    ax.text(bar.get_width() + 0.05, bar.get_y() + bar.get_height()/2,
            f'${val:.1f}M', va='center', fontsize=11)

ax.set_xlabel('Revenue ($ Millions)', fontsize=12)
ax.set_title('Revenue by Product Category - Q4 2024', fontsize=14, fontweight='bold')
ax.invert_yaxis()  # highest on top
plt.tight_layout()
plt.savefig('/workspace/chart.png', dpi=150, bbox_inches='tight')
print('Chart saved to /workspace/chart.png')

Générer le rapport écrit

L’itération finale produit le rapport récapitulatif écrit. Le LLM lit les résultats de l’analyse et la description du graphique, puis rédige un texte concis et exact qui répond à la question initiale avec des chiffres précis. Le rapport fait référence au graphique et présente l’idée clé, les données justificatives ainsi qu’une recommandation ou une implication pour l’entreprise.

import json

with open('/workspace/analysis_result.json') as f:
    revenue_data = json.load(f)

top_category = max(revenue_data, key=revenue_data.get)
top_revenue = revenue_data[top_category]
total_revenue = sum(revenue_data.values())
share = top_revenue / total_revenue * 100

report = f'''# Q4 2024 Revenue Analysis

## Answer
The **{top_category}** category generated the highest revenue in Q4 2024:
**${top_revenue:,.0f}** ({share:.1f}% of total Q4 revenue).

## Key Findings
- Total Q4 revenue: ${total_revenue:,.0f}
- Top 3 categories: {list(revenue_data.items())[:3]}
- The top category outperformed the average by {top_revenue / (total_revenue / len(revenue_data)):.1f}x

## Chart
See chart.png for the full breakdown by category.

## Recommendation
Consider reallocating marketing budget toward {top_category} to
capitalize on its demonstrated strong performance.
'''

with open('/workspace/report.md', 'w') as f:
    f.write(report)
print('TASK COMPLETE')
print(report)

Assembler l’orchestrateur de l’agent

L’orchestrateur relie toutes les phases : il initialise l’espace de travail, copie le CSV d’entrée, exécute la boucle d’exécution du code, surveille le signal TASK COMPLETE, puis collecte les fichiers de sortie (report.md, chart.png). Il gère également les erreurs, les nouvelles tentatives et le nettoyage final des fichiers intermédiaires.

import shutil
from pathlib import Path

def run_data_analysis_agent(csv_path: str, question: str) -> dict:
    workspace = setup_workspace()
    shutil.copy(csv_path, workspace / 'data.csv')
    
    messages = [
        {'role': 'system', 'content': DATA_AGENT_SYSTEM_PROMPT},
        {'role': 'user', 'content': f'File: /workspace/data.csv\nQuestion: {question}'}
    ]
    
    state = ExecutionState(task=question)
    
    for iteration in range(15):  # max 15 iterations
        response = llm.complete(messages)
        code = extract_code_block(response)
        
        if not code or 'TASK COMPLETE' in response:
            break
        
        stdout, stderr = execute_in_docker(code, workspace=workspace)
        observation = format_observation(stdout, stderr)
        messages += [
            {'role': 'assistant', 'content': response},
            {'role': 'user', 'content': observation}
        ]
        state.after_execution(stdout, f'iteration_{iteration}')
    
    return {
        'report': (workspace / 'report.md').read_text() if (workspace / 'report.md').exists() else '',
        'chart_path': str(workspace / 'chart.png'),
        'iterations': state.iteration
    }

Gérer les questions ambiguës

Les utilisateurs posent souvent des questions ambiguës comme « quels produits se portent bien ? ». Un agent d’analyse de données robuste clarifie l’ambiguïté avant de commencer : il explore d’abord les données, détermine quels indicateurs sont disponibles, puis déduit l’interprétation la plus pertinente ou demande des précisions à l’utilisateur. Cette étape de réflexion empêche l’agent de produire une réponse techniquement correcte mais inutile en pratique.

def handle_ambiguous_question(question: str, df_summary: dict) -> str:
    clarification_prompt = f'''The user asked: '{question}'

Available data:
- Columns: {df_summary['columns']}
- Date range: {df_summary['date_range']}
- Metrics available: {df_summary['numeric_columns']}

Is the question clear enough to answer definitively?
If yes, restate the specific interpretation you will use.
If no, list the 2-3 clarifications needed to proceed.'''
    
    response = llm.complete([{'role': 'user', 'content': clarification_prompt}])
    return response

Contrôles qualité de la sortie de l’agent

Une fois l’agent terminé, validez la qualité de sa sortie. Vérifiez que le fichier de rapport a bien été créé, que le PNG du graphique est un fichier image valide, que les nombres du rapport correspondent aux données de analysis_result.json et que le rapport répond effectivement à la question initiale. Une étape automatisée d’assurance qualité utilisant un deuxième appel à un LLM peut détecter les cas où l’agent est allé jusqu’au bout du processus, mais a produit une réponse médiocre.

def validate_analysis_output(workspace: str, question: str, report: str) -> dict:
    validation_prompt = f'''Original question: {question}

Agent report:
{report[:2000]}

Rate this analysis on a scale of 1-5 for:
1. Does it directly answer the question? (1=No, 5=Yes)
2. Are specific numbers cited? (1=No, 5=Yes)
3. Is the conclusion clearly stated? (1=No, 5=Yes)

Return JSON: {{"question_answered": N, "numbers_cited": N, "clear_conclusion": N, "overall": N}}'''
    
    result = llm.complete([{'role': 'user', 'content': validation_prompt}],
                          response_format={'type': 'json_object'})
    scores = json.loads(result)
    passed = scores['overall'] >= 4
    return {'scores': scores, 'passed': passed}

Étendre l’agent avec des outils spécialisés

L’agent de code de base devient encore plus puissant lorsqu’il est étendu avec des outils spécifiques au domaine. Pour un agent de données financières, ajoutez des fonctions qui récupèrent les cours boursiers en temps réel. Pour un agent de données marketing, ajoutez un accès à l’API Google Analytics. Pour un agent commercial, ajoutez des requêtes Salesforce. Ces outils sont mis à la disposition du LLM par des définitions de fonctions dans l’invite système ou au moyen du décorateur @tool de LangChain.

Vérification rapide

Testez votre compréhension de l’agent d’analyse de données présenté dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris qu’un agent d’analyse de données suit quatre phases — exploration, nettoyage, analyse et rapport — chacune étant mise en œuvre par une génération et une exécution itératives de code, que la génération de graphiques avec matplotlib et la persistance de l’état dans des fichiers relient ces phases pour former un processus cohérent, et que la validation de la sortie garantit que la réponse finale de l’agent répond effectivement à la question initiale. Dans la prochaine leçon, nous découvrirons l’observabilité et le traçage des LLM.

Questions Fréquemment Posées

La leçon « Créer un agent d’analyse de données » est-elle gratuite ?

Oui — le texte complet de « Créer un agent d’analyse de données » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Engineering Academy, passe à CoddyKit PRO. Le cours AI Engineering Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Créer un agent d’analyse de données » ?

Créez un agent d’analyse de données de bout en bout qui accepte un fichier CSV et une question en langage naturel, écrit itérativement du code pandas et matplotlib, puis produit un rapport soigné. Tu pratiques AI Engineering Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Engineering Academy ?

Aucune expérience préalable n'est requise. AI Engineering Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Créer un agent d’analyse de données » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Engineering Academy ?

Oui. Chaque leçon AI Engineering Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. La boucle d’exécution du code
  2. Isoler l’exécution avec Docker et RestrictedPython
  3. Gérer l’état entre les étapes d’exécution
  4. Créer un agent d’analyse de données
← Retour à AI Engineering Academy