Skip to main content
Data analysis agent that processes CSV files and generates visualizations.

Code

Create ai-data-analysis-agent.py with the code below, or save it directly from your editor.
import os
import traceback
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import seaborn as sns
from agno.agent import Agent
from agno.models.openrouter import OpenRouter
from bindu.penguin.bindufy import bindufy
from dotenv import load_dotenv

load_dotenv()

# -----------------------------
# Custom Data Analyst Tools
# -----------------------------

def analyze_dataset(file_path: str) -> str:
    if not os.path.exists(file_path):
        return f"Error: File not found at {file_path}. Please provide a valid absolute path."
    try:
        df = pd.read_csv(file_path)
        info = [
            f"Dataset Shape: {df.shape[0]} rows, {df.shape[1]} columns\n",
            "Columns and Data Types:\n" + str(df.dtypes) + "\n",
            "Missing Values:\n" + str(df.isnull().sum()) + "\n",
            "Summary Statistics:\n" + df.describe(include='all').to_string()
        ]
        return "\n".join(info)
    except Exception as e:
        return f"Error analyzing dataset: {str(e)}"

def generate_visualization(file_path: str, x_column: str, y_column: str, chart_type: str = "bar") -> str:
    if not os.path.exists(file_path):
        return f"Error: File not found at {file_path}."
    try:
        df = pd.read_csv(file_path)
        if x_column not in df.columns or (y_column and y_column not in df.columns):
            return f"Error: Columns '{x_column}' or '{y_column}' not found."

        plt.figure(figsize=(10, 6))
        sns.set_theme(style="whitegrid")

        if chart_type == "bar":
            sns.barplot(data=df, x=x_column, y=y_column)
        elif chart_type == "line":
            sns.lineplot(data=df, x=x_column, y=y_column)
        else:
            sns.scatterplot(data=df, x=x_column, y=y_column)

        plt.title(f"{chart_type.capitalize()} Chart: {y_column} vs {x_column}")
        plt.xticks(rotation=45)
        plt.tight_layout()

        os.makedirs("outputs", exist_ok=True)
        output_path = f"outputs/chart_{x_column}_{y_column}.png"
        plt.savefig(output_path)
        plt.close()

        return f"Success! Visualization generated and saved to: {output_path}"
    except Exception as e:
        return f"Error generating visualization: {str(e)}"

# -----------------------------
# Agent Handler
# -----------------------------

def handler(messages: list[dict]):
    try:
        last_message = messages[-1]
        user_query = ""

        # Safely extract text from the Bindu payload
        if "parts" in last_message:
            for part in last_message["parts"]:
                if part.get("kind") == "text":
                    user_query += part.get("text", "") + "\n"
        elif "content" in last_message:
            user_query = last_message.get("content", "")

        user_query = user_query.strip()

        if not user_query:
            return [{"role": "assistant", "content": "Error: No text received."}]

        # Instantiate agent cleanly inside the thread
        agent = Agent(
            name="AI Data Analysis Agent",
            instructions=[
                "You are an elite Data Scientist.",
                "When a user provides a path to a CSV, use the 'analyze_dataset' tool to understand its structure.",
                "Proactively use the 'generate_visualization' tool to create compelling charts.",
                "Always format your final output as a highly structured analytical report using Markdown."
            ],
            model=OpenRouter(
                id="openai/gpt-oss-120b",
                api_key=os.getenv("OPENROUTER_API_KEY")
            ),
            tools=[analyze_dataset, generate_visualization],
            markdown=True,
            telemetry=False
        )

        result = agent.run(user_query)

        # Agent autonomously saves its own report
        os.makedirs("outputs", exist_ok=True)
        report_path = "outputs/analysis_report.md"
        with open(report_path, "w", encoding="utf-8") as f:
            f.write(result.content)

        return [{"role": "assistant", "content": str(result.content)}]

    except Exception as e:
        traceback.print_exc()
        return [{"role": "assistant", "content": f"Agent crashed: {str(e)}"}]

# -----------------------------
# Bindu Configuration
# -----------------------------

config = {
    "author": "your.email@example.com",
    "name": "AI Data Analysis Agent",
    "description": "An analytical agent that processes CSV data and generates visual charts.",
    "deployment": {
        "url": "http://localhost:3773",
        "expose": True,
        "cors_origins": ["http://localhost:5173"]
    },
    "skills":["skills/ai-data-analysis-agent"],
}

