# Decision models

> Models like Jev and Clef return a probability for each allowed answer instead of text, for fast routing, scoring and yes/no gates.

Concept · LLMs in production · https://levelcode.org/concepts/decision-models

A **decision model** answers typed questions about an input and returns probabilities, never prose. You ask "which team owns this ticket?", "is it urgent?" or "how risky is it, 0–2?", and get a calibrated number for every allowed answer. Your code acts on the number. TypeSafe's **Jev** started the category; Cloudflare's **Clef** followed with a compatible API.

## How it works

One request carries a `state` (the input) and named `questions`. All of them are answered against the same state. There are three question types:

- **`choice`** picks from 1–255 named options and returns the top one plus a probability for each.
- **`score`** places the input on 1–10 ordered levels and returns the probability-weighted position. A score of 1.4 means it sits between levels 1 and 2.
- **`noul`** is a yes/no question and returns the probability of "yes".

```json
{
  "model": "jev-latest",
  "state": "Charged twice for October. Need it fixed before payroll runs Friday.",
  "questions": {
    "team":   { "type": "choice", "instructions": "Which team owns this ticket?",
                "criteria": { "billing": "Payments, invoices, refunds", "bug": "Something is broken", "sales": "Plans and pricing" } },
    "urgent": { "type": "noul", "instructions": "Does the customer need a reply today?" },
    "churn":  { "type": "score", "instructions": "How likely is this customer to leave?",
                "criteria": ["Unlikely", "Possible", "Likely"] }
  }
}
```

An abridged response, with illustrative values:

```json
{
  "answers": {
    "team":   { "type": "choice", "choice": "billing", "confidence": 0.97, "probabilities": { "billing": 0.97, "bug": 0.02, "sales": 0.01 } },
    "urgent": { "type": "noul", "noul": 0.88 },
    "churn":  { "type": "score", "score": 1.4, "probabilities": { "0": 0.12, "1": 0.36, "2": 0.52 } }
  }
}
```

Because every answer is a probability, "send it to a human when unsure" becomes a threshold in your code, such as `confidence < 0.7`, rather than a hope written into a prompt.

## Jev and Clef

| | Jev | Clef / Clef-flash |
|---|---|---|
| From | TypeSafe AI | Cloudflare (October 2026) |
| Runs | Hosted API, `POST /v1/systemone` | Workers AI (`@cf/cloudflare/clef`), or self-hosted |
| Weights | Closed | Open, Apache 2.0 (27B and 9B) |
| Context | 32K (as quoted by Cloudflare) | 64K, with image input |

Cloudflare reports median latencies of about 39 ms for Clef-flash, 209 ms for Clef and 524 ms for Jev. In its own benchmarks, Clef wins on most tasks but trails Jev on a few, including When2Call (deciding whether to call a tool). Those are vendor numbers. Run your own [evals](https://levelcode.org/concepts/llm-as-judge) before switching.

## When to use one

They fit **bounded decisions in a hot path**: routing a request to the right model or prompt, triage, moderation, and "should the agent stop and ask?" gates. Compared with a generative model plus [structured outputs](https://levelcode.org/concepts/structured-outputs), they're faster and cheaper per call. They also return a distribution, not a single sampled label.

They don't write replies, extract free-text fields or reason through multi-step problems. Pair them with an LLM that does.

Two cautions. Probabilities are only as calibrated as your data allows, so pick thresholds from a labelled test set. And `state` is untrusted text: [prompt injection](https://levelcode.org/concepts/prompt-injection) can tilt the verdict. Keep a hard rule or a human on any gate that grants access or moves money.
