Answer questions with SQL
Let people ask questions of a database in plain language. The model writes a query; your code runs it safely; the model explains the result.
Safety first
- Connect with a read-only database user limited to the schemas you expose.
- Set a statement timeout (for example 10 seconds) and a row limit.
- Run queries on a replica, not the primary.
- Never let the model’s SQL reach the database without these limits; prompts are not access control.
Give the model the schema
Send table and column names, types, and one-line descriptions of what each column means, inside <schema> tags. Include 3 to 5 example questions with correct queries. For large schemas, select relevant tables first with a cheap classification call or embeddings.
Use a tool
Define one strict tool:
{"type": "function", "function": {"name": "run_sql", "strict": true,
"description": "Run one read-only SQL SELECT against the analytics database. Returns at most 200 rows.",
"parameters": {"type": "object", "additionalProperties": false, "required": ["sql"],
"properties": {"sql": {"type": "string", "description": "A single SELECT statement. No semicolons, no DDL or DML."}}}}}Check in code that the statement is a single SELECT before running it. Return errors to the model as tool results so it can fix the query.
Explain, do not just answer
Ask for the answer plus the query used and any assumptions (“I counted only paid orders”). People trust numbers they can check.
Evaluate
Build a dataset of questions with known correct answers, and grade by comparing the result rows, not the SQL text: different queries can be equally right.