CrewAI: Agentic Exploratory Data Analysis
This notebook demonstrates a real-world CrewAI application where a Data Analyst agent performs Exploratory Data Analysis (EDA) on a CSV dataset using three custom tools.
Workflow¶
- Generate a synthetic sales dataset
- Define three EDA tools (preview, histogram, grouped aggregation)
- Create a Data Analyst agent equipped with those tools
- Assign a multi-step EDA task and execute the crew
- Display the histogram artifact produced by the agent
All reusable helper functions live in crewai_utils.py; this notebook
only orchestrates and displays results.
%load_ext autoreload
%autoreload 2
import logging
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from crewai import Agent, Crew, Process, Task
import crewai_utils as tcrwuti
logging.basicConfig(level=logging.INFO)
_LOG = logging.getLogger(__name__)Part 1: Data Preparation¶
Objective: Create a synthetic sales dataset to use throughout the tutorial.
- Columns:
region,month,units_sold,price - 20 rows; random seed fixed at 42 for reproducibility
- Saved to
data/sales.csv
# Generate (or regenerate) the demo sales CSV.
csv_path = tcrwuti.generate_sales_csv("data/sales.csv")
print(f"Dataset saved to: {csv_path}")
# Quick sanity check – preview the first few rows.
import pandas as pd
df = pd.read_csv(csv_path)
print(df.head())Part 2: LLM and Agent Setup¶
Objective: Configure a local Ollama LLM and create a Data Analyst agent with three EDA tools:
read_head– preview CSV rowsplot_histogram– generate a histogram PNGgroupby_agg– compute grouped means
All tools are defined in crewai_utils.EDA_TOOLS.
# Use the local Ollama LLM so no API key is required.
llm = tcrwuti.get_local_llm(
model="ollama/gemma3:latest",
base_url="http://host.docker.internal:11434",
temperature=0,
)
# Create the Data Analyst agent.
analyst = Agent(
role="Data Analyst",
goal=(
"Perform lightweight EDA on local CSVs via tools and "
"report succinct results."
),
backstory=(
"Prefers precise, minimal outputs. Uses tools exactly as requested."
),
tools=tcrwuti.EDA_TOOLS,
llm=llm,
verbose=True,
)
print(f"Agent tools: {[t.name for t in analyst.tools]}")Part 3: EDA Task Definition¶
Objective: Define a three-step EDA task for the agent.
The task instructs the agent to:
- Preview the top 5 rows of the CSV
- Plot a histogram of the
pricecolumn - Compute mean
units_soldgrouped byregion
The expected_output anchors the agent’s final response format.
eda_task = Task(
description=(
"1) Use read_head on './data/sales.csv' (n=5).\n"
"2) Use plot_histogram on column 'price' with 20 bins.\n"
"3) Use groupby_agg by 'region' on metric 'units_sold'.\n"
"Return three sections: PREVIEW, HISTOGRAM_PATH, GROUPED_MEANS, "
"each containing only the respective tool output."
),
expected_output="Sections: PREVIEW, HISTOGRAM_PATH, GROUPED_MEANS.",
agent=analyst,
)Part 4: Crew Execution¶
Objective: Assemble the crew and run the EDA pipeline.
We use Process.sequential since there is only a single task.
crew = Crew(
agents=[analyst],
tasks=[eda_task],
process=Process.sequential,
verbose=True,
)
# Run the crew and capture the structured result.
result = crew.kickoff()
print("\n=== RESULT ===\n", result)Part 5: Display Artifacts¶
Objective: Show the histogram PNG generated by the agent.
# Display the histogram generated by the plot_histogram tool.
hist_path = "artifacts/hist_price.png"
try:
img = mpimg.imread(hist_path)
fig, ax = plt.subplots(figsize=(7, 4))
ax.imshow(img)
ax.axis("off")
ax.set_title("Histogram of price (generated by CrewAI agent)")
plt.tight_layout()
plt.show()
except FileNotFoundError:
print(f"Histogram not found at {hist_path}. Run the crew first.")