automated-data-analyst

agent
Security Audit
Pass
Health Pass
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 34 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

The math arm for LLMs: compute and check numbers from CSV and Excel data with pandas, SciPy and statsmodels, each with its calculation. Tool calling for Claude, Codex and local models (Ollama, vLLM, llama.cpp, LM Studio), Kaggle-style AutoML with --explain, and paper tables and figures.

README.md

ADA: the math arm for LLMs

CI
PyPI
Python
License: MIT
Stars
Agent skill: Claude Code and Codex
Tool calling: Ollama, vLLM, llama.cpp, LM Studio
MCP server

⭐ Star ADA if it saves you an afternoon · Try it in the browser · Docs · What's new in 0.7.0
Read this in 中文 · 日本語 · 한국어 · Español · Português · Deutsch · Français · Русский

ADA (Automated Data Analyst) is the part of a language model that does the
math. Point it at CSV or Excel data and ask in plain words: it computes the
answer with pandas, SciPy and statsmodels and returns the number with its
calculation and the rows behind it, or refuses with the reason. It checks
numbers stated about the data too: verified, or unverified with the reason
and the one question that would settle it.

A model never has to do arithmetic in its head again. That helps Claude and
Codex, and it helps open-source models most: a small local model run with
Ollama, llama.cpp, vLLM or LM Studio only has to pick the tool and read the
answer. ADA is a Python package, a command line and a set of tool
definitions any model with function calling can use.

pip install automated-data-analyst     # Python 3.11 or newer

Give a language model a math arm

Chat with a local model. With Ollama running:

ollama pull qwen3:1.7b       # any model with tool calling works
ada chat penguins.csv        # ask in plain words; the model asks ADA for every number
$ ada chat penguins.csv
ADA chat: qwen3:1.7b at http://localhost:11434/v1, reading penguins.csv. Ask about the data; Ctrl-D or 'exit' leaves.
> Which species has the longest bills on average?
  ADA ada_ask(path="penguins.csv", question="average bill_length_mm by species")
    -> answered: Chinstrap has the highest average bill_length_mm of any species, at 48.83 (n = 68). The species groups do differ (Welch ANOVA, p < 0.001; η² = 0.71). Based on the 342 rows with bill_length_mm recorded, of 344 rows. Each: Chinstrap 48.83; Gentoo 47.50; Adelie 38.79.
The species with the longest average bill length is **Chinstrap**, with an average of **48.83 mm** (n = 68). This result is based on the mean calculation of `bill_length_mm` grouped by species, sorted in descending order. The data spans 342 rows, and the values are as follows:
- **Chinstrap**: 48.83 mm
- **Gentoo**: 47.50 mm
- **Adelie**: 38.79 mm

The p-value indicates significant differences between species (p < 0.001), confirming the observed trends.

The model, 1.4 GB on four processor cores with no GPU, picked the tool; ADA
computed every number and showed how. Each tool call and its result are
printed above the answer.

Add ADA to an app that takes MCP servers: LM Studio, Jan, Claude Desktop,
Cursor, VS Code, Cline and others. Put this in its mcp.json:

{"mcpServers": {"ada": {"command": "uvx", "args": ["--from", "automated-data-analyst", "ada", "mcp"]}}}

For Open WebUI, run ada mcp --http and add http://127.0.0.1:8000/mcp as
an MCP (Streamable HTTP) server under External Tools.

In your own code, ada.chat.chat(question, "penguins.csv", model=...)
runs the whole loop, or give the model tools.definitions() and run its
calls with tools.run:

from ada import tools

tools.definitions()                    # four tools for function calling: ask, check a claim, scan, model
tools.run("ada_check_claim", {"path": "flights.csv", "claim": "The average departure delay was about 13 minutes."})

ADA as the math tool of a language model has the setup
for each app, which local models work, a loop with the Anthropic API and
what comes back.

Check a number

$ ada claim flights.csv "The average departure delay was about 13 minutes."
verified: The average departure delay was about 13 minutes.
  12.63907026 (328,521 rows) from mean(dep_delay) lies in 12 to 14, which about 13 minutes stands for.
  calc: mean(dep_delay)
  assumes: Read "departure delay" as dep_delay.
  assumes: Left out 8,255 rows with dep_delay missing.
  assumes: Read "about" as 12 to 14.
  assumes: The unit "minutes" comes from the claim; the check compares numbers only.

