TypeSafe AI just released Jev, a new System One model that solves the most frustrating part of AI development. Unlike Claude, OpenAI Codex, or the models powering Cursor, which are built to reason and generate extensive prose, Jev is designed purely for split-second decisions. Most LLMs generate responses token by token even when you only need a simple structured decision. You end up wasting more time configuring the JSON parser, and it also costs you so many unnecessary tokens just to get a basic classification.
Jev does not play that game. It skips text generation entirely and directly predicts probabilities over defined typed outputs (Booleans, Choices, Scores). Code owns the workflow, Jev supplies the prediction. In this article I will explain how you can call Jev from Python to build reliable and cheaper AI classification.
What is Jev?
When you need an AI to route a request, score a document, or detect a jailbreak attempt, you are asking for a structured decision. Traditional LLMs treat this as a text generation problem. They have to generate tokens one by one, which is slow and expensive.
TypeSafe AI claims Jev can deliver responses in 70 to 500 milliseconds. It skips token generation entirely. Instead of predicting the next word, it predicts the probability of a specific classification.
This makes Jev ideal for:
- Model routing: Deciding if a simple query can go to a cheap model or if it needs a complex reasoning engine.
- Classification: Labeling tickets, determining urgency, or extracting intent.
- Scoring: Estimating relevance in Retrieval-Augmented Generation (RAG) pipelines.
- Guardrails: Fast checks for prompt injection or unsafe tool calls before passing the input to a generative model.
In my internal testing, the speed difference changes how you build. You can put Jev directly in the hot path of a user request without ruining the experience.
Setting Up the TypeSafe Python SDK
While the Vercel AI Gateway supports Jev natively for TypeScript, Python developers can use the direct TypeSafe API.
First, install the SDK:
pip install typesafe-sdk
or
uv add typesafe-sdk
Next, grab your API key from the TypeSafe AI dashboard and export it to your environment:
export TYPESAFE_API_KEY="your-api-key-here"
The SDK gives you a straightforward client. You do not need to worry about the underlying HTTP requests or retry logic for rate limits. The client handles 429 and 529 HTTP status codes automatically with exponential backoff.
Defining States and Questions
The core concept in Jev is pretty straightforward. You pass a state and a dictionary of questions.
The state can be a string, a dictionary, or a list. It contains the context Jev needs to make a decision. The questions are strongly typed definitions of what you want to know.
Python uses three main primitive types for questions, each fitting specific use cases:
Noul: A boolean yes/no question. Returns a probability. Use this for binary guardrails like jailbreak detection, spam filtering, or checking if a request requires human escalation.Choice: A multiple-choice question. Returns the most likely option and an optional distribution. Use this for categorical routing, such as sorting support tickets by department, intent detection, or picking which downstream LLM should handle a prompt.Score: A rating across defined levels. Returns a fractional score. Use this for measuring intensity or relevance, such as reranking search results in a RAG pipeline, scoring lead quality, or assessing customer frustration.
Here is an example of routing a customer support ticket:
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
state = {
"message": "I was charged twice and need the duplicate refunded today.",
"account_tier": "business",
}
with TypeSafeClient() as client:
response = client.system_one(
state=state,
questions={
"intent": Choice(
instructions="What is the customer's main request?",
criteria={
"refund": "The customer wants money returned.",
"technical_help": "The customer needs a bug or integration fixed.",
"other": "None of the options clearly fits.",
},
),
"is_urgent": Noul(
instructions="Does `message` explicitly communicate time pressure?"
),
"frustration": Score(
instructions="How frustrated does the customer appear?",
criteria=["Calm and neutral", "Concerned but civil", "Very angry"],
),
},
)
Notice how we define criteria. For Choice, it is a dictionary mapping keys to descriptions. Always include an “other” option. If you force Jev into a list that does not cover the input, it will pick the least wrong answer.
For Score, the criteria is an ordered list from lowest to highest.
Reading Probabilities and Confidence
Once you get the response, you do not need to parse JSON. The objects are already typed.
intent_answer = response.answers["intent"]
print(f"Choice: {intent_answer.choice}")
# Output: Choice: refund
print(f"Probabilities: {intent_answer.probabilities}")
# Output: Probabilities: {'refund': 0.95, 'technical_help': 0.03, 'other': 0.02}
urgent_answer = response.nouls["is_urgent"]
print(f"Urgent Probability: {urgent_answer.noul}")
# Output: Urgent Probability: 0.98
frustration_answer = response.scores["frustration"]
print(f"Frustration Score: {frustration_answer.score}")
# Output: Frustration Score: 1.8
The probability on a Noul is the likelihood that the statement is true. A value of 0.98 means it is almost certainly true. A value of 0.02 means it is almost certainly false. A value near 0.5 does not mean “medium intensity”. It means Jev is genuinely uncertain if the statement is true or false.
If you need to measure intensity, use a Score. The score comes back as a fractional value representing the probability-weighted mean of your levels. A score of 1.8 on our 0-to-2 frustration scale means the customer is very close to “Very angry”.
You can also read the confidence attribute on Choice and Score answers. This helps you build reliable fallback mechanisms. If the confidence is below a certain threshold, you can route the ticket to a human instead of relying on the automated classification.
When to Use (and When to Skip)?
Jev is a specialized tool. It does one thing exceptionally well: structured classification.
Use it when your application needs to branch on a decision. Use it when you are currently writing brittle regular expressions to parse LLM outputs. Use it for guardrails, routing, and intent detection.
Skip Jev if you need to generate text, summarize an article, or explain a concept. It literally cannot do those things.
The typed output guarantees the interface, but it does not guarantee truth. You still need to design good questions, provide enough context in the state, and validate the model’s accuracy on your specific domain data.
But once you have it dialed in, you will never go back to begging a model for valid JSON again.

