← Blog
Tutorial7 min read

Why our CSV agent checks your spreadsheet before it answers

By Kushal Sharma

Ask most AI tools to average a column and they will average it. If a third of the values are text, if two rows are the same row, if the dates are in two formats, you will still get a number — formatted confidently to two decimal places. The CSV Analyst is built around refusing to do that.

A table that has been checked, becoming a chart. The flagged cell is the point of the agent, which is why it is the only amber thing in the drawing.

The sample data is broken on purpose

Every agent we build is seeded with a file to work on. The obvious move is to seed a clean one — it demonstrates well, the charts come out nicely, nothing embarrassing happens on camera.

We seed a broken one, and it is the single most useful decision in the whole agent. A correct dataset lets an agent look competent while proving nothing. Anything can average a clean column. So the spreadsheet this agent opens on contains four faults, each chosen because it breaks a different thing:

  • Two date formats in one column. Sorting is now wrong, and every “by month” grouping silently splits.
  • A number stored as text. The column looks numeric. Sum it and you get either an error or, worse, a smaller number.
  • A duplicate row. Counts are inflated by exactly one, which is the hardest kind of wrong to notice.
  • A blank in a numeric column. The mean changes depending on whether the blank counts as zero or as absent, and nobody tells you which one happened.
The profiling pass. Four different faults, marked four different ways — the claim is not that it validates data, it is that it names which thing is wrong with which cell before it puts a number in front of you.

Profile first, answer second

The agent's instructions put one step before everything else: load the file, describe what is actually in it, and say what is wrong before answering anything. Not as a validation step that passes or fails — as a paragraph you read.

In practice its first message on the seeded file is closer to this than to a summary:

1,204 rows, 7 columns. signup_date has two formats (2026-03-04 and 04/03/2026) — I have parsed both but you should know they were mixed. revenue is stored as text in 38 rows because of a currency symbol. Row 412 duplicates row 411 exactly. seats is blank in 9 rows; I have left them out of the average rather than treating them as zero.

Every one of those sentences changes what the next number means. The version of this product that skips them is faster to demo and worse at the job.

It runs real code, and you get the code

This is not a model describing what an analysis would show. The agent has a Linux sandbox with Python and pandas in it, and it writes a script, runs it, and reads the output — the same loop a person would run, with the same failure modes.

Python
import pandas as pd df = pd.read_csv("data/signups.csv") df["revenue"] = pd.to_numeric( df["revenue"].astype(str).str.replace(r"[^0-9.]", "", regex=True), errors="coerce", ) print(df["revenue"].isna().sum(), "rows could not be parsed")

The script stays in your workspace. So does the CSV it wrote, and the chart. You can open them, change them, run them again — and if you disagree with a decision the agent made, the line where it made that decision is right there.

Charts are files, not descriptions

When it plots something, it writes a PNG. That sounds trivial and is the source of one of the more useful rules in the prompt: it opens the image afterwards and looks at it.

A savefig call that exits zero can still produce a chart with overlapping labels, a legend covering the data, or forty thousand categories on the x-axis. Exit code zero means matplotlib did not crash; it does not mean the picture is readable. So the agent views its own output and redraws when what came back is not worth showing you.

What it will not do

The agent page lists the constraints in full, and they are real ones rather than a modesty section. The two worth knowing before you start:

  • It will not guess what a column means. If status contains four values it has not seen before, it asks rather than inventing a taxonomy that looks plausible in a chart.
  • It will not quietly clean your data. Every transformation it applies is named in the answer, because a cleaned dataset with no record of the cleaning is a dataset nobody can check.

Try it on something real

The agent opens with a seeded file so there is something to poke at immediately, but the interesting run is your own export — a spreadsheet, a CSV, a PDF with a table in it. Drop it in and ask a question in plain English.

Open CSV Analyst, or read the series post about why we are building one of these a day — this one found a bug where no app in the product had ever sent its system prompt.