Skip to main content
Web Application (SaaS)

Building PrismAnalyst: A Privacy-First, Multi-Agent AI Analyst for Business Data

By Sameer Joshi

A conversational BI platform that lets business teams upload a spreadsheet and ask questions in plain English. Every answer is verified by a live SQL query, never guessed, and raw data never leaves the customer's environment.

Platform

Web (SSE Chat)

Duration

5 weeks

3

Specialist agents behind one supervisor

2

Tools power every analysis (SQL + chart)

94

Automated tests covering safety, privacy, and routing

Project overview

A validated multi-agent, zero-hallucination architecture: three specialist agents, a two-tool SQL-first design, and a Schema-Only privacy protocol, now the basis for PrismAnalyst's production roadmap.

Platform

Web (SSE Chat)

Duration

5 weeks

Type

Web Application (SaaS)

Stack

10 technologies

The challenge

Business teams sit on more spreadsheet data than they can use, but getting a straight answer means waiting on an analyst, learning SQL, or trusting a general-purpose AI assistant that can state a wrong number with full confidence and needs to see raw, often sensitive rows to do it.

Getting a simple answer from business data meant waiting on an analyst or a BI ticket queue

Traditional BI tools require SQL, or a data team to write it, before anyone can ask a new question

Uploading spreadsheets to a general-purpose AI assistant sends raw rows, including anything sensitive in them, to a third-party model

General AI answers cannot be audited: there is no way to check which numbers were computed versus recalled from the model's memory

Real-world spreadsheets are messy (title rows, merged cells, footer totals) and break naive CSV ingestion before analysis can even start

What we set out to do

  • 01

    Let a business user upload a spreadsheet and ask questions in plain English, with zero SQL required

  • 02

    Route each question to the right specialist automatically: sales/revenue, inventory/assortment, or deep analysis and forecasting

  • 03

    Make it architecturally impossible for an agent to answer without executing a real query: no hallucinated numbers

  • 04

    Keep raw data inside the customer's own environment: the LLM should only ever see schema and aggregated results

  • 05

    Handle real-world, messy Excel exports (title rows, merged cells, footer totals) without a manual cleanup step

How we solved it

01

Multi-Agent Supervisor Routing

A LangGraph StateGraph opens every conversation at a Supervisor node, which classifies the question against five labels (SALES, ASSORTMENT, ANALYST, BOTH, CLARIFY) using structured (Zod-validated) output from the LLM. If structured output fails, a regex-based fallback parser extracts the route from raw text, and if that fails too, the system defaults to SALES rather than going silent: a real question should never be dropped on a parsing error. BOTH triggers a chained hand-off: the Sales agent runs first and passes its findings as context into the Assortment agent, so a question like "what's driving the revenue drop, and which SKUs are at risk" gets a coordinated answer from two specialists instead of one shallow one.

Key decision

Structured output with a text-parsing fallback and a safe default, rather than a single brittle parse path

Result

Reliable routing across Sales, Assortment, and Analyst specialists, validated by a dedicated routing test suite covering malformed and edge-case responses

02

SQL-First, Zero-Hallucination Tooling

Every specialist agent (Sales, Assortment, and Analyst) is given exactly two tools: query_dataset_sql and generate_chart. There is no separate hardcoded statistics, forecasting, or recommendations engine; those existed in an earlier iteration and were deliberately removed once the team proved the LLM could write the SQL itself. Forecasting runs as a REGR_SLOPE/REGR_INTERCEPT regression, anomaly detection as an IQR calculation via PERCENTILE_CONT, correlation via CORR, and period comparisons via window functions (LAG/LEAD), all computed live against the uploaded data, not recalled from the model's memory.

Key decision

Two shared tools and SQL-first analysis over a library of specialized, hardcoded analysis tools

Result

Agents are structurally prevented from answering without a query result behind them; every number in every answer traces back to an executed SQL statement

03

Schema-Only Privacy Protocol

The analysis engine, DuckDB, runs in-process and never exposes raw rows to the LLM. The model only ever receives the dataset's column names and types, plus aggregated query results: sums, counts, averages, capped result sets. A strict-mode layer sits in front of every query result: it caps output to 50 rows and 5 columns by default, and auto-detects and redacts likely PII columns (email, phone, address, SSN, date of birth, and more) by name pattern before anything reaches the model.

Key decision

Enforce the privacy boundary in code (a result-shaping layer), not just as a prompt instruction

Result

Raw customer rows and PII fields never reach the LLM, by construction rather than by policy

04

SQL Safety Guardrails

Because agents write their own SQL, that SQL has to be untrusted input. A validator requires every query to start with SELECT or WITH, rejects a blocklist of mutating keywords and file/network functions (INSERT, DROP, ATTACH, COPY, read_csv, httpfs, and others), and blocks multiple chained statements. A LIMIT is auto-injected on any query that lacks one, and an existing LIMIT is capped rather than trusted outright, with nesting-aware parsing so a LIMIT inside a subquery isn't mistaken for the outer one. Every query also runs under a hard timeout.

Key decision

A dedicated, independently-tested SQL validator between the agent and the database, rather than trusting model-generated SQL directly

Result

The largest single test file in the suite (24 cases) is dedicated to this validator, covering injection attempts, keyword bypasses, and LIMIT edge cases

05

LLM-Guided Excel Ingestion

Real spreadsheets exported from enterprise systems rarely start with a clean header row. The ingestion pipeline unmerges merged cells (propagating the top-left value across the range), then, for anything larger than 20 rows, asks the LLM to look at the first and last 20 rows and identify where the actual header row and any footer/summary rows are, so title rows, generated-on timestamps, and "Grand Total" rows get stripped before the data ever reaches DuckDB. Once ingested, a separate pass samples each text column and auto-casts it to a proper DATE type when 90%+ of sampled values parse cleanly, correcting for cases where DuckDB's own CSV auto-detection misses non-ISO date formats.

Key decision

Use the LLM for structural cleanup of the file itself, not only for answering questions about it

Result

CSV, Excel (.xlsx/.xls), and JSON uploads all convert into a clean, correctly-typed DuckDB table without a manual data-prep step

Measurable impact

3

Specialist Agents

2

Tools per Agent

94

Automated Tests

0

Raw Rows Sent to the LLM

5

SQL-Computed Analysis Types

Tech stack

TTypeScriptNNode.jsEExpressLLangGraphDDuckDBZZodSSheetJSVVitestCClaude (Anthropic)RRender

What we learned

PrismAnalyst started as the generalized form of a conversational analytics interface first built inside an enterprise engagement, then rebuilt from the ground up as a standalone architecture: any team with a spreadsheet and a question, no analyst or SQL required, and no requirement to trust an AI vendor with raw business data to get there.

  • 01

    Constraining an agent to "always query, never recall" removes hallucination structurally: prompt instructions alone don't hold up under pressure, a tool-call requirement does

  • 02

    Privacy can be an architectural property, not just a policy statement: a schema-only boundary enforced in code is a stronger claim than "we promise not to look"

  • 03

    Real-world spreadsheets need an LLM in the ingestion path, not only the chat path: header/footer detection on messy enterprise exports is its own hard problem

  • 04

    A small, independently-tested SQL validator (blocklist, LIMIT injection, statement-count check) closes most of the risk of letting an LLM write live queries against a database

  • 05

    Removing code can be a milestone: retiring three hardcoded analysis tools in favor of SQL-first generation was a deliberate simplification, not a shortcut

Ready to build something that matters?

We solve problems that don't have Stack Overflow answers. Let's talk.

Book a Discovery Call