Jev with Spring AI: Fast, Cheap, Structured Decisions and Model Routing
Jev is a hosted TypeSafe AI API that answers yes/no, pick-one and score questions about your data. Here is the Spring AI starter, how to wire it, and a confidence-gated model router, verified offline.
Most LLM calls in an application are not conversations. They are decisions: is this ticket urgent, which of these four categories fits, how toxic is this comment on a scale of one to five. You can ask a large chat model each time, but you pay for a whole answer and wait for it when all you wanted was a label. Jev is a hosted service from TypeSafe AI built for exactly that kind of question, and the Spring AI community now has a starter for it. This post shows the coordinates, the three question types, a model router built on top, and an honest list of what I could not test.
Versions and limits.org.springaicommunity:spring-ai-starter-typesafe0.4.0 and typesafe-spring-ai 0.4.0 (both the latest on Maven Central on 13 October 2026), Spring Boot 4.1.1, Spring AI 2.0.1, JDK 25. These are community 0.x libraries. I had no TypeSafe API key and never called the service. What ran: bean wiring, building questions, and my routing code on responses I constructed by hand. Every speed and price figure below is TypeSafe’s own claim from their article, not something I measured. The demo is one downloadable file: JevRoutingDemo.java.
The failure first: no API key, no client, no error
The starter only creates its client when a key is configured. Its own metadata says so: “No Jev client is auto-configured until it is set”. I ran the auto-configuration twice, once without and once with a dummy key:
== 1. when does a TypeSafeClient bean exist?
no api key -> TypeSafeClient beans: 0
with api key -> TypeSafeClient beans: 1
default model = jev-latest, timeout = PT10S
The practical result: if you forget spring.ai.typesafe.api-key (or the TYPESAFE_API_KEY environment variable in the vendor’s setup instructions), Spring does not fail at startup. A bean you injected simply does not exist, so you get a “no qualifying bean” error from your own class, which looks unrelated to Jev. The dummy key was never sent anywhere. Output from JevRoutingDemo.java.
Defaults I read from the metadata: base URL https://api.typesafe.ai, model jev-latest, a 10-second timeout and a retry policy with a 500 ms initial backoff that doubles.
What Jev is, in the vendor’s words
According to TypeSafe’s article on the Spring blog, Jev answers structured questions about some state you give it, rather than writing text. It does not stream. The state you pass must be a string, object, array or null. I describe it only as they do and I did not verify how it works inside; the claims about its speed come next, so you can see how much rests on the vendor.
The drawing shows the shape of the API, from the compiled typesafe-java-sdk: one request carries your state and a map of named questions, and the response carries one typed answer per name.
Setup
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>spring-ai-starter-typesafe</artifactId>
<version>0.4.0</version>
</dependency>
<!-- optional: ChatModel, advisors and tool index built on the client -->
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>typesafe-spring-ai</artifactId>
<version>0.4.0</version>
</dependency>
spring.ai.typesafe.api-key=${TYPESAFE_API_KEY}
The plain Java SDK is a separate artifact, org.springaicommunity:typesafe-java-sdk, and the starter pulls it in. The second artifact’s description in its POM reads “Spring AI advisors, RAG post-processors and a tool index backed by the TypeSafe AI System One (Jev) model”.
Three kinds of question
From the SDK’s question package:
Noul: a yes/no question answered as a number between 0 and 1. NoulAnswer.isTrue() compares it to a threshold.
Choice: pick one of several labels. The answer has the chosen value, a probability for each option, and an overall confidence.
Score: a level on a scale you describe, with the nearest level, its label and a confidence.
You build them with static factories and send them under names you choose. These are the two I used for a support-ticket router:
static Map<String, Question> routerQuestions() {
Map<String, Question> q = new LinkedHashMap<>();
q.put("difficulty", Choice.of("How hard is it to answer this ticket correctly?", "simple", "complex"));
q.put("needs_account_data", Noul.of("Does answering require looking at the customer's account data?"));
return q;
}
The call itself, which I compiled but did not run, is client.systemOne(state, routerQuestions()) with the ticket text as state. It returns a SystemOneResponse with helper accessors such as choice("difficulty") and noulValue("needs_account_data"). Printing the questions confirms they are built as intended:
difficulty -> choice: JsonContent[value=How hard is it to answer this ticket correctly?]
needs_account_data -> noul: JsonContent[value=Does answering require looking at the customer's account data?]
A model router that fails safe
Routing means sending easy requests to a cheap model and hard ones to a strong model. The risk is a wrong “easy” verdict, so the rule I wrote uses the answer’s confidence: take the fast path only when Jev says simple and is at least 80% confident. Everything else goes to the large model.
The middle line is the point. A low-confidence “simple” is treated as unknown. Choose the threshold by labelling a few hundred real tickets and measuring how often a “simple” verdict was wrong at each level. I did not do that. Combine this router with the provider switching shown in the provider comparison or the failover patterns in the LLM gateway post.
The vendor’s numbers, labelled as theirs
Claim from TypeSafe’s article
Value they report
Verified by me?
Median latency, one question
275 ms
No
Median latency, three questions
310 ms
No
Compared model claude-haiku-4-5
about $0.0018 per request, 1.8 s
No
Compared reasoning models
about $0.033 per request, 11 to 14 s
No
Overall
“10-125x faster, 22-805x cheaper”
No
They are comparisons on the vendor’s tasks, run by the vendor. Measure on your own tickets before you plan a budget around them.
What else is in typesafe-spring-ai 0.4.0 (listed, not run)
From the jar’s class list: JevChatModel (a Spring AI ChatModel), JevGuardrailAdvisor and JevGuardrail, JevSelfRefineAdvisor, JevToolIndex (a tool index in the spirit of Spring AI’s tool-search advisor) and a judge package with JevVerdict, JevCriterion, JevConsistency and JevConfidenceGate. The SDK also has typed exceptions for rate limiting, authentication and overload. I did not instantiate or call any of them, so I cannot tell you how they behave.
Compile and run the demo
Create a Maven project with the Spring Boot 4.1.1 BOM, spring-ai-starter-typesafe 0.4.0, typesafe-spring-ai 0.4.0, spring-boot-starter, spring-boot-test and assertj-core. The demo is a plain main method and needs no network.
Should you even do this? Think hard before you do. Your ticket text goes to a third party’s API, so check your data rules. The libraries are version 0.4, the model does not stream, and nothing I ran shows how accurate its verdicts are. A cheaper alternative for a simple router is a small model you already use, asked for a one-word answer with structured output; measure both before choosing. Jev earns a trial if you make many high-volume classification calls where latency matters, and you can validate it against labelled data.
No Comments yet!