TypeSafe shipped Jev on 15 September, calling it a new class of model: not a language model, produces no text, takes a piece of state plus a map of typed questions and returns typed answers with calibrated probabilities in a single parallel pass.
I spent two days wiring it into the two places VOLO would actually use it, and made about fifteen hundred calls. The conclusion is that it earns its place. But the conclusion is not the valuable part of this piece — the valuable part is the pits I fell into, four of which are the same shape.
On the numbers: anything marked "I measured" I ran myself, one run, one model (jev-latest), one channel. "The docs say" comes from TypeSafe's own documentation. Anything else is named. I have no relationship with TypeSafe and pay for the API myself.
What it is
Three question types. You can ask a dozen in one call and the extra ones barely cost time.
| Type | You give | You get back |
|---|---|---|
noul |
one yes/no statement | probability that it is true, 0 to 1 |
choice |
up to 255 options, each described | the pick + per-option probabilities + confidence |
score |
an ordered scale of 2 to 10 levels | a continuous score + distribution + confidence |
curl https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "The deploy failed twice and customers are seeing 500s",
"questions": {
"urgent": { "type": "noul", "instructions": "Does this need attention right now?" },
"area": { "type": "choice", "instructions": "Which team owns it?",
"criteria": { "infra": "infrastructure and deploys",
"app": "application code",
"unknown": "the text does not say" } },
"severity": { "type": "score", "instructions": "How severe is it?",
"criteria": ["internal only", "some users see it", "all users see it"] }
}
}'
I measured: first call HTTP 200, 0.84 seconds, 436 input tokens. The docs say 70 to 500 ms end to end, $0.042 per million input tokens, output not billed. It is also on Cloudflare Workers AI, OpenRouter and Vercel AI Gateway.
One thing to say up front: the "zero hallucination" claim means the answer always lands inside the option set you supplied. It does not mean the answer is right. Those two things are far apart, and most of what follows happened in the gap.
What it suits
A test is more useful than a list. In one sentence: sorting a lot of things into a few boxes you defined in advance, where you also need to know how sure it is.
If all three hold, it probably fits:
- the output space is closed and you can enumerate the options, including "none of these";
- the judgement repeats at high frequency, hundreds to millions of times a day;
- you need a number you can route on — act on high confidence, ask on medium, hand low confidence to a person.
The concrete work falls into a few groups.
Routing. Tickets, mail and alerts to the right queue. Intent detection, then deciding between deterministic code, a specialist model, or a human. Model routing: does this turn need the expensive one.
Retrieval. Scoring each retrieved passage for relevance before it enters the context. Re-ranking an embedding shortlist pair by pair. Checking whether a claim is actually supported by the passage it cites.
Safety and quality. Screening an LLM's inputs and outputs. Turning team conventions into yes/no checks in CI and using the result to annotate a pull request — annotate, not rewrite.
Data and operations. Validation after structured extraction (extraction goes elsewhere; picking the right candidate comes here). Scoring leads, vendors or applicants on independent dimensions, with the weights in your own code. High-cardinality classification in two staged passes.
My own two: multilingual role-name resolution, and first-pass triage of a few hundred leads a day.
The catalogue above draws on the community's awesome-jev list and the Patterns section of the official docs. I only ran the last two myself.
One number that is not mine: Langfuse wrote up how to wire it into an evaluation pipeline and cited Good Start Labs' testing — Jev agreed with Claude Fable 5.1's verdicts 91.5% of the time, at $160 per million graded answers against $33,000. That measures agreement with another model, not agreement with reality, and they say so themselves.
What I measured
Role-name resolution: Jev 45/53, my hand-written rules 35/53.
53 cases across six languages, a dozen of them bugs this codebase has actually shipped. The comparison is lopsided: those rules were written for Chinese and English, and the test cases come from their own bug history, so they lost at home.
What decided it for me was not the score but that confidence separates right from wrong. The three it got wrong in Chinese carried 0.39, 0.49 and 0.62 — the three lowest in the whole table — while the correct ones averaged 0.95. That makes threshold routing viable.
Evidence triage: right on high confidence, wrong only on low.
Ten real items, each with a human verdict I had already recorded. Stage classification was right at 0.99, 0.96, 0.91, 0.85 and 0.84, and wrong at 0.35, 0.38 and 0.39.
That is what calibration is supposed to look like. A model being wrong is not the problem. A model being wrong as confidently as it is right, is.
The prettiest result was abstention: I put an explicit cannot_tell in the option set, and two pieces of pure noise chose it at 0.85 and 0.84.
Cost: about 1,100 input tokens per triage item, roughly $0.009 a day for 200 items. 1,440 terms across four languages, zero failed calls.
The pits
Same model, same data — 2/10 and 10/10 apart
The most expensive number of the two days. I asked the same gate three ways, in parallel, in one call.
| Wording | Correct |
|---|---|
| v1 "does this describe a concrete thing where AI changed someone's work" | 2/10 |
| v2 "is there a concrete, checkable fact here about AI being used, adopted, priced, regulated or measured in workplaces" | 10/10 |
| v3 "would a researcher bother opening the original" | 3/10 |
v1 judged three records already in my own database as irrelevant: Figma's 10-Q at 0.14, a Eurostat usage statistic at 0.06, an article of Korea's AI Framework Act at 0.09.
I had already started writing "it cannot recognise our kind of evidence".
The problem was mine. The phrase "changed someone's work" appears nowhere in those three documents. Figma's is about metering AI usage, Eurostat's is about what share of firms apply AI to what, the Korean article is about human oversight.
It reads literally. That is the first line of the official documentation, I had read it, and my first instinct was still to doubt the model.
Wiring up a classifier, the work is not the call. It is the wording — and whether the wording is right can only be found by running it against a set whose answers you already know.
I was not asking the question I actually needed
It happened again the next day, more completely, while validating a multilingual term list.
I asked: "would a native speaker understand this word as naming the same job?" 387 terms, 160 flagged. Looking through them, nearly every flagged term was a good one. In Japanese 簿記 is a field rather than a job title, 法務部 is where a lawyer sits rather than the lawyer, マーケティング is the name of a discipline.
An alias is not a synonym by definition. It is the word someone in that job would type into a search box.
Swapping in the question my own system actually asks — which page should a person typing this land on — took 387 down to 1 flagged.
From 160 to 1. Same model, same data, one sentence changed.
Work out which judgement your system actually makes, then hand it that judgement unaltered. Do not translate it into a question that sounds more general.
Do not ask it things you already know
I added a field asking whether the publisher was the party that did the thing, to pre-sort primary from secondary sources. It was wrong across the board: 0.39 on the Korean statute, 0.48 on a Japanese ministry report, 0.71 on Eurostat.
Not the model's fault. I gave it the body text without telling it who published it — and every source in my pipeline already carries its publisher and tier as a fixed field.
Every field you ask about a fact you already hold is one more chance to be wrong about it.
"None of these" has to be an explicit option
I gave it 84 occupations to choose between. Without an 85th option, it has to pick one of the 84.
With "none of the above" added, "astronaut" and "animal trainer" both chose it at 1.00 confidence.
The docs cover this (it cannot abstain); I found it by falling in first. It matters particularly here: a wrong match is worse than no match. "We do not cover this" gets seen and said out loud. A wrong match does not.
Confidence can route, but it cannot go on the page
A product judgement rather than a technical one, and more dangerous for it.
That 0-to-1 number looks far too much like a score. VOLO has a rule that nothing gets scored — "answer five questions, get your redundancy risk score" is the opposite of why the product exists. So confidence stays inside the routing logic and not one byte of it is rendered.
Three runs writing to the same filename
I let four languages' validation reports write to one path. Afterwards only the last one was there, and the overwrite was silent: the log printed "checked 352" for every language, so all three looked present.
This codebase has been caught three times by failure being indistinguishable from emptiness — once because timeout does not exist on this Mac, and the 37-byte file it left behind read exactly like "zero crawler traffic". This was a new variant: result indistinguishable from result.
Any script that will be run repeatedly should carry whatever varies between runs in its output filename.
The biggest find came from the control group, not the model
To give Jev a control group I ran my hand-written rules across six languages, and hit a real production defect.
The alias field was string[] rather than a multilingual type, so all six locales shared one Chinese-plus-English alias table — while every translation-completeness guard honestly reported 5,758 of 5,758 complete, because a field never declared multilingual is invisible to the walker.
Ten real role names per language:
| zh | en | pt | es | fr | ja | |
|---|---|---|---|---|---|---|
| before | 10 | 9 | 9 | 8 | 7 | 6 |
| after | 10 | 10 | 10 | 10 | 10 | 10 |
The Japanese input box carries the placeholder "e.g. 経理, 公認会計士, グラフィックデザイナー". Until that day, we could not resolve a single one of our own three examples.
Jev's validation then turned up a second one: the rule deciding whether a sentence names a field of study or a job was a regex in Chinese and English only, so estudio marketing, estudo marketing and j'étudie le marketing all resolved to the occupation. A student saying what they study got a page about how that job is changing.
The cost of building a control group for a new tool often gets repaid by the control group itself.
What the vendor admits to
Worth its own section: TypeSafe publishes a page called model jaggedness setting out where the model is unreliable. A vendor volunteering its own model's weaknesses is rare, and this one is specific.
| Weakness | What it means |
|---|---|
| Literal reading | "answers the question you wrote, not the one you meant" |
| Arithmetic | "not a calculator"; unreliable at counting and at judging numeric proximity |
| Numeric form | hex values do worse than English names |
| Dates and time | "reads dates as text, not as ordered quantities" |
| Indirection | double negatives and multi-hop reasoning cost accuracy |
| Irrelevant detail | accuracy falls as the state fills with content the question does not need |
| Adversarial content | it does not treat the state as hostile by default |
| Contradictory instructions | instructions and criteria asking different things confuses it |
| Generation | forcing it to generate "will not work well and will be very slow" |
The adversarial line is a hard constraint for anyone using it as a guardrail: do not make it the last line of defence against hostile input.
Two more worth knowing. It generates no text, so when an evaluation scores badly it gives you no reason at all — getting one means adding a second model, which eats part of the cost advantage. And the official guidance says "English is the primary language; test non-English workloads on representative data." My six-language run showed no obvious degradation, but that is one run and does not refute it.
When not to use it
Not for writing anything; it produces no text. Not for arithmetic, date comparison or numeric proximity — the vendor says so itself. Not for open-ended questions; you must enumerate the options. Not as the last line of defence against adversarial input.
And its confidence measures how much the text looks like the thing, not whether the thing is true.
My own boundary is harder: nothing that writes into VOLO's judgement layer goes near it. It proposes, a person verifies. That is not distrust of the model — it is that the product's promise is that every judgement traces back to a named person.
One last thing
The four pits I fell into over those two days are the same shape: I came up with a criterion that sounded right, then used it without calibrating it.
"It must be the wording again." "This alias should be rejected." "It's not in the log, so it didn't happen." Each looks like insight on its own, and a rule you derived yourself is indistinguishable from a bias until it has been calibrated.
The cure was the same all four times: go and look at what the existing set actually looks like, then decide.
That is useful advice for using Jev. It is equally useful for not using it.