A Spring AI client answers typed questions and never generates a token
Christian Tzolov has introduced Spring AI TypeSafe, a Spring AI Community project that wires TypeSafe AI's hosted Jev API into Spring applications. The point of it is stated bluntly in the post: this is not a chat model. It classifies, scores and decides, and it never produces text. You pass it a state — the thing being judged — together with a map of typed questions, and it answers all of them against that state in a single call.
The whole API is three primitives. A Noul asks a yes/no question and returns a truth value between 0 and 1, with no separate confidence field because the number already is the certainty — 0.5 means undecided. A Choice picks one label from a set and returns the winner, a probability for every option and a confidence. A Score places the state on an ordered rubric and returns a continuous value, the legend, per-level probabilities and a confidence. A support ticket run through three of these comes back with an urgency of 0.95, a department of billing behind a distribution of {billing: 0.87, technical: 0.13, sales: 0.0}, a confidence of 0.82 and a frustration of 1.1 on a three-level scale.
One measurement in the post deserves to outlive the product. Running that same ticket with bare labels instead of described options — "billing", "technical", "sales" with no explanation of what each means — drops the confidence from 0.82 to 0.60. The descriptions are not documentation for the reader; they are input.
The rest is Spring plumbing, and the author is careful about its limits. JevJudge composes criteria, each a question plus the threshold it has to clear, and returns a verdict per criterion; where a criterion lands below the judge's floor it is reported INCONCLUSIVE rather than FAILED, and failOnInconclusive(true) is there for teams who would rather reject than let an unverified answer through. JevSelfRefineAdvisor closes the loop around a ChatClient: the model answers, the judge checks every criterion in one call, and on failure the failing criterion's own whenFalse sentence, its score and its threshold are appended to the prompt and the call is re-issued up to a configured number of attempts.
The constraints are listed rather than buried. Jev does not stream, so a call returns after a few hundred milliseconds rather than token by token. The state must be a string, object, array or null — a bare number or boolean returns HTTP 422. Work is one call per document, so reranking a top-20 list costs twenty calls and the post tells you to screen the list first. A Choice always names a winner, so "none of these" has to be asked as its own Noul. And confidence is described as a routing signal, not a quality score.
⚠ Both artefacts are at version 0.1.0 on Maven Central under org.springaicommunity, this is a community project rather than part of Spring AI proper, and it calls a hosted third-party service that needs an account and an API key. The latency figure and the cost claim — thousandths of a cent, on TypeSafe's own benchmark — are the vendor's. The post does state that its quoted outputs come from live runs, and it discloses where a demo was scripted: the weather tool in the self-refine example returns −125 °C on purpose.

What it means
The design idea is separable from the vendor. Ask several narrow questions instead of one broad one, answer them against one state in one pass, and attach a confidence to each answer so that code — not a prose response — decides what happens next. That shape is worth copying whatever you call at the other end.
It is aimed squarely at the ugliest part of the current stack. Getting a parseable number out of a second chat model means integer scales, few-shot examples, temperature zero, a JSON schema and a parser, and then a retry when it comes back as a sentence. Every one of those layers exists to make a text generator behave like a classifier. A component that never generates text does not need them.
The question to ask before adopting it is about the dependency, not the API. A routing decision that used to be an if statement becomes a network call to a company whose benchmark you cannot reproduce and whose model you cannot pin. That is a reasonable trade for some decisions and an unreasonable one for others, and version 0.1.0 of a community integration is the moment to decide which kind you have.
Source: https://spring.io/blog/2026/09/21/spring-ai-typesafe-structured-judgment