A local SQL assistant still needs guardrails
Here's the rule I'd start with: make the database enforce the boundary the prompt only describes. If a local SQL assistant can execute anything its connection string permits, the fact that the model lives on your own hardware bought you nothing on the safety side. Privacy and operational safety are two separate properties, and running inference locally only answers the first one.
That distinction gets lost fast in practice. Somebody gets the model talking to a real analytics database, the demo looks good, and the credential attached to it quietly turns out to be a full read-write account because nobody wanted to debug permission errors during the prototype phase. Nobody revisits that decision once the thing works.
same box, three jobs, three different appetites for risk
A single machine can host a private chat used a couple of times an hour, a coding loop, and a nightly extraction job, and treating them as one workload is the first mistake. Each has a different blast radius if the model gets something wrong. A chat session that hallucinates is embarrassing; a SQL assistant that hallucinates against production data can delete rows, lock a table during business hours, or return a confident, wrong number that ends up in a report someone trusts. The coding loop usually sits in between, since tests catch a fair share of its nonsense before anyone ships.
So before any of that gets automated, I want read-only credentials, schema metadata handed to the model instead of discovered live, a statement parser sitting between the model's output and the database, a hard cap on query cost, and a plan preview for anything that isn't trivially cheap. None of that is exotic. It's the same instinct behind sandboxing a coding agent: you don't trust the thing to self-limit, you build a fence it can't climb no matter what it claims it's doing.
Worth logging alongside every query: how the system degraded when it failed, not just whether it did. A model that quietly falls back to a lower-effort mode, or a queue that keeps serving requests from a session nobody's watching anymore, doesn't throw an error. It just changes what you're actually getting, and generating SQL from a prompt is exactly the kind of workload where a silent downgrade looks identical to a correct answer until someone checks the number by hand.
the failure that never raises an exception
A boundary the model can talk its way around was never really a boundary.
This is the part I'd flag hardest: the tempting mistake is treating "runs locally" as a synonym for "safe to point at anything," and it survives because the output still reads as fluent, plausible SQL. A query that's wrong looks exactly like a query that's right, right up until someone acts on it. Watch for the boring failures too: partial CPU offload nobody noticed, a cache that stopped hitting, swap creeping up under load. None of these throw. They just make the system slower or stranger while still returning something.
The fix that holds up is boring on purpose. Enforce the boundary in the database layer, not in the system prompt, and keep the configuration reproducible from a script or a service file rather than a pile of manual tuning that breaks on the next driver update. It's less fun than picking a bigger model. It's also the only version of this that survives someone else touching the machine six months from now, which is the actual test.
What I still don't have a clean answer for: a read-only, cost-capped, schema-aware assistant can still write a query that's syntactically perfect, costs nothing, and answers a subtly different question than the one you asked. Guardrails built around execution stop the expensive and the destructive. They do nothing about the merely wrong, and I haven't found a validation layer that reliably catches "correct SQL, wrong question" without a person reading the result.