if __name__ == "__main__":
    bindufy(config=config, handler=handler)

Skill Configuration

Create skills/ai-data-analysis-agent/skill.yaml:
id: data-analysis-skill
name: data-analysis-skill
version: 1.0.0
author: your.email@example.com
description: |
  Advanced data science skill that provides comprehensive dataset analysis,
  statistical summaries, and autonomous visual chart generation.

  Features:
  - CSV parsing and structural analysis
  - Statistical summaries (mean, median, standard deviation)
  - Missing value detection and data type inference
  - Autonomous data visualization (Bar, Line, and Scatter charts)
  - Markdown-formatted analytical reporting

  Uses Pandas for heavy data manipulation and a thread-safe
  Matplotlib/Seaborn backend (Agg) for background image generation.
tags:
  - data-science
  - analytics
  - visualization
  - pandas
  - csv
  - statistics
input_modes:
  - application/json
output_modes:
  - application/json
examples:
  - "Please analyze the dataset located at sample_sales.csv"
  - "Give me a brief summary of the data, and generate a bar chart showing Sales by Product"
  - "Are there any missing values in this dataset?"
  - "Create a scatter plot comparing Revenue and Marketing Spend"
capabilities_detail:
  dataset_parsing:
    supported: true
    description: "Ability to ingest and read CSV file structures"
  statistical_analysis:
    supported: true
    description: "Computes core statistics and identifies data anomalies/nulls"
  data_visualization:
    supported: true
    description: "Generates custom PNG charts based on user prompts and data trends"
  markdown_reporting:
    supported: true
    description: "Synthesizes data findings into highly readable Markdown reports"

How It Works

Data Processing
  • analyze_dataset: Reads CSV files and generates summary statistics
  • Reports dataset shape, data types, missing values, and descriptive statistics
  • Handles file path validation and error reporting
Visualization Generation
  • generate_visualization: Creates charts using matplotlib and seaborn
  • Supports bar, line, and scatter plots
  • Automatically saves charts to outputs directory
  • Configurable chart styling with seaborn themes
Agent Capabilities
  • Elite Data Scientist persona with analytical expertise
  • Proactively uses tools for dataset understanding
  • Generates structured Markdown reports
  • Autonomous report saving to file system
Error Handling
  • Robust exception handling with detailed error messages
  • File path validation and existence checks
  • Graceful failure recovery with user feedback

Dependencies

uv init
uv add bindu agno python-dotenv pandas matplotlib seaborn

Environment Setup

Create .env file:
OPENROUTER_API_KEY=your_openrouter_api_key_here

Run

uv run ai-data-analysis-agent.py
Examples:
  • “Analyze the dataset at /path/to/your/data.csv and create a bar chart showing sales by region”
  • “Give me a brief summary of data, and generate a bar chart showing Sales by Product”
  • “Are there any missing values in this dataset?”

Example API Calls

{
  "jsonrpc": "2.0",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "kind": "message",
      "messageId": "9f11c870-5616-49ad-b187-d93cbb100001",
      "contextId": "9f11c870-5616-49ad-b187-d93cbb100002",
      "taskId": "9f11c870-5616-49ad-b187-d93cbb100003",
      "parts": [
        {
          "kind": "text",
          "text": "Analyze the dataset at /path/to/your/data.csv and create a bar chart showing sales by region"
        }
      ]
    },
     "skillId": "data-analysis-skill",
    "configuration": {
      "acceptedOutputModes": ["application/json"]
    }
  },
  "id": "9f11c870-5616-49ad-b187-d93cbb100003"
}
{
  "jsonrpc": "2.0",
  "method": "tasks/get",
  "params": {
    "taskId": "9f11c870-5616-49ad-b187-d93cbb100003"
  },
  "id": "9f11c870-5616-49ad-b187-d93cbb100004"
}

Frontend Setup

# Clone the Bindu repository
git clone https://github.com/GetBindu/Bindu

# Navigate to frontend directory
cd frontend

# Install dependencies
npm install

# Start frontend development server
npm run dev
Open http://localhost:5173 and try to chat with the AI data analysis agent