Using Jev as a classifier.
Jev, TypeSafe's System One model, can classify text against labels you describe in plain language in each request, with no task-specific training step. The design decision that matters most is whether more than one label can be true at once. If exactly one label wins, ask one Choice. If labels can co-occur, ask one Noul per label.
Both return probabilities rather than a bare label. What happens when those probabilities are not decisive is up to your code: route to a person, fall back to a broader category, or hand the case to another model.
Pick the classification shape before writing labels
| Your problem | Example | Ask Jev | Read |
|---|---|---|---|
| Exactly one label applies | One queue owns each ticket | One choice() with every label, plus other | .choice, .confidence, .probabilities |
| Any number of labels can apply | A ticket asks for a refund and threatens to cancel | One noul() per label | .noul on each, with its own cutoff |
| Several independent dimensions | Queue, plus risk flags | Several keyed questions in one systemOne() call | Each answer under its own key |
| Labels are ordered levels | Severity from low to critical | score() (see Score) | .score, which can fall between levels |
| The answer is not decisive | A vague one-line message | Nothing extra | Your own rule on confidence or P(yes) |
Single-label: one Choice, one winner
Criteria are an object: each key is a label your code will receive, each value describes when that label applies. The TypeScript SDK turns the keys into a union type, so a misspelled label in a switch is a compile error.
other or “none of the above” label when your list may not cover every input. Without it, an off-topic message still gets assigned to one of your real queues.confidence from the shape of the whole distribution: 1.0 when all probability sits on one label, lower as it spreads. The probabilities map is still there if another measure suits you better, such as the margin between the top two labels.Multi-label: one Noul per label
A Noul answers one yes/no question and returns a single number, the probability of yes. Ask one per label and each is judged separately, so a ticket can be a refund request and a cancellation threat at the same time. There is no confidence field on a Noul. The probability already expresses the uncertainty.
Same ticket, a refund request that also says the customer will cancel, asked both ways. Values are illustrative, not measured output.
Noul values for different labels are not constrained to relate to each other. Choose each label's cutoff by what a mistake on that label costs. TypeSafe also warns against reusing a cutoff tuned on a Noul for a Choice.
Classify several dimensions in one request
Real classifiers rarely answer one question. This support-triage function asks for one owning queue and three independent flags against the same ticket in a single call. The questions are evaluated in parallel, and the ticket is sent once instead of once per question.
`ticket.body` in the question. Only send fields a question needs; unrelated context lowers accuracy.state must be assignable to the SDK's JsonValue type. A type alias of JSON fields passes. An interface fails unless it declares [key: string]: JsonValue, because TypeScript gives only type aliases an implicit index signature. A Date field fails too; send an ISO string. We hit the interface case compiling the example.Both TypeScript examples type-check under strict against @typesafe-ai/sdk 0.6.0. We confirmed the request body the SDK sends with a stubbed fetch; we did not run them against the live API, and no answers on this page come from a real request.
Decide in code what counts as uncertain
Jev always returns an answer. It does not abstain. Holding back is your application's job, and the signals are all in the response:
| Signal | What it means | Typical action |
|---|---|---|
Low Choice confidence | Probability is spread across labels | Human review, or report the parent category instead |
| Small top-two margin | Two specific labels are competing | Check whether the labels overlap; if both can be true, switch to Nouls |
other wins | Input is outside your label set | Triage queue; review these to find missing labels |
| Noul near the middle | Yes and no are close | Review, or a slower model that can reason and explain |
For a Choice-driven dispatcher that sends requests to code, an LLM, or a person, see model routing with Jev.
When another classifier is the better tool
Jev is not the default answer to every labeling problem. These are our editorial rules of thumb, not measured comparisons.
| Approach | Better when | Jev instead when |
|---|---|---|
| Rules, regex, SQL | The signal is literal: a field value, a domain, an amount, a date window. Anything involving counting, dates, or arithmetic, which TypeSafe lists as jev-1.13 weaknesses. | The rule would need to understand wording, and keyword lists keep growing exceptions |
| Embeddings and nearest neighbor | Thousands of labels, labels defined by examples rather than descriptions, or deduplication and search | You want a decision with probabilities among a short list of described labels. Embeddings can shortlist candidates for a Choice. |
| Trained classifier | You have plenty of labeled data, the label set is stable, and you need to run it on your own hardware or tune it to your data | You have no training set yet, or labels change often enough that retraining is the bottleneck |
| Generative LLM | You need an explanation, extracted text, an open-ended label, or multi-step reasoning, which TypeSafe says lowers jev-1.13 accuracy | The answer is a known label and you want typed output with probabilities instead of parsed text (see Jev vs. LLMs) |
Measure before committing. Published classification results are collected, with methodology notes, on the benchmarks page; none of them replace a test on your own data.
Limits that shape label design
state plus the longest question. Text and JSON only; no images or audio.state.jev-latest can move to a new model. Log model from each response, and pin jev-1.13.0 while you re-check cutoffs on a new release.Client setup, errors, and retries are covered in the TypeScript SDK guide; keys and rate limits in API access.