Flagship · 2024 – present · SynergyBoat

DeepQuery, plain-English access to your databases

Teams sit on databases their non-technical people cannot query. We built DeepQuery for one client's operations team: it discovers a schema and answers plain-English questions across Postgres, MySQL, and Mongo. It runs their reporting in production, and SynergyBoat is now making it a product other clients can point at their own databases.

The problem

A client’s non-technical operations team needed to answer business questions that lived across three databases: PostgreSQL for users and billing, MySQL for a legacy product system, and MongoDB for event logs. Every question cost an engineer’s day. Their founder needed that engineer back.

The obvious answer, train operators to write SQL, had failed twice before. The subtle answer was what we built: a text-to-SQL engine that was actually trustworthy across three dialects.

What shipped

A text-to-SQL engine that auto-discovers schemas across all three databases, classifies user intent against a small catalogue of query shapes, resolves ambiguous values (e.g., “last week” vs. an ISO date range), and generates optimized queries that stay inside an 8K-token context budget (Figure 1).

Live in production for that client. Their operators run their own reports, and the engineers they used to interrupt got those hours back. SynergyBoat is now turning the engine into a product other clients can point at their own databases.

Tokens are money and correctness simultaneously.

How it works

Four stages. Intent classification maps a natural-language request to a small set of query shapes: analytics-style aggregates, lookup by entity, time-series comparisons, or “I don’t know, ask me more.” Schema retrieval uses pre-computed digests so the prompt never carries a full schema dump. Value resolution handles ambiguity before the model generates, so "customers from last month" becomes concrete dates and "premium users" becomes a resolved filter. Query generation happens last, with the context budget enforced upstream so the model never has to decide what to drop.

The key insight: every stage is a budgeting decision. Tokens are money and correctness simultaneously. Designing for the budget first made everything downstream simpler.

What I’d do differently

Caching the schema digests earlier would have saved weeks. The first version hit the databases on every query; observability eventually made it obvious, but the fix was a one-afternoon change that should have been there from day one.

Intent classification was also too ambitious early. The first version tried to handle open-ended requests; the working version has a clear “ask me more” branch that punts when confidence is low. That branch is the single biggest accuracy improvement we made.

The DeepQuery context budget A question typed in plain English, customers from last month, enters at the top, asked by the operations team rather than by an engineer. Intent classification maps it to a small set of query shapes: analytics-style aggregates, lookup by entity, time-series comparisons, or ask me more, which punts when confidence is low. Schema retrieval feeds the context with pre-computed digests, discovered across all three databases, so the prompt never carries a full schema dump. Value resolution turns last month into concrete dates and premium users into a resolved filter, before the model generates. Below them a context budget bar fills toward an 8K-token ceiling, drawn as a hard line, and stops short of it. The budget is enforced upstream, so the model never has to decide what to drop. Query generation runs last: the model is called only after the budget stops. The query then routes to the matching database: PostgreSQL for users and billing, MySQL for a legacy product system, and MongoDB for event logs. The route drawn here reaches PostgreSQL, which holds users and billing. question, in plain english customers from last month a sentence from the operations team, not a chat box from the operations team intent classification a small set of query shapes aggregate, lookup by entity, time-series, or ask me more, which punts when confidence is low schema retrieval pre-computed digests discovered across all three databases, never a full dump value resolution before the model generates last month becomes dates, premium users becomes a filter every stage puts something in the context before the model is called context budget 8k tokens ceiling stops here stays inside enforced upstream, so the model never decides what to drop the fill stops short of the ceiling, and the gap is measured query generation the model is called here last, after the budget has already stopped routes to the matching database postgresql users and billing mysql legacy product system mongodb event logs the query goes down the one database that holds what was asked
part what it does
question Plain English, from the operations team rather than an engineer. The one drawn is customers from last month.
intent classification Maps the request to a small set of query shapes: analytics-style aggregates, lookup by entity, time-series comparisons, or ask me more.
ask me more The branch that punts when confidence is low.
schema retrieval Pre-computed digests, discovered across all three databases, so the prompt never carries a full schema dump.
value resolution Resolves ambiguity before the model generates: last month becomes concrete dates, premium users becomes a resolved filter.
context budget The ceiling is 8K tokens. The context fills toward it and stops short, enforced upstream, so the model never has to decide what to drop.
query generation Runs last. The model is called only after the budget stops.
postgresql Users and billing. The query drawn here routes here.
mysql A legacy product system.
mongodb Event logs.
Fig. 1. The context budget. A question is classified, the schema is discovered, and the context fills toward an 8K-token ceiling and stops before the model is called. The query then routes to the matching database. Drawn for DeepQuery only. Nothing on this page reuses it.