Decision Models vs. SQL Rules: A Data Team's Guide

You have a pipeline that works until it doesn't. A keyword rule misfiles half your support tickets, a threshold flags the wrong invoices, and every fix is another CASE WHEN that breaks something else. A new class of model, with Jev from TypeSafe AI as the first public example, targets exactly this gap. Used carelessly, though, it just adds cost where plain SQL was already fine.
Start with the rule: if SQL can settle it, use SQL
Use SQL whenever the answer sits in the data in a clean form. VentureBeat quotes an expert saying that if plain SQL can settle a question, such as a value over a threshold or a keyword match, you should just use SQL. Decision models are for cases SQL cannot settle, not a replacement for it (source).
That framing should drive every design choice below. A quick sorting test:
| Question | Right tool |
|---|---|
Is amount > 10000? |
SQL |
| Does the description contain "refund"? | SQL |
| Do these two tables share an ID? | SQL join |
| Is this vendor note describing a dispute, even though it never uses the word? | Decision model |
| Which of 40 spend categories fits this free-text line item? | Decision model |
| Is this change request risky given its context? | Decision model, plus rules |
The pattern: rules win when the signal is explicit and exact. Decision models win when the signal is implied, fuzzy, or spread across wording you can't enumerate.
What a decision model actually is (and isn't)
A decision model returns structured answers with probabilities, not prose. According to the dbt-labs issue describing the interface, Jev takes a state (text or JSON) plus typed questions of three kinds: a yes/no probability, a choice among 1 to 255 labeled options, and a score on an ordered scale. It returns answers with probabilities and a confidence value, and it never generates text (source).
TypeSafe's launch post describes these structured outputs as fuzzy decision rules inside ordinary software: they can classify, route, score, extract or branch where hand-written logic is too brittle (source).
Two consequences matter for builders:
- It can't explain itself. Because Jev doesn't generate text, it can't summarize a call or explain a choice, and it only sees the record you send it (source). If you need an audit narrative, you generate it elsewhere.
- Valid is not correct. Jev cannot return an answer outside the schema you give it. That guarantees well-formed output, not a right decision (source). Vendor language about the model being unable to hallucinate should be read with that distinction in mind. Your validation and spot-checks still matter.
For context on provenance: TypeSafe AI, a San Francisco lab, came out of stealth on September 15, 2026 with Jev as its first public model (source). It's new. Treat everything below as early-stage practice, not settled doctrine.
The cost picture: cheap enough to change the architecture
The pricing is what makes this interesting for small teams. TypeSafe's docs list both Jev 1.14 and Jev 1.13 at $0.042 per million input tokens, with output tokens free (source). Check the docs for current pricing before you build a budget around it.
Vendor-reported numbers, which I'd treat as directional rather than proven:
- Astronomer reported that Jev classified 4,000 titles in 66 seconds for 16 cents, and estimated $11 to $21 for the same work on Snowflake's AI_CLASSIFY at list price. The AI_CLASSIFY figure is an estimate, not a measured run (source).
- In MotherDuck's own 100,000-row benchmark, Jev reached 89% accuracy in 40 seconds for $0.50. That's a company benchmark, not independent (source).
Neither result is independent, and your data will differ. What they do suggest is that per-row model calls over a whole table are now a normal design option rather than a budget event. Run your own sample before committing.
Pattern 1: rules first, model for the remainder
The highest-value pattern is a cascade. Let SQL take everything it can settle for free, and send only the residue to the model.
One engineer's case study shows the shape. In a pipeline classifying Brazilian electoral expense records, cheap SQL keyword rules classified 42% of 192,000 distinct descriptions for free. Only the rest went to Jev, which roughly halved cost compared with sending everything to Jev (source). That's a single case study, so don't extrapolate the 42%. Your hit rate depends on how regular your data is.
Here's the skeleton in SQL-flavored pseudocode. The decide call is illustrative, so adapt it to whichever integration you use:
-- Stage 1: deterministic rules claim what they can
CREATE TABLE classified AS
SELECT
id,
description,
CASE
WHEN description ILIKE '%fuel%' OR description ILIKE '%gasoline%' THEN 'fuel'
WHEN description ILIKE '%postage%' THEN 'shipping'
ELSE NULL
END AS category,
CASE WHEN category IS NOT NULL THEN 'rule' END AS decided_by
FROM raw_expenses;
-- Stage 2: only unresolved rows go to the decision model
UPDATE classified
SET category = decide(description, options => ['fuel','shipping','software','travel','other']),
decided_by = 'model'
WHERE category IS NULL;
Always record decided_by. When a category looks wrong in a report six weeks from now, you'll want to know whether a rule or the model made the call.
Pattern 2: confidence-based escalation
A decision model returns a confidence value, so you can route on it instead of trusting every answer equally. A research paper on using Jev as a judge describes this exact pattern: confident decisions are accepted, and uncertain ones go to a stronger LLM judge (source).
For a small team, the practical version has three lanes:
def route(decision):
# decision = {"label": "...", "confidence": 0.0-1.0}
if decision["confidence"] >= HIGH: # tune on your own labeled sample
return "auto_accept"
if decision["confidence"] >= LOW:
return "escalate_to_llm" # stronger model, can explain
return "human_review_queue"
Don't copy thresholds from a blog post, including this one. Label a few hundred real rows, plot accuracy against confidence, and pick cutoffs from your own curve. The thresholds are the part you tune; the three-lane structure is the part that transfers.
Pattern 3: rules as guardrails around the model
For anything with consequences (database changes, access grants, payments), keep deterministic policy in charge and let the model handle context. Bytebase recommends combining static SQL review rules, Jev, an LLM and human review for database change workflows. In that design the rules enforce explicit policy, Jev assesses contextual risk, the LLM explains, and a human decides (source).
That division of labor is worth stealing in any domain:
| Layer | Job | Why this layer |
|---|---|---|
| Static rules | Hard policy ("never drop a production table without approval") | Must be exact and auditable |
| Decision model | Contextual risk score | Handles wording and situations rules can't list |
| LLM | Plain-language explanation | The decision model can't generate text |
| Human | Final call on risky cases | Accountability |
The model never gets to override a hard rule. It can only add caution or fast-track the boring cases.
What to keep out of the model entirely
Some work should stay deterministic. TypeSafe's documented known limits for Jev 1.13 include literal reading, calculations, counting and date comparisons (source). In practice:
- Arithmetic and totals. Sum in SQL. Never ask a model whether an invoice total matches its line items.
- Date logic. "Is this invoice overdue?" is a date comparison. Compute it, then pass the result to the model if it's relevant context.
- Counting and exact string matching. Count in code.
- Anything requiring text output. Summaries and explanations belong to a generative model.
A useful habit is to precompute facts deterministically, then hand the model a clean state object:
{
"vendor_note": "Pls hold payment until the crates arrive, we were short last time",
"days_overdue": 12,
"amount_usd": 4300,
"prior_disputes_90d": 1
}
The numbers came from SQL. The model only has to interpret the note against them. That keeps the fuzzy part small and the exact part exact.
Operational limits and failure modes to plan for
A few constraints that affect real deployments:
- Context limits. By default, Jev allows 64k tokens per request and 32k per question. An opt-in header,
TypeSafe-Danger-Zone-Long-Context: true, raises both limits to 262k tokens (source). For most row-level decisions you'll never get near these, but document-level decisions might. - Latency. Databricks announced that Jev-1.14 is available there, callable on Lakehouse data through
ai_classifyandai_decide, and cites roughly 70 to 500 ms per decision (source). That's a vendor figure. Budget for your own measured latency, especially if a decision sits in a user-facing path. - Rate limits. Published figures conflict across sources. The docs say limits are per organization, shown in the console, and adjusted dynamically, so check your console rather than relying on numbers from articles.
- Platform availability. Databricks CEO Ali Ghodsi announced
ai_decide(), which runs decision models natively on data inside Databricks (source), and MotherDuck added aprompt_jev()SQL function (source). Availability, regions and maturity vary by platform, so confirm in each vendor's current docs before planning around a specific one. - Adversarial input. If the text you classify comes from outside parties (vendor notes, support tickets, form fields), assume someone will try to talk the model into a favorable answer. Pair the model with hard rules for anything gameable, and test with deliberately manipulative inputs.
A minimal rollout checklist:
- Pull 300 to 500 real rows and label them by hand.
- Run rules alone and measure how many they settle and how accurate they are.
- Run the model on the remainder and measure accuracy against your labels.
- Set confidence lanes from your own accuracy curve.
- Ship with
decided_byand the confidence stored on every row. - Sample 20 to 50 auto-accepted rows weekly for the first month.
Where this fits in practice
I build AI automations for small teams, and that includes replacing brittle rules with a model-based decision step. The pattern is the one above: an invoice-intake or categorization flow where the keyword list keeps growing and the exceptions keep multiplying is a good candidate. The deterministic guardrails (exact math, date logic, hard policy checks, human review for high-stakes items) stay in place around the model.
If you have SQL-and-rules logic you suspect should be smarter, the useful first step is an audit of your own pipeline: which rules are still right and cheap, and which are generating exceptions and manual cleanup. Sort the logic into "leave it alone" and "worth upgrading" before you spend anything on a model.
Work with BizFlowAI
If you'd rather have this built for you, that's what we do: production AI automation for solo founders and small teams — agents, integrations, and document pipelines that actually ship.
Request a free discovery call — 30 minutes, we map the highest-ROI automation in your workflow. No pitch deck, just engineering.
More guides like this on the BizFlowAI blog.
Frequently asked questions
When should I use a decision model instead of SQL rules?
Use SQL whenever the answer is explicit and exact in the data, such as a value over a threshold, a keyword match, or a join on shared IDs. Use a decision model when the signal is implied, fuzzy, or spread across wording you cannot enumerate, like deciding whether a vendor note describes a dispute without using that word. A good default is a cascade: let SQL resolve everything it can for free, then send only the unresolved rows to the model.
What is a decision model like Jev and what does it return?
A decision model takes a state (text or JSON) plus typed questions and returns structured answers with probabilities and a confidence value. The question types are a yes/no probability, a choice among 1 to 255 labeled options, and a score on an ordered scale. It never generates prose, so it cannot summarize or explain its choices. Jev from TypeSafe AI is the first public example of this model class.
How do I use confidence scores to decide when to trust a classification model?
Route each result by its confidence value into three lanes: auto-accept high-confidence answers, escalate mid-confidence ones to a stronger LLM judge, and send the lowest-confidence rows to a human review queue. Do not copy thresholds from articles. Label a few hundred of your own rows, plot accuracy against confidence, and choose cutoffs from that curve.
Can a decision model be trusted to make correct decisions if it cannot hallucinate?
Not automatically. A decision model cannot return an answer outside the schema you define, which guarantees well-formed output, but a valid answer is not necessarily a correct one. It can still pick the wrong label. You still need validation, spot-checks against labeled samples, and a record of which rows were decided by rules versus the model.
What tasks should I keep out of a decision model and handle deterministically?
Keep arithmetic, totals, counting, exact string matching, and date comparisons in SQL or code, since documented limits for Jev include literal reading, calculations, counting, and date comparisons. For example, compute whether an invoice is overdue in SQL and pass that result to the model as context rather than asking it to work it out. Anything requiring text output, such as summaries or audit explanations, belongs to a generative LLM.