I remember the first time someone on our finance team asked the data warehouse a question in plain English. It was a Tuesday, I think, and the tool cheerfully returned a number that was off by about forty million dollars. Not a great start. The query sounded simple enough: "what were total sales last quarter?" But our database had three different definitions of sales, depending on whether you meant booked, recognized, or invoiced. The natural language layer picked one at random, or whatever the model thought was most likely. It never asked a clarifying question. It just answered.
That was my introduction to the gap between a demo and a production system. In a demo, the questions are clean and the schema is tidy. In the real world, the database has thirty years of accumulated table names like SALESV2FINALUSETHIS and columns that mean different things to different departments. Natural language interfaces are getting good at translation, but translation was never the hard part. The hard part is knowing which translation the user actually wanted.
Since then I've worked on a few of these projects, and the pattern is always the same. The interface works beautifully for the first week, then someone asks a question with the word "active" in it, and nobody can agree what active means. Or they ask for "customers in the northeast" and the model includes New York but not Pennsylvania, because the regional mapping table has an old hierarchy that predates the current sales org. The interface didn't fail technically. It failed contextually.
What I've learned is that natural language interfaces need guardrails that are less about the language and more about the business semantics. You need a layer of definitions that says, when someone says sales, show them the three options and make them pick. When someone says last quarter, clarify whether they mean calendar or fiscal. That sounds obvious, but most teams spend all their time tuning the model's parsing and almost no time building the semantic catalog underneath. I made that mistake early on. I thought if we trained the model on enough queries, it would learn the disambiguation. It didn't. It just got more confident in its wrong answers.
The other thing that surprised me was the permissions problem. A natural language interface doesn't respect row-level security just because the underlying database does. If a user asks "how many employees make over two hundred thousand," the model might generate a query that bypasses the view you carefully built to hide sensitive compensation data. Or it might join tables that the user technically has access to individually but shouldn't be able to combine. We caught that one in a security review, luckily, but it was close. Now I insist that any natural language query gets parsed into SQL, then run through the same permission layer as a human-written query. No exceptions.
I'm not bearish on the technology. It genuinely helps with the long tail of simple requests that never get asked because nobody wants to learn the schema. But I've stopped pitching it as "just talk to your database." That's the demo version. The real version is a constrained, well-governed dialogue where the system knows what it doesn't know and isn't afraid to ask. And that takes a lot more than a good language model. It takes the same unglamorous work we've been doing for decades: defining terms, mapping tables, and enforcing permissions. The interface just makes all that work visible in a new way.