Inspiration

Every team that's ever opened a CSV export knows this feeling: broken headers, mixed date formats, a column that's supposed to be numbers but has a stray text value hiding in row 847. What should be a five-minute question — "what's our total revenue by region?" — turns into either a fight with spreadsheet formulas or a message to an analyst who won't get to it until tomorrow.

We wanted to build something that closed that gap entirely: type your question in plain English, and get back not just an answer, but the actual code that produced it — so nothing is a black box, and nothing requires you to already know pandas.

What it does

CSV Whisperer lets you upload a messy CSV or Excel file and ask questions about it conversationally. Behind the scenes, GPT-5.6 reads the file's schema and writes a real, working pandas script tailored to your exact question — not a canned template. That code runs inside an isolated sandbox, and the result comes back alongside the code itself, so you can see exactly how the answer was produced. If the generated code fails for any reason, GPT-5.6 sees the actual error and rewrites the fix automatically, retrying until it succeeds or gracefully reporting back — no human debugging required. Every result can be downloaded as a clean CSV, and you can keep refining the analysis conversationally.

How we built it

We built the entire backend inside Codex, working through it as a single continuous session, one deliberate step at a time rather than one giant unscoped request: scaffolding, file upload and schema parsing, the GPT-5.6 integration, the self-correction retry loop, the execution sandbox, download, and session cleanup — each step tested and confirmed working before we moved to the next.

The frontend is a Next.js interface with three panels — chat, result table, and a live code viewer — so the model's work is always visible, never hidden.

One of the most important architectural decisions was isolating the LLM call behind a single function interface. That let us develop and test the entire pipeline early using a free-tier model, then swap in GPT-5.6 for the final build with a one-line configuration change instead of touching the rest of the codebase.

Challenges we ran into

The sandbox. Since GPT-5.6 is writing real, executable code that runs on our server for every single query, we couldn't treat this as an afterthought. We built a two-layer defense: a static AST-based check that rejects dangerous imports and calls before anything runs, plus isolated subprocess execution with a hard timeout. We tested it against a real os.system attempt and a deliberate infinite loop to confirm both were actually caught — not just logically sound.

A silent correctness bug. Early on, our grouped query results were returning numbers with no labels — a total with no region attached to it. It turned out pandas was dropping the group labels during JSON serialization because they lived in the DataFrame's index, not as a column. It was a subtle bug that would have quietly undermined trust in every single answer if we hadn't caught it.

Moving targets on the free-tier model. During development, we hit three consecutive provider-side errors in a row — a model deprecated for new accounts, then its replacement also deprecated mid-week, then a quota mismatch on a paid-only model we'd accidentally been pointed at. Debugging across a live, shifting third-party API taught us to keep our LLM integration cleanly isolated and easy to swap — which paid off directly when it came time to move to GPT-5.6 for submission.

Environment friction. Moving our backend folder into the main project repository partway through broke our editor's workspace path, and a mid-project Windows port conflict took some real troubleshooting to track down. Small things, but real ones — the kind that don't show up in a spec but eat a afternoon regardless.

What we learned

That trust in an AI-generated answer isn't really about the answer — it's about being able to see the work. Showing the code alongside the result turned out to be the single most important product decision we made, more than any UI polish. We also learned, very concretely, how much a well-designed sandbox matters the moment you let a model write and run its own code — this isn't optional hardening, it's core to the product's integrity.

What's next

Expanding beyond pandas-shaped analysis toward light visualization suggestions, supporting larger files with chunked processing, and persisting sessions so a user's analysis history survives a page refresh.

Built With

Share this project:

Updates