Building AI agents to query your databases
blog.dust.tt
blog.dust.tt
Cursed mission. These sorts of things do work amazingly well for toy problem domains. But, once you get into more complex business involving 4-way+ joins, things go sideways fast.
I think it might be possible to have a human in the loop during the SQL authoring phase, but there's no way you can do it clean without outside interaction in all cases.
95% correct might sound amazing at first, but it might as well be 0% in practice. You need to be perfectly correct when working with data in bulk with SQL operations.
The tricky part is correctly supporting multiple systems which each have their own specificity. All the way to Salesforce which is an entirely different beast in terms of query language. We're working on it right now and will likely follow-up with a blog post there :+1:
--- start quote ---
prompt engineering is nothing but an attempt to reverse-engineer a non-deterministic black box for which any of the parameters below are unknown:
- training set
- weights
- constraints on the model
- layers between you and the model that transform both your input and the model's output that can change at any time
- availability of compute for your specific query
- and definitely some more details I haven't thought of
https://dmitriid.com/prompting-llms-is-not-engineering
--- end quote ---
This is the crux. Sure, for high level software (e.g. Web apps), many parts of the system will feel like black boxes, but low-level software does not generally have this problem. Sure, sometimes you have to deal with a binary blob driver, but more often than not you're in control of or and to debug most all of the software running on your system.
> Building a bridge
There should NOT be significant unknowns when you're building a bridge, this is how people die. You turn those parameters into "knowns with high confidence", which is not something you can even begin to do for the LLM parameters described above.
In absolutely every way that matters and in all the details that don't matter.
> Do you know everything in advance about the composition of terrain, the traffic, the wind and the earthquakes?
No, and there are established procedures and ways to establish those facts.
"This magical incantation that I pretend works better because the US is asleep and more compute is available" is not such a procedure.
For complex queries/use-cases, we generally instead push our users to create agents that assist them in shaping SQL directly, instead of going directly from text to result/graphs. Pushes them to think more about correctness while still saving them tone of time (the agent has access to the table schemas etc...), but not a good fit for non technical people of course.
It solves 100% cases where some manager requests dashboard never to look at it again after one day.
> It solves 100% cases where some manager requests dashboard never to look at it again after one day.
Better than having engineers build it for days (for the same result).
With a semantic layer, you get the added benefit of writing queries in JSON instead of raw SQL. LLM's are much more consistent at writing a small JSON vs. hundreds of lines of SQL.
We[0] use cube[1] for this. It's the best open source semantic layer, but there's a couple closed source options too.
Another alternative here is Veezoo [0], which combines the semantic layer (a Knowledge Graph) and self-service analytics into one integrated solution.
We built it specifically for the analytics use-case for both the "data persona" to manage the semantic layer, as well as for the "business persona" to analyze the data.
If you’re looking for a semantic-layer + (embedded) BI solution right out of the box. This could be a fit.
We use a pattern where we ETL things into tables that model the upstream source closely, then use SQL Views to tighten up the model and integrate across data sources where needed. Keeping this all inside one DB allows us to use tools that understand the schema for autocomplete, etc.
I expect the developer experience would be significantly worse if we started writing views in YAML instead of SQL… but you’ve found the opposite?
A semantic layer is the best way to enable self-serve analytics, but if you don't care about it, it's probably not worth the hassle.
We also use the semantic layer for other nice things like setting goals, column descriptions and other metadata.
My schema is - 90+ Tables, 2500+ Columns, well documented
From your experience, does Cube look a fit? My use cases will definitely have JOINS.
with that many tables, you might want to use Views: https://cube.dev/docs/reference/data-model/view
In my use case, it's going to be exposed to various kind of stakeholders and there will be versatility of user queries. I can't pre-create views/aggregations for all scenarios.
1. Get a .dot file of the database. Many tools will export this. 2. Open the .dot in a tool I built for the purpose. 3. Select the tables I'm interested in, and export a subset of the .dot file representing just those tables and relationships. 4. Hand that subset .dot file to the LLM and say, "given this schema, write a query -- here's what I want: <rest of the request here>"
That gets the job done 60% of the time. Sometimes when there's an incorrect shortcut relationship resulting in the wrong join I'll have to redirect with something like, "You need to go through <table list> to relate <table X> to <table Y>" That gets my success rate up above 95%. I'm not doing ridiculous queries, but I am doing recursive aggregations successfully.
Some comments on this thread mention popular semantic layer tools like cube.dev. I also made an open source one that I use regularly, though it's currently in I-hope-to-put-more-time-into-this-someday mode. Been busy with an acquisition this year.
We spin up a data lake and pipelines (we support 500+ integrations / connectors) to populate the data lake for you then put DuckDB on top as a single query engine to access all your data.
Our main requirement was querying recent operational data across daily/weekly/monthly/quarterly timeframes. The data sources included OLTP binlogs, OLAP views, SFDC, and about 15 other marketing platforms. We implemented a datalake with our own query and archival layers. This approach worked well for queries like "conversion rate per channel this quarter" where we needed broad data coverage (all 17 integrations) but manageable depth (reasonable row scanned).
This architecture also enabled quick solutions for additional use cases, like on-the-fly SFDC data enrichment that our analytics team could handle independently. Later, I learned the team integrated LLMs as they began dumping OLAP views inside the datalake for different query types, and eventually replaced our original query layer with DuckDB.
I believe approaches like these (what I had done as in house solution and what definite may be doing more extensively) are data and query-pattern focused first. While it might initially seem like overkill, this approach can withstand organizational complexity challenges - with LLMs serving primarily as an interpretation layer. From skimming the Dustt blog, their approach is refreshing, though it seems their product was built primarily for LLM integration rather than focusing first on data management and scale. They likely have internal mechanisms to handle various use cases that weren't detailed in the blog.
Some large enterprises won't allow their data to leave e.g. their own Snowflake warehouse. All tooling they use has to run on top of their warehouse.
MindRoot: https://github.com/runvnc/mindroot
Demo of agent using it to update a database after doing research: https://www.youtube.com/watch?v=nXwwSj0KSXI
If you give it the actual database password it will use a Postgres client to get the actual information_schema and put it in the system message. It uses the normal Supabase library for everything else.
2. Investing in good data models and documentating the edge cases. Also learning from explicit feedback is powerful.
This helps our customers at getdot.ai get highly reliable results.
The models also got a lot better at making sense of weird and complex data models in the last months.
"Validating the query to ensure it's safe and well-formed" all I can say to that is "ROFL. LMAO."
"AI Bot, summarize the number of logins this week broken down by email address and password hash".
They host a repo with lots of what they call "reference" implementations, including this one for postgres which naively takes a query from a request and shoves it at your database with no validation, escaping, anything: https://github.com/modelcontextprotocol/servers/blob/7d6cdb6...
There's an issue calling this out, and it's been labeled a bug, but still.
When you go to their documentation, the only example of actually building a server is this section where they just...use an LLM to build it. Here's their prompt:
> Build an MCP server that: - Connects to my company's PostgreSQL database - Exposes table schemas as resources - Provides tools for running read-only SQL queries - Includes prompts for common data analysis tasks
So, I think there's a fairly high chance that all of the "reference implementations" they're hosting are AI generated with basically no security considerations or code reviews made.