AI should be a dumb renderer
Most AI insights features hand a pile of data to a model and ask it to do the maths. Models are bad at maths and very good at writing. Do the sums in code first, then let the model explain what they say.
You can’t trust a language model to add up a column of numbers. You can trust it to explain a sum that something else already worked out. Almost everything about building a decent AI insights feature falls out of taking both of those seriously at the same time.
The usual approach does the opposite. It takes a table, pastes it into the context window, and asks the model to count the rows, compare the segments and say what changed. That’s a CSV in ChatGPT with a product wrapped around it. It demos well, and it falls over the first time a stakeholder checks a number against the source, because the model was producing text that looks like the result of counting rather than counting.
The boundary is the product
Draw a line through the middle of the system. On one side is everything with a single correct answer: the aggregations, the group-bys, the deltas, the percentages, the ranking, the “this is up 12% on last quarter”. On the other side is everything that’s a judgement call about language: which of those facts matters, how to phrase it, what to lead with, how to turn three numbers into a sentence someone will act on.
The first side is arithmetic. You write it in SQL or pandas, you test it, it gives the same answer every time, and when someone questions a figure you can show them the query. The second side is writing. You hand the model facts that are already settled and ask it to narrate them. It’s very good at that, better than any deterministic system, and it can’t invent a number it was never given.
That line is the whole architecture. Everything to the left is auditable, everything to the right is generated, and most broken AI features have put arithmetic on the right.
What this looks like in practice
Take an analytics feature built on that split. Every claim it makes is clickable: click “revenue rose 18% last quarter” and you land on the 340 orders that figure came from. You can only make that promise because the claim was calculated before the model saw it. The model receives a structured object that already says revenue rose 18% across these 340 orders, and its job is to turn that into a readable sentence with some context around it. It can’t quietly say 19%, because it never had the orders. It had a fact with a fixed shape.
I ran into the same boundary from the other side at Lyssna, working on AI analysis of user-research studies. With a pile of interview transcripts, the tempting move is to throw the lot at a model and ask what we learned. What comes back reads like a synthesis and is impossible to defend, because you can’t trace any sentence back to the moment a participant said the thing. The work that mattered happened before the model: coding responses, tagging themes, counting how many participants hit a given problem. Once those counts exist, a model writing “seven of twelve participants stalled at the pricing step” is just reporting, and a researcher can click through to all seven. Skip the counting and that same sentence is a guess that happens to sound specific.
Why this is the order that scales
The deterministic side scales because it’s ordinary software. You can cache it, test it, run it cheaply, and it won’t start behaving differently when the model version changes underneath you. The generative side scales because there’s less that can go wrong and the things that do go wrong are recoverable. A clumsy sentence costs you very little. A wrong total costs you the account.
Do it the other way round and you get the worst of both. You’re paying model latency and token costs to do work a database does for free, the answers change between runs, and you can’t prove any of them. The errors are also confident and well-written, which is the part that makes them dangerous. A wrong number in a badly written email gets queried. A wrong number in a polished executive summary gets forwarded.
This matters beyond any one product, because “AI insights” is turning into a default feature request and the default implementation is the broken one. The fix is moving the boundary rather than reaching for a better model or a longer prompt. Work out every fact before the model sees it, then let the model do the thing it’s better at than your codebase, which is putting those facts into language someone will believe.
Whether people trust the output depends on where you drew that line, and hardly at all on the model you picked.