Criando um agente de análise de dados
Crie um agente de análise de dados de ponta a ponta que aceite um arquivo CSV e uma pergunta em linguagem natural, escreva código com pandas e matplotlib de forma iterativa e produza um relatório refinado.
Criando um agente de análise de dados é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.
Partes desta aula ainda não foram traduzidas e aparecem em 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.
Perguntas Frequentes
A aula “Criando um agente de análise de dados” é grátis?
Sim — o texto completo de “Criando um agente de análise de dados” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.
O que vou aprender em “Criando um agente de análise de dados”?
Crie um agente de análise de dados de ponta a ponta que aceite um arquivo CSV e uma pergunta em linguagem natural, escreva código com pandas e matplotlib de forma iterativa e produza um relatório ref… Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar AI Engineering Academy?
Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Criando um agente de análise de dados”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de AI Engineering Academy?
Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O loop de execução de código
- Isolamento com Docker e RestrictedPython
- Gerenciamento de estado entre etapas de execução
- Criando um agente de análise de dados