Autonomous Data Analyst Agent
An LLM-powered autonomous agent that accepts a dataset, plans analysis, writes Python code, executes it in a sandbox, self-corrects on errors, and generates actionable insights — all streamed to a React dashboard in real time.
┌─────────────────────────────────────────────────────────────────┐
│ React Dashboard │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │CSV Upload│ │ Chat UI │ │Code View │ │Reasoning Trace│ │
│ └────┬─────┘ └────┬─────┘ └──────────┘ └───────────────┘ │
│ │ │ ▲ ▲ │
│ │ SSE Stream│ │ │ │
└───────┼──────────────┼─────────────┼───────────────┼────────────┘
│ │ │ │
▼ ▼ │ │
┌───────────────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌─────────────┐ │
│ │ Planner │→ │ Executor │→ │Reflection │→ │ Narrative │ │
│ │(LLM call)│ │(tool loop)│ │ (fix loop) │ │ Generator │ │
│ └──────────┘ └────┬─────┘ └───────────┘ └─────────────┘ │
│ │ │
│ ┌───────────────────┴───────────────────────────────┐ │
│ │ Memory Manager │ │
│ │ • Conversation Memory • Task / Step Memory │ │
│ │ • Error Memory • Context Variables │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────┴───────────────────────────────┐ │
│ │ Tool Registry │ │
│ │ • execute_python (subprocess sandbox) │ │
│ │ • query_dataframe (pandas .query()) │ │
│ │ • summarize_findings (insight recording) │ │
│ └────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
Feature
Details
Tool Calling
OpenAI function calling with 3 tools: Python REPL, DataFrame query, findings recorder
Code Execution Sandbox
Subprocess-isolated Python execution with timeout, stdout/stderr capture, matplotlib→base64
Planning
LLM decomposes the user question into 3-7 ordered analysis steps
Reflection Loop
On execution errors, the LLM diagnoses → rewrites → retries (up to 3 attempts)
Memory Management
Conversation memory, step memory, error memory, and shared context variables
Streaming
Real-time SSE stream from backend to frontend — see every step as it happens
Visual Dashboard
React + Tailwind UI: CSV upload, chat, generated code viewer, plot gallery, reasoning trace
Decision
Rationale
Subprocess sandbox over exec()
Process isolation prevents agent code from crashing the server
SSE over WebSockets
Simpler for unidirectional streaming; works behind most proxies
Zustand over Redux
Minimal boilerplate for simple state management
JSON-mode for planner
Structured output avoids fragile parsing of free-text plans
Context variable serialization
DataFrames round-trip as JSON so they survive across separate subprocess executions
Separate reflection module
Clean separation of concerns; the reflection prompt is specialized for debugging
Failure Cases & Guard Rails
Scenario
Handling
Code times out (>30s)
Subprocess killed; error reported to user
Infinite loop in agent code
Caught by execution timeout
LLM returns malformed JSON
Fallback default plan / graceful error
3 consecutive fix attempts fail
Reflection gives up, reports partial results
Large stdout (>8KB)
Truncated to prevent context overflow
Non-CSV upload
Rejected at API level with 400
Python 3.11+
Node.js 18+
OpenAI API key
cd backend
cp .env.example .env # add your OPENAI_API_KEY
pip install -r requirements.txt
python main.py # runs on :8000
cd frontend
npm install
npm run dev # runs on :5173, proxies /api → :8000
cp backend/.env.example backend/.env # add your key
docker-compose up --build
# Frontend → http://localhost:3000
# Backend → http://localhost:8000
autonomous-analyst/
├── backend/
│ ├── agent/
│ │ ├── memory.py # Conversation + step + error memory
│ │ ├── planner.py # LLM-based task decomposition
│ │ ├── executor.py # Tool calling loop (LLM → tool → LLM)
│ │ ├── reflection.py # Error diagnosis + code rewrite loop
│ │ ├── orchestrator.py # Main agent loop with SSE streaming
│ │ └── tools.py # OpenAI function definitions
│ ├── api/
│ │ └── routes.py # FastAPI endpoints (/upload, /analyse, etc.)
│ ├── core/
│ │ ├── config.py # Settings (env vars, limits)
│ │ └── sandbox.py # Subprocess code execution engine
│ └── main.py # FastAPI entry point
├── frontend/
│ └── src/
│ ├── components/
│ │ ├── CSVUploader.tsx
│ │ ├── ChatInterface.tsx
│ │ ├── CodeViewer.tsx
│ │ ├── PlotViewer.tsx
│ │ └── ReasoningTrace.tsx
│ ├── hooks/useAnalysis.ts
│ ├── store/agentStore.ts
│ └── App.tsx
├── docker/
│ ├── Dockerfile.backend
│ ├── Dockerfile.frontend
│ └── nginx.conf
└── docker-compose.yml
No persistent storage — sessions are in-memory; restarting the server clears all state.
Single-user sandbox — subprocess execution is not containerized per-request (use Docker sandbox for production).
OpenAI dependency — currently requires an OpenAI API key. Swap in any OpenAI-compatible endpoint (Ollama, vLLM, etc.) by changing the base URL.
No authentication — add API key middleware or OAuth for production.
CSV only — Excel, Parquet, JSON ingestion not implemented yet.
Model
Avg. tokens per analysis
Estimated cost
GPT-4o
~8,000–15,000
$0.04–$0.12
GPT-4o-mini
~8,000–15,000
$0.002–$0.005
Llama 3 70B (self-hosted)
~8,000–15,000
Infrastructure only
MIT