AppliedAIPrep logoAppliedAI/Prep
System Design for AI in Production / 06

Design a text-to-SQL feature: let users ask questions in natural language over a real database.

Text-to-SQL is deceptively hard because correctness is binary and the failure mode is a confident wrong number. The signal is schema grounding, query validation, and a safety layer, not just 'prompt an LLM with the schema.' Here is the production design.

Updated Aug 2026 · Grounded in real Applied AI Engineer interview loops and written to a senior-engineer editorial bar.

TL;DR: Ground the model in the schema (for large databases, retrieve only the relevant tables and columns), generate SQL, then validate before executing: parse it, check it against the schema, enforce read-only plus row and cost limits, and run on a replica. Handle ambiguity by asking a clarifying question or showing the SQL for confirmation, and evaluate with execution accuracy on a labeled set, not string match. The danger is a plausible query that returns a wrong number silently, so verification matters more than raw generation.

GUARDRAILS (send an input through the layers)
prompt injection
input filter
model
output filter
output
Guardrails wrap the non-deterministic model in deterministic checks. Send each input type and watch where it is stopped. A prompt injection should be caught; toggle off the layer that catches it and watch it slip through.

How to approach it. Stress what separates this from generic generation: SQL is executable and correctness is unforgiving, so a wrong-but-runnable query yields a confident wrong answer that nobody catches. Lay out the pipeline (ground, generate, validate, execute, present) and put the weight on safety and evaluation, since that is where the round is won.

A strong answer.

rendering diagram…
  • Schema grounding. The model needs the schema to write correct SQL. For a small database, put the full schema (tables, columns, types, a few sample rows, key relationships) in the prompt. For a warehouse with thousands of tables that does not fit and actively hurts accuracy, so retrieve the relevant tables and columns (embed schema and column descriptions, match against the question) and ground on those. Column descriptions and example values markedly improve correctness.
  • Generation. Prompt with the grounded schema, the SQL dialect, and few-shot question-to-SQL examples for this database. Constrained or structured decoding helps validity.
  • Validation before execution, the safety core. Parse the SQL, confirm every referenced table and column exists (catch hallucinated columns), and enforce read-only (reject INSERT, UPDATE, DELETE, DDL), a row LIMIT, and a query timeout or cost guard so a generated cross-join cannot melt the warehouse. Run on a read replica with a least-privilege account.
  • Ambiguity and trust. Natural language is ambiguous: "top customers" by revenue or by count? Either ask a clarifying question or, better, show the generated SQL and the assumptions so the user can confirm, correct, and iterate. Surfacing the query is the single biggest trust lever, because users catch a wrong interpretation before they believe the number.
  • Evaluation. Build a labeled set of (question, correct SQL or result) pairs and measure execution accuracy: does the generated query return the right result. String match fails, because many distinct SQL strings are semantically equivalent. Track accuracy per schema and gate changes on it.

The honest framing: the risk is not a crash, it is a runnable query that quietly returns the wrong answer, so the design centers on grounding, validation, and making the SQL visible and verifiable.

Key takeaways

  • The failure mode is a confident wrong number, not an error, so verification beats raw generation quality.
  • Retrieve only the relevant tables for large schemas; dumping thousands of tables hurts both accuracy and cost.
  • Treat validation as a hard gate: parse, schema-check, read-only, LIMIT, timeout, replica, least-privilege.
  • Measure execution accuracy on labeled pairs, never string match, and show users the SQL to build trust.

What interviewers probe next.

  • "Schema too big for the prompt?" Retrieve relevant tables via embeddings over schema and column descriptions, and ground only on what the question needs.
  • "How do you stop a destructive or runaway query?" Read-only account, parse-and-reject writes and DDL, enforce LIMIT and timeouts, execute on a replica.
  • "Evaluate correctness?" Execution accuracy against gold results on a labeled set. String matching fails because equivalent queries differ textually.
  • "Joins and ambiguity?" Provide foreign-key relationships and column semantics in grounding. For ambiguous asks, clarify or show SQL for confirmation.
  • "Few-shot vs fine-tune?" Start with schema-grounded few-shot. Fine-tune on your dialect and schema only if accuracy plateaus.

Common mistakes.

  • Dumping a giant schema into the prompt for a large database, hurting accuracy and cost, instead of retrieving the relevant subset.
  • Executing generated SQL without validation, read-only enforcement, or limits.
  • Hiding the SQL, so users cannot catch a misinterpretation before trusting the number.
  • Evaluating with string match instead of execution accuracy.
HOW DID IT GO?
0
UP NEXT ON YOUR JOURNEY
DISCUSSION · 0

No comments yet — be the first to share your approach.