Every time I needed to explore a dataset quickly, the same wall appeared: spin up a notebook, deal with encoding errors, write the cleaning boilerplate, decide which chart type actually makes sense, iterate when the data has surprises. The mechanical parts — null handling, imputation, finding correlations, picking a visualization — aren't interesting work. They're just in the way.
Tools like ChatGPT's Code Interpreter or Julius AI solve this. But they upload your data to a cloud you don't control, lock you into one LLM, and charge per seat. I wanted something that ran on my own hardware, worked with whichever model I preferred, and didn't require an account to try.
So I built Insight Orchestra — an open-source, self-hostable AI data analyst. Connect a file or a database, watch four specialized agents work through the analysis in real time, then keep asking follow-up questions in plain English.
Your data, analyzed by a team of AI agents.
Connect a data file or a database and watch specialized agents clean it, form hypotheses,
debate them, and visualize what matters — then ask follow-ups in plain English
Website · Docs · Report a bug
A real run on the bundled Sales dataset — unedited.
Insight Orchestra is an open-source AI data analyst you can self-host — think Julius AI or ChatGPT's data analysis, but running on your own hardware, with your choice of LLM, where your data never leaves your machine. Upload a data file — CSV, TSV, Excel, JSON, or Parquet — or connect a PostgreSQL, MySQL, SQLite, or DuckDB database, and a 4-agent pipeline cleans the data, generates evidence-backed hypotheses, scores them in an LLM-refereed debate, and builds interactive Plotly charts. Then keep asking questions in plain English: an NLQ agent writes…
Files: CSV, TSV (auto-detects encoding and delimiter — semicolons and pipes work fine), Excel .xlsx, JSON records, Parquet.
Databases: PostgreSQL, MySQL, SQLite, DuckDB — connect with a standard connection string and the agent can query across all your tables with JOINs, not just one materialized table at a time. BigQuery is available as an experimental connector.
LLMs: OpenAI, Anthropic, or DeepSeek in the cloud, or fully local and private with Ollama. You can switch provider and model at runtime through the UI — no restart needed.
When you run an analysis, four agents execute sequentially, each passing its output to the next:
Your data (file or database table)
│
▼
┌──────────────────────────────────┐
│ [1] Data Janitor │
│ Removes dupes, imputes missing │
│ values, flags bias (>30% null), │
│ detects outliers via IQR │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ [2] Hypothesis Bot │
│ Builds stats summary (means, │
│ correlations, distributions) │
│ → LLM generates 5-8 directional │
│ insights grounded in the numbers │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ [3] Debate Manager │
│ LLM scores each hypothesis on │
│ confidence × business value, │
│ citing the actual statistics │
│ → elects a consensus finding │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ [4] Viz Whiz │
│ Up to 6 Plotly charts, chart │
│ type chosen by data types │
│ (scatter, bar, histogram, etc.) │
└────────────────┬─────────────────┘
│
▼
Narrative summary
+ suggested follow-up questions
(streamed live to your browser)
Progress for each stage streams to your browser via Server-Sent Events as it runs — you see what's happening instead of waiting for a spinner to resolve into a wall of output.
After the pipeline finishes, you can keep asking questions in plain English. The NLQ agent converts them to pandas code, executes in a sandbox, and renders a chart if one was produced. For connected databases, a separate agent generates read-only SQL instead of pandas code — JOIN-capable across every table in your schema.
The first prototype was a single prompt: "here's the CSV schema and some sample rows, write me an analysis." It works on clean, small datasets. On real data it falls apart.
A single call trying to clean, analyze, and visualize at once has no recovery path when one step fails. You don't know whether the bad chart came from a cleaning mistake, a wrong assumption in the analysis, or buggy visualization code. There's no partial output, no progress feedback, and the prompt balloons quickly when you embed schema, sample rows, and instructions together.
Splitting into agents gives you a different contract: each agent has one job and produces structured output. The Debate Manager receives the same statistics summary the Hypothesis Bot used — it's scoring hypotheses against actual evidence, not just voting on text. Failures are local. The system degrades gracefully if the LLM is unavailable: the Janitor runs without one, and the Hypothesis Bot falls back to heuristic group/correlation analysis and labels the output accordingly.
The NLQ agent writes Python and runs it. exec() on untrusted code is obviously dangerous — the model can write os.system(...), read files outside the data directory, or make network calls. Even if you trust the model, a user can upload a CSV with a prompt-injected column value.
The solution is RestrictedPython. Every generated script goes through two passes before execution:
open, no os, no subprocess, no __import__ outside a curated allowlist
The model can use NumPy, pandas, and Plotly. It cannot touch the filesystem or the network. If generated code tries, it gets a clean exception.
There's a real trade-off here: RestrictedPython occasionally blocks valid pandas patterns that use unusual builtins, and it doesn't cover every possible attack surface. The allowlist needed tuning. But it's a meaningful reduction in blast radius compared to raw exec, and the NLQ agent retries with the error message fed back to the model — most blocked patterns resolve on retry.
Prerequisites: Docker, Docker Compose v2, Git. 4 GB RAM (8 GB+ for local LLMs).
The easiest path is the setup wizard, which asks which LLM provider to use, writes backend/.env, and pulls prebuilt images:
curl -fsSL https://raw.githubusercontent.com/laban254/insight-orchestra/main/install.sh | bash
Or clone first and run the wizard yourself:
git clone https://github.com/laban254/insight-orchestra.git
cd insight-orchestra
./setup.sh
For a fully non-interactive setup (CI, provisioning scripts):
./setup.sh --provider ollama -y
./setup.sh --provider openai --api-key sk-... -y
If something doesn't start, ./setup.sh doctor checks Docker, ports, config, and running services.
Open http://localhost:3000. No login required by default.
Insight Orchestra ships with auth disabled. For local use, a personal install, or an internal tool on a private network, requiring login adds friction with no benefit.
One environment variable flips the full RBAC system on:
AUTH_ENABLED=true
With auth enabled you get: local accounts (email + password), OIDC SSO (Google, Okta, or any standards-compliant IdP), API key management with optional expiry, three roles (admin / member / viewer), and an audit log for logins and user management actions.
Query cache — the same question against the same dataset and model is served from an in-memory cache (1 hour TTL) rather than calling the LLM again. Follow-up sessions that re-ask a prior question are instant.
Workspaces — analysis sessions are saveable and reopenable. The platform checks whether the original dataset is still available and surfaces a clear error up front rather than failing silently mid-session.
Degraded mode — if your LLM provider is unreachable, the pipeline doesn't silently return heuristic output as if it were LLM-backed. Each stage that fell back is named explicitly in the response so you know what you're looking at.
Large dataset sampling — datasets over 250k rows are sampled for the pipeline, with a notice showing how many rows were analyzed vs. the total.
RAG grounding (optional) — the Hypothesis Bot can pull findings from previously analyzed datasets via vector search, grounding new hypotheses in past work. Needs a PostgreSQL instance with the pgvector extension and an OpenAI or Ollama embedding model.
| Layer | Technology |
|---|---|
| Backend | FastAPI (Python) |
| Frontend | Next.js (TypeScript) |
| Agents | Google ADK |
| Real-time | Server-Sent Events |
| Session state | Redis (in-memory fallback) |
| LLM providers | OpenAI, Anthropic, DeepSeek, Ollama |
| Code sandbox | RestrictedPython |
| Deployment | Docker Compose + prebuilt images |
The repo is at github.com/laban254/insight-orchestra. MIT-licensed. There are docs covering setup, the agent pipeline, and the API reference, and a CONTRIBUTING.md if you want to add an agent or a connector.
If you run into something rough, open an issue. If you find it useful, a star helps others find it.
What data source would make this most useful for your workflow — a specific database connector, a file format, or something else entirely?