$ ada claim flights.csv "The average delay was 13 minutes."
unverified: The average delay was 13 minutes.
  The claim's words fit more than one column, and they give different answers: dep_delay gives 12.63907026; arr_delay gives 6.895376757.
  to check it: Which column is meant: dep_delay or arr_delay?

verified means this number, from these rows, by this calculation, with the
assumptions listed. unverified is not false: only the reason failed_check
says the data give a different number. --json gives the whole record, and
ada.check_claim(...) does the same in Python. See
Checking claims for the reasons, intervals and units.

Compute an answer, or map a folder

ada scan lahman/ --template answers.yml      # the files, how they join, the questions to ask first
ada ask flights.csv "average dep_delay by origin" --json   # the numbers, the calculation, the rows used
ada claim lahman/ "Barry Bonds hit 73 home runs in 2001." --answers answers.yml

ada scan asks what the analysis should find out, what a row is, and each
choice ADA would otherwise make by default, with its proposed answer; ada ask and ada claim take the edited file. When an answer rests on a choice,
such as leaving World and region rows out of an average, it says which, and
--decide picks the other (Decisions). A
question or claim about a folder is answered from the file it fits, or from
two files joined along a link ADA is sure of. A question ADA can't answer
comes back refused, with the reason. See Ask ADA
and Reading a folder of tables.

Before it answers, ADA reports the rows it left out and why, counts each
subject once when several rows come from one, says when groups reverse a
pooled figure, adds up the count column of a table of counts, and gives a
reason instead of a number when the data are too thin.

Use it from Claude Code or Codex

ada skill               # .claude/skills/ada (Claude Code) and .agents/skills/ada (Codex)
ada skill --user        # the same in your home folder, for every project

It also installs as a plugin (how).
The skill has the assistant let ADA do the
arithmetic, check every number it states with ada claim, and ask you ADA's
question instead of choosing a reading.

Paper assets for a study

ada demo mice && cd mice           # an example study to try first
ada init data/measurements.csv     # asks about the study; writes study.yml
ada build                          # writes paper-assets/
ada verify                         # rebuilds and compares every number

ada build makes a data audit, a data dictionary, a record of every
exclusion, results tables in Word, LaTeX and CSV, figures with captions and a
methods draft. See Paper assets for a study. ada analyze
gives a first look at any table, and ada app opens the same in a browser
(pip install "automated-data-analyst[app]").

Predict a column

pip install "automated-data-analyst[model]"
ada model titanic/ --metric accuracy --out submission.csv

ada model predicts one column of a table from the others, as a tabular
Kaggle competition asks. The features come from rules on the columns' shapes,
LightGBM, XGBoost and a linear model are blended on out-of-fold predictions,
every score is cross-validated, and the submission is checked before it is
written. See Predicting a column.

ada auto does the same with a wider search and takes longer: CatBoost,
LightGBM with random split points, extremely randomized trees and a neural
network join the blend, a second layer is fitted on their out-of-fold predictions, and the
weights come from greedy selection. Each step stays only when the folds say it
helps. --jobs N fits N learners at once and gives the same model.

--explain predicts with a model a person can read instead, a linear or an
additive one, with its coefficients and 95% intervals, each column's effect
curve, and what explaining costs against the full search, fold by fold.

It is scored on Kaggle competitions with no code for any one of them: the
runner passes ADA the competition's folder and the name of its metric, and
ADA does the rest. Each competition is also split inside itself, the way its
test is made, so a change is measured on all 22 without a submission. On the 22 scored so far, with ada auto where it was
run, it places in the top 10% on 2 (Titanic, and Housing Prices on Kaggle
Learn, at 2%), in the top 15% on 6 and in the top 30% on 13. Store Sales, a
forecast of 1,782 series, is its weakest, at 58%.
Every score.

What it doesn't do yet

Numbers that need three files joined, many phrasings ("horsepower" for hp,
slopes, several numbers in one claim), and some year columns read as numbers
rather than dates. These come back unverified or refused with a
reason. See Not covered yet.

Progress

73 cases on 20 public datasets, each expected value computed separately with
pandas, SciPy and statsmodels; a fifth of each dataset's cases are holdout
cases, only scored (details).

ADA 0.5.0 Now
Dev cases 9/58 50/58
Holdout cases 0/15 14/15
Wrong verdicts on claims 0/35
True claims verified 0/25 23/25
False claims caught 0/7 6/7

Each change is also scored on rounds of new public data, six datasets at a
time from statistics offices, city portals and research projects, with claims
written as reports write them; the pull request gives the scores.

More

All documentation · Contributing ·
Credits · Citing · MIT License

Reviews (0)

No results found