Count the LLM calls in your backend that end in a parser.
Not the ones that write an email or summarise a document — the ones where you asked a chat model a question whose answer is a boolean, a label, or a number between 1 and 5. Then you wrote a prompt template, a JSON schema, a parser, and a retry for the time it replied "Sure! Here's my assessment:" instead of {"urgent": true}.
Jev, released by TypeSafe AI on 15 September 2026, deletes that whole layer — by refusing to generate text at all.
TL;DR
- Jev answers typed questions: yes/no, pick-one, score-on-a-rubric. No prose, ever.
- Every answer comes back with a probability, and most with a confidence as well.
- No prompt template, no schema, no parser, no repair step. The shape is the request.
- TypeSafe quotes $0.042 per million input tokens, free output, 70–500 ms. Cheap enough to check every expensive call instead of sampling.
- It does not replace your chat model. It decides what to do with what the chat model produced.
What a "System One model" is
The name refers to fast, intuitive thinking as opposed to slow deliberation. TypeSafe describes the target as "a judgment a knowledgeable person makes in a second given the right context."
Three things matter to a backend engineer:
- It isn't autoregressive. No token-by-token generation, which is why answers arrive in a few hundred milliseconds instead of seconds.
- The output is type-constrained. You don't ask for JSON and hope. The type is part of the request.
- Answers carry calibrated probabilities, not just values.
The trade is absolute: it gives up string generation entirely. It cannot write you a sentence.
The entire API surface
| Primitive | You ask | You get back |
|---|---|---|
| Noul | a yes/no question | a truth value in [0, 1]
|
| Choice | pick one label | the label, a probability per option, and a confidence |
| Score | place on an ordered rubric | a continuous value, the legend, per-level probabilities, and a confidence |
That's it. Three shapes.
A Noul has no separate confidence because the value is the certainty — 0.5 means undecided. A Score is continuous, so 1.1 on a three-level rubric means "just past the middle level", which is what makes a threshold like 2.0 mean something.
From Spring Boot
There's a Spring AI Community integration, version 0.1.0 on Maven Central:
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>spring-ai-starter-typesafe</artifactId>
<version>0.1.0</version>
</dependency>
Set TYPESAFE_API_KEY, and auto-configuration gives you a TypeSafeClient. Here it is triaging a payment complaint — the kind of ticket I spend my working life near:
SystemOneResponse response = typeSafeClient.systemOne(
"Customer says: my card was charged twice for order 4417 but only one order shows up.",
Map.of(
"duplicate_charge", Noul.builder()
.instructions("Is the customer reporting being charged more than once for one purchase?")
.whenTrue("The customer describes multiple charges for a single order")
.whenFalse("The customer describes a single charge, or a different problem")
.build(),
"queue", Choice.builder()
.instructions("Which queue should handle this?")
.option("payments-ops", "Duplicate charges, stuck payments, reconciliation mismatches")
.option("disputes", "Chargebacks, evidence submission, representments")
.option("billing", "Invoices, refunds, subscription changes")
.build(),
"urgency", Score.of("How urgent is this for the customer?",
"Can wait", "Needs attention today", "Money is missing right now")));
double duplicate = response.noulValue("duplicate_charge");
String queue = response.choiceValue("queue");
double certainty = response.choice("queue").confidence();
Three questions, three typed answers, one call, no parsing.
Write real option descriptions. The Spring post measured the difference: the same ticket with bare labels instead of described options dropped confidence from 0.82 to 0.60. The descriptions are how the model learns what your labels mean.
The idea worth stealing: confidence is a routing decision
This is the part that changes how you write the calling code, even if you never use Jev.
The answer tells you what. The confidence tells you whether to act on it unattended. One number can't carry both — which is exactly why the classic "rate this 1–5" prompt fails: one catastrophic flaw gets averaged into a middling score.
So you get three branches, not two:
if (certainty < 0.5) {
humanReview(ticket, response); // undecided is not "wrong"
} else if (duplicate > 0.8) {
payments.investigateDuplicate(ticket); // confident and true
} else {
route(queue, ticket);
}
"Not unattended" becomes a first-class outcome instead of an error case. Anyone who has built a fraud queue or a dispute workflow already recognises this shape.
Cost and latency — and who is claiming what
| Source | Claim |
|---|---|
| TypeSafe | $0.042 / MTok input, output free ("too cheap to meter") |
| TypeSafe | 70–500 ms end to end; 40–200× faster, 40–400× cheaper than frontier LLMs |
| TypeSafe's cookbook | a 14-question call at $0.000043 and 111 ms vs ~$0.0018 / 1.8 s for a small chat model |
| Spring blog author, measured on a laptop | median 275 ms for one question, 310 ms for three |
The multipliers are vendor benchmarks on tasks the vendor chose. Treat them as an order of magnitude, not as a line in a business case — but note that two extra questions cost the Spring author 35 ms, because everything is answered against one read of the state.
The real consequence isn't saving money on calls you already make. It's that at thousandths of a cent, a check can run in front of every expensive call rather than on a sample: a gate on a model cascade, a relevance filter before a long-context generation, a verification pass on output you currently ship unchecked.
Things that will bite you
- No streaming. Nothing is generated token by token, so there is nothing to stream.
- State must be a string, object, array or null. A bare number or boolean returns a 422.
- Per-document work is one call per document. Reranking a top-20 list is twenty calls — filter first, rank the survivors.
-
Choicealways names a winner, because the probabilities sum to one. If "none of these" is a real answer, ask it as a separateNoul. - Early access, US West Coast. That's a real latency budget if you serve from elsewhere.
What a typed output does not fix
A typed answer can't be malformed. That genuinely kills a class of bug: the parse failure, the apology instead of an answer, the "yes, but..." where you expected a boolean.
It does not make the answer right. A calibrated probability is still a probability. In payments, where I work, that means:
- Keep it out of the authorization path. A decision that moves money needs a deterministic rule and an audit trail, not a model's 0.91.
- Anything you must justify to a regulator or card scheme needs a reason. "The model scored it 0.87" is not one.
- Threshold choice is a product decision. Where you set the confidence floor decides how much work lands on a human.
Where this leaves us
Most backends have been using one tool for two jobs, because there was only one tool. Chat models write. System One models decide.
Go and look for the calls in your codebase that end in a parser. That's the list.
I write about payments and backend engineering at feezankhattak.com. The longer version of this post covers the guardrail and reranking integrations, and I build free in-browser tools for backend developers — no sign-up, nothing uploaded.
Top comments (0)