How We Turn Raw Data into Charts Without Letting AI Lie to You

Building a system where an AI describes charts but never touches the numbers, ensuring accuracy while keeping the process fast and secure.

3 min read

How We Turn Raw Data into Charts Without Letting AI Lie to You cover

Data is only useful if someone actually looks at it. Too often, teams collect metrics, logs, and activity records, then let them sit untouched in a database. That’s not data. That’s a digital graveyard. At LiveReview, we built a system to change that. We call it Livi, a chat bot that answers real questions about engineering activity with real charts, not vague guesses or paragraphs of corporate-speak.

The wrong way to generate charts with AI

The obvious approach is tempting. Feed a question to an LLM, let it generate an image of a chart, and call it a day. That’s a terrible idea. Image models don’t understand numbers. They hallucinate. You’d end up with a bar chart that looks correct but shows made-up values. A chart like that isn’t a tool. It’s fiction.

We took a different path. Instead of asking the LLM to draw, we ask it to describe. The model writes Vega-Lite, a JSON format for defining charts. It specifies what the data represents and how it should be visualized, but it never touches the actual numbers. Vega-Lite handles the rendering. The LLM’s job is to pick the right chart type, not to invent data.

How the pipeline actually works

When someone asks Livi a question, the system doesn’t jump straight to generating a chart. First, it figures out how much data the answer will involve. If the result is too large, it returns a CSV instead of a chart. Nobody wants a bar chart with thousands of bars.

  • The LLM writes a preliminary SQL query to estimate the size of the result set.

  • If the data is manageable, it writes a second query to fetch the actual data and describe the chart.

  • A guard checks every query to block anything that isn’t read-only or could expose sensitive data.

  • The LLM only sees a narrow slice of the database schema, not the entire thing, to avoid confusion and wasted tokens.

This two-step process might seem redundant, but it solves real problems. The guard prevents security issues, like a query that accidentally exposes one team’s data to another. The schema filtering keeps the LLM focused. Our database has over fifty tables. Dumping all of them into every prompt would waste tokens and confuse the model.

Keeping the LLM on track with dbctx

Not every question needs the entire database schema. If someone asks about review counts, the LLM doesn’t need to know about billing tables. We built dbctx, a Go library, to handle this. It takes a natural-language question and a Postgres connection, then returns only the relevant tables and columns. The output is compact and formatted for the LLM, not a raw schema dump.

Dbctx doesn’t use generative AI. It relies on deterministic introspection and heuristics to figure out which parts of the schema matter. It also includes optional features, like semantic embeddings, to improve relevance. The goal is simple: give the LLM what it needs, nothing more.

Why this approach works

The key is separation of concerns. The LLM decides how to present the data. Vega-Lite renders it. The database provides the numbers. Each part does one thing well. The LLM never sees raw data, so it can’t invent or misrepresent it. The guard ensures security. The schema filtering keeps prompts efficient.

This system isn’t just about charts. It’s about trust. When an engineering leader asks a question, they get an answer backed by real data, not an AI’s best guess. That’s the difference between a tool that sits unused and one that actually helps teams make decisions.

What we learned along the way

  • LLMs are good at describing charts but terrible at drawing them. Keep them in their lane.

  • Security isn’t optional. A single bad query can expose sensitive data. Guardrails are non-negotiable.

  • Schema filtering isn’t just about efficiency. It also prevents the LLM from getting distracted or confused.

  • Two-step queries sound slow, but they save time by avoiding bad outputs and wasted renders.

Building Livi taught us that AI can be practical without being reckless. The trick is to use it for what it’s good at and nothing else. Describe, don’t hallucinate. Filter, don’t dump. Guard, don’t hope. Do that, and you end up with a system that’s both powerful and trustworthy.

Join the newsletter

Be the first to read our articles.

How We Turn Raw Data into Charts Without Letting AI Lie to You | Muhammad Adil