Creación de un agente de análisis de datos
Cree un agente de análisis de datos de principio a fin que acepte un archivo CSV y una pregunta en lenguaje natural, escriba código de pandas y matplotlib de forma iterativa y produzca un informe elaborado.
Creación de un agente de análisis de datos es una lección gratuita de AI Engineering Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Engineering Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Engineering Academy incluye 4 lecciones en total.
Partes de esta lección aún no han sido traducidas y se muestran en inglés.
The Data Analysis Agent Vision
A data analysis agent accepts a CSV file and a natural language question, then autonomously explores the data, cleans it, computes statistics, generates visualizations, and produces a polished report — all through iterative code generation and execution. This is one of the most practical applications of code agents and directly replicates the workflow of a data analyst, minus the human effort.
The Agent's Overall Architecture
The data analysis agent has four conceptual phases: Exploration (understand the data's shape, types, and quality), Cleaning (handle missing values, outliers, type conversions), Analysis (compute the metrics and statistics that answer the question), and Reporting (generate charts and summarize findings in prose). Each phase corresponds to 1-5 code execution iterations.
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: Data Exploration Code
The exploration phase loads the data and immediately prints all the information needed to plan the analysis: shape, column names and types, sample rows, summary statistics, and null counts. The LLM reads this output and uses it to make informed decisions about cleaning and analysis in subsequent iterations.
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: Data Cleaning
After exploration, the agent writes targeted cleaning code based on what it observed. The cleaning strategy is dynamic — if the LLM observed 15% nulls in a column, it decides whether to drop or impute. If it saw negative values in a column that should be non-negative, it filters them. This adaptive, observation-driven cleaning is what makes the agent genuinely useful rather than just running a fixed pipeline.
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: Answering the Question
In the analysis phase, the agent focuses on computing the specific answer to the user's question. If the question is 'which product category had the highest revenue last quarter?', the agent writes code to filter by date, group by category, sum revenue, and sort. The analysis code is generated fresh based on both the question and what the agent observed during exploration — it is not a generic template.
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: Generating Charts
Visualizations make analytical findings clear and compelling. The data analysis agent generates matplotlib charts and saves them as PNG files in the workspace. Key chart design decisions — chart type, color palette, axis labels, title, annotations — are made by the LLM based on the nature of the data. The agent always saves charts to /workspace/ so they can be included in the final report.
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')Generating the Written Report
The final iteration produces the written summary report. The LLM reads the analysis results and chart description, then writes a concise, accurate narrative that answers the original question with specific numbers. The report references the chart and includes the key insight, supporting data, and a recommendation or implication for the business.
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)Assembling the Agent Orchestrator
The orchestrator ties all phases together: it initializes the workspace, copies the input CSV, runs the code execution loop, monitors for the TASK COMPLETE signal, and then collects the output files (report.md, chart.png). The orchestrator also handles errors, retries, and the final cleanup of intermediate files.
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
}Handling Ambiguous Questions
Users often ask ambiguous questions like 'which products are performing well?'. A robust data analysis agent clarifies ambiguity before starting: it first explores the data, identifies what metrics are available, and then either infers the most sensible interpretation or asks the user for clarification. This reflection step prevents the agent from producing a technically correct but practically useless answer.
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 responseQuality Checks on Agent Output
After the agent completes, validate the quality of its output. Check that the report file was actually created, the chart PNG is a valid image file, the numbers in the report match the data in analysis_result.json, and the report actually answers the original question. An automated QA step using a second LLM call can catch cases where the agent completed the loop but produced a poor answer.
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}Extending the Agent with Domain Tools
The basic code agent becomes even more powerful when extended with domain-specific tools. For a financial data agent, add functions that fetch live stock prices. For a marketing data agent, add Google Analytics API access. For a sales agent, add Salesforce queries. These tools become available to the LLM through function definitions in the system prompt or through LangChain's @tool decorator.
Quick Check
Test your understanding of the data analysis agent from this lesson.
Lesson Recap
In this lesson you learned: a data analysis agent follows four phases — explore, clean, analyze, report — each implemented through iterative code generation and execution, chart generation with matplotlib and file-based state persistence tie the phases together into a coherent workflow, and output validation ensures the agent's final answer actually addresses the original question. Next up we explore LLM observability and tracing.
Preguntas frecuentes
¿La lección «Creación de un agente de análisis de datos» es gratis?
Sí — el texto completo de «Creación de un agente de análisis de datos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Engineering Academy, actualiza a CoddyKit PRO. El curso de AI Engineering Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Creación de un agente de análisis de datos»?
Cree un agente de análisis de datos de principio a fin que acepte un archivo CSV y una pregunta en lenguaje natural, escriba código de pandas y matplotlib de forma iterativa y produzca un informe ela… Practicas AI Engineering Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar AI Engineering Academy?
No se requiere experiencia previa. AI Engineering Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Creación de un agente de análisis de datos»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de AI Engineering Academy?
Sí. Cada lección de AI Engineering Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- El bucle de ejecución de código
- Aislamiento con Docker y RestrictedPython
- Gestión del estado entre pasos de ejecución
- Creación de un agente de análisis de datos