Creare un agente per l'analisi dei dati
Crei un agente end-to-end per l'analisi dei dati che accetti un file CSV e una domanda in linguaggio naturale, scriva iterativamente codice pandas e matplotlib e produca un report curato.
Creare un agente per l'analisi dei dati è una lezione AI Engineering Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Engineering Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Engineering Academy include 4 lezioni in totale.
La visione dell'agente per l'analisi dei dati
Un agente per l'analisi dei dati accetta un file CSV e una domanda in linguaggio naturale, quindi esplora autonomamente i dati, li pulisce, calcola statistiche, genera visualizzazioni e produce un report curato, il tutto attraverso la generazione e l'esecuzione iterative di codice. Si tratta di una delle applicazioni più pratiche degli agenti di codice e riproduce direttamente il flusso di lavoro di un analista dei dati, senza l'intervento umano.
Architettura complessiva dell'agente
L'agente per l'analisi dei dati comprende quattro fasi concettuali: Esplorazione (comprendere struttura, tipi e qualità dei dati), Pulizia (gestire valori mancanti, valori anomali e conversioni dei tipi), Analisi (calcolare le metriche e le statistiche che rispondono alla domanda) e Report (generare grafici e riassumere i risultati in forma testuale). Ogni fase corrisponde da 1 a 5 iterazioni di esecuzione del codice.
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.
'''Fase 1: codice per l'esplorazione dei dati
La fase di esplorazione carica i dati e stampa immediatamente tutte le informazioni necessarie per pianificare l'analisi: dimensioni, nomi e tipi delle colonne, righe di esempio, statistiche riepilogative e conteggi dei valori null. L'LLM legge questo output e lo usa per prendere decisioni informate sulla pulizia e sull'analisi nelle iterazioni successive.
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.')Fase 2: pulizia dei dati
Dopo l'esplorazione, l'agente scrive codice di pulizia mirato sulla base di ciò che ha osservato. La strategia di pulizia è dinamica: se l'LLM ha osservato il 15% di valori null in una colonna, decide se eliminarli o imputarli. Se ha rilevato valori negativi in una colonna che dovrebbe contenere solo valori non negativi, li filtra. Questa pulizia adattiva e guidata dalle osservazioni è ciò che rende l'agente realmente utile, anziché limitarsi a eseguire una pipeline fissa.
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)Fase 3: rispondere alla domanda
Nella fase di analisi, l'agente si concentra sul calcolo della risposta specifica alla domanda dell'utente. Se la domanda è "quale categoria di prodotti ha registrato il fatturato più alto nell'ultimo trimestre?", l'agente scrive codice per filtrare in base alla data, raggruppare per categoria, sommare il fatturato e ordinare i risultati. Il codice di analisi viene generato da zero sulla base sia della domanda sia di ciò che l'agente ha osservato durante l'esplorazione: non è un modello generico.
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')Fase 4: generare grafici
Le visualizzazioni rendono i risultati analitici chiari e convincenti. L'agente per l'analisi dei dati genera grafici matplotlib e li salva come file PNG nello spazio di lavoro. Le principali scelte di progettazione del grafico — tipo di grafico, palette di colori, etichette degli assi, titolo e annotazioni — vengono effettuate dall'LLM in base alla natura dei dati. L'agente salva sempre i grafici in /workspace/, così potranno essere inclusi nel report finale.
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')Generare il report scritto
L'iterazione finale produce il report riepilogativo scritto. L'LLM legge i risultati dell'analisi e la descrizione del grafico, quindi scrive una narrazione concisa e accurata che risponde alla domanda originale con numeri specifici. Il report fa riferimento al grafico e include l'insight principale, i dati a supporto e una raccomandazione o un'implicazione per l'attività.
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)Assemblare l'orchestratore dell'agente
L'orchestratore collega tutte le fasi: inizializza lo spazio di lavoro, copia il CSV di input, esegue il ciclo di esecuzione del codice, controlla la presenza del segnale TASK COMPLETE e quindi raccoglie i file di output (report.md, chart.png). L'orchestratore gestisce anche gli errori, i nuovi tentativi e la pulizia finale dei file intermedi.
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
}Gestire le domande ambigue
Gli utenti pongono spesso domande ambigue come "quali prodotti stanno ottenendo buoni risultati?". Un agente robusto per l'analisi dei dati chiarisce l'ambiguità prima di iniziare: esplora innanzitutto i dati, individua le metriche disponibili e poi deduce l'interpretazione più sensata oppure chiede chiarimenti all'utente. Questo passaggio di riflessione impedisce all'agente di produrre una risposta tecnicamente corretta ma praticamente inutile.
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 responseControlli di qualità sull'output dell'agente
Al termine dell'esecuzione dell'agente, valuti la qualità del suo output. Verifichi che il file del report sia stato effettivamente creato, che il PNG del grafico sia un file immagine valido, che i numeri nel report corrispondano ai dati in analysis_result.json e che il report risponda realmente alla domanda originale. Un passaggio di controllo qualità automatizzato, che utilizzi una seconda chiamata a un LLM, può individuare i casi in cui l'agente ha completato il ciclo ma ha prodotto una risposta di scarsa qualità.
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}Estendere l'agente con strumenti specifici del dominio
L'agente di codice di base diventa ancora più potente quando viene esteso con strumenti specifici del dominio. Per un agente che lavora con dati finanziari, aggiunga funzioni per recuperare i prezzi azionari in tempo reale. Per un agente che lavora con dati di marketing, aggiunga l'accesso all'API di Google Analytics. Per un agente commerciale, aggiunga query Salesforce. Questi strumenti diventano disponibili per l'LLM tramite definizioni di funzioni nel system prompt oppure mediante il decoratore @tool di LangChain.
Verifica rapida
Verifichi la Sua comprensione dell'agente di analisi dei dati presentato in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato che un agente di analisi dei dati segue quattro fasi — esplorazione, pulizia, analisi e report — ciascuna implementata tramite generazione ed esecuzione iterative del codice; la generazione di grafici con matplotlib e la persistenza dello stato basata su file collegano le fasi in un flusso di lavoro coerente; infine, la convalida dell'output garantisce che la risposta finale dell'agente risponda effettivamente alla domanda originale. Nella prossima lezione esploreremo l'osservabilità e il tracing degli LLM.
Domande Frequenti
La lezione «Creare un agente per l'analisi dei dati» è gratuita?
Sì — il testo completo di «Creare un agente per l'analisi dei dati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Engineering Academy, passa a CoddyKit PRO. Il corso AI Engineering Academy include 4 lezioni in totale.
Cosa imparerò in «Creare un agente per l'analisi dei dati»?
Crei un agente end-to-end per l'analisi dei dati che accetti un file CSV e una domanda in linguaggio naturale, scriva iterativamente codice pandas e matplotlib e produca un report curato. Eserciti AI Engineering Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Engineering Academy?
Non è richiesta alcuna esperienza precedente. AI Engineering Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Creare un agente per l'analisi dei dati»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Engineering Academy?
Sì. Ogni lezione AI Engineering Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Il loop di esecuzione del codice
- Sandboxing con Docker e RestrictedPython
- Gestire lo stato tra i passaggi di esecuzione
- Creare un agente per l'analisi dei dati