Résumez cet article avec :
TypeSafe AI's Jev is the first System One Model: instead of generating text one token at a time, it takes program state plus typed questions and returns structured decisions with calibrated probabilities in a single parallel pass. This guide explains what that changes architecturally, then walks through building a working model router where Jev classifies each incoming request and Eden AI executes it against the right model. It covers the Choice, Score and Noul question types, confidence thresholds and fallback paths, a complete runnable Python router, and an honest look at where a decision model beats a fine-tuned classifier and where it does not.
Large language models have become remarkably good at understanding instructions, writing code, and reasoning through hard problems. But a large share of the work inside a production AI application isn't generation at all. It's decisions.
Which category does this request belong to? Which tool should the agent call next? Should this go to a fast model or a reasoning model? Is this retrieved document relevant? Should this result be auto-approved or sent for review?
These decisions are often tiny compared with generating an entire answer. Yet traditional LLMs are frequently used to make them, requiring a model to generate tokens even when the software ultimately needs only a label, score, or boolean decision.
Jev, the first public System One Model from TypeSafe AI, takes a different approach. Instead of generating strings for humans to interpret, Jev is designed to return structured, probabilistic decisions that software can consume directly.
The result is a model aimed at a different layer of the AI stack: not the model that writes the final answer, but the intelligence that decides what should happen next.
What is Jev ?
TypeSafe AI released Jev on September 15, 2026, alongside $40 million in funding, led by DCVC. The company was founded by Diogo Almeida, who co-invented RLHF and InstructGPT at OpenAI.
Jev is a text-input decision model: it evaluates a block of state against a set of typed questions and returns a structured answer for each one, with a probability distribution and a confidence value, in a single API call. It generates no text. The answer space for every question is enumerated in the request, so the response is a value from a set you defined, not a string to parse.
Two practical notes before you plan around it. Jev is proprietary and served from TypeSafe's own hosted API, currently behind an early-access waitlist — there are no published weights and no on-prem option today. And while it can't emit a value outside the answer space you define, which removes schema and parse failures, it can still be confidently wrong.
The Problem: We Keep Asking LLMs to Do Everything
The dominant architecture of modern AI applications is simple: a user sends a request, an LLM reads it, the LLM generates a response. This works extremely well when the output itself is language.
But consider an application receiving thousands of requests per minute. Before calling an expensive frontier model, it may need to know whether this is a coding request, whether it requires vision, whether it's a simple question or a hard reasoning task, and whether it should be handled automatically or escalated. The application ultimately needs one value:
"coding"
A conventional LLM still reaches that value through autoregressive text generation — generating tokens sequentially, paying for them, waiting for them, then parsing the result back into a structure. Jev starts from the other end. Instead of asking "What should I write?", the model is built around "What decision should I make?"
From Strings to Decisions
TypeSafe calls this family System One Models. The name refers to Daniel Kahneman's distinction between fast, intuitive System 1 thinking and slow, deliberate System 2 reasoning, and the trade it names is explicit: giving up free-form text generation in exchange for parallel sampling, guaranteed schema conformance, and a probability attached to every answer.
The central idea: decisions, not strings.
A conventional LLM might return "This looks like a technical support request related to authentication. It would probably be best handled by…", and your application then has to interpret that text. With Jev, you declare the decision space before inference — the model picks from it and attaches probabilities. There's no asking a model to produce JSON and hoping the JSON matches your schema.
The second architecture is much closer to how ordinary software already works.
Three Primitives: Choice, Score, and Noul
Jev exposes a small set of question types that you compose into larger decision systems. Every request carries a model, a state (a string, object, or array), and a non-empty questions object. Each question requires a type and instructions.
The exact bounds matter when you design a schema. Choice takes 1–255 categories; Score takes an ordered array of 2–10 levels; Noul needs no criteria at all. You can send many questions in one request, and the answers come back under the same keys you used for the questions.
Why Probabilities Matter
Jev doesn't just return an answer, it returns information about its own uncertainty. TypeSafe calls the training approach Reinforcement Learning for Calibrated Decisions (RLCD), and it optimises for those probabilities being honest rather than for human preference, as RLHF does.
Compare a routing decision that looks like this:
technical: 0.86
billing: 0.11
sales: 0.03
with one that looks like this:
technical: 0.37
billing: 0.34
sales: 0.29
Both have a winner. Only one of them should be automated.
A word of caution that TypeSafe's own material makes, and that's worth repeating: a probability is not a guarantee of correctness. Reported probabilities can be rounded and may not sum to exactly one, a reported label can differ from a calculation over the estimates, and probabilities and confidence are not demonstrated accuracy guarantees or permission to act. Calibrate your thresholds against your own labelled traffic.
Why Jev Can Be So Fast
Traditional autoregressive models produce output sequentially. Each token depends on the one before it.
That makes sense when the objective is an arbitrary-length piece of language. It's less obviously necessary when the answer is technical or 0.82.
Jev is non-autoregressive: it ingests one state, evaluates every question against it in parallel, and returns all answers in a single pass in 70 to 500 milliseconds. The published figures are striking — TypeSafe's own comparison shows Jev completing a System One task in 0.114 seconds against 8.566 seconds for a frontier LLM, at $0.000081 against $0.013880, which it summarises as 193.6x faster and 444.6x cheaper. Pricing is $0.042 per million input tokens, with output billed at zero.
Treat those as vendor benchmarks on vendor-selected workflows. The durable idea isn't the multiple — it's that a decision doesn't require a generative model to behave like a chatbot.
"Why Not Just Use a Classifier?"
This is the question an experienced engineer asks before the routing question, and it deserves a straight answer. Text classification is a solved problem. Fine-tuned BERT, embeddings plus logistic regression, and small models with structured output modes all classify well and cost almost nothing.
Where a System One model differs:
- No training data and no training run. A fine-tuned classifier needs a labelled dataset per task. Jev takes a schema written in the request, so you can ship a new decision in the time it takes to write a dictionary.
- Schema changes are free. Adding a fifth routing category to a fine-tuned classifier means relabelling and retraining. Here you add a key to
criteria. - The rubric travels with the call. State and questions are sent together on every request, so there's no separate rubric-registration step.
- Calibration is the training objective, not an afterthought you patch with temperature scaling.
- Frontier-level semantics. A small classifier struggles with requests that need world knowledge or subtle intent. That's exactly where routing decisions get hard.
The honest counterpoint: if you have a stable, high-volume, narrow classification task and plenty of labelled data, a fine-tuned small model will likely be cheaper and just as accurate. System One models earn their place when the decision space changes often, when there's no labelled data, or when the judgement needs real semantic understanding.
Jev Is Not a Smaller Chatbot
It's tempting to ask whether this is simply a small LLM, but that misses the architectural point: the model is optimised around a different interface. A general-purpose LLM is designed to generate strings; Jev is designed to answer predefined questions about a state and return typed decisions.
The trade-off is deliberate. Jev is not the model you'd ask to write a blog post, produce a long explanation, generate an application, brainstorm, or write an email. It's aimed at decisions made inside software — classification, routing, scoring, extraction — rather than at chat. That makes it complementary rather than competitive.
Building a Custom Router with Jev + Eden AI
Model routing is the clearest application. A modern application might have a fast model for simple requests, a coding model for programming tasks, a reasoning model for hard problems, a multimodal model for images, and a cheap model for bulk classification. The challenge is deciding which one receives each request.
The interesting move is to separate routing intelligence from model execution — and you can do both through Eden AI with a single API key. Eden AI serves Jev through a dedicated decisions endpoint, and names that endpoint for the capability rather than the vendor, so a second provider of decision models lands on the same path.
One important note before you build. The decisions endpoint is in alpha: its request and response shapes, the model ids it exposes, and its pricing can change in ways that break existing integrations, without a deprecation period. Eden AI's own advice is to keep the call behind a small adapter of your own, so a shape change is one edit rather than many.
Step 1: Define the Routing Categories
Suppose we're building a general-purpose assistant with four categories, each mapped to a model available through Eden AI:
MODEL_BY_CATEGORY = {
"simple": "google/gemini-2.0-flash",
"coding": "anthropic/claude-sonnet-4",
"reasoning": "openai/gpt-5",
"creative": "anthropic/claude-sonnet-4"
}
Check your ids against the catalogue before shipping — Eden AI uses the provider/model format everywhere in V3, and the list moves as providers ship. You can discover the decision models the same way:
import requests
response = requests.get("https://api.edenai.run/v3/alpha/decisions/models")
print(response.json())
{
"object": "list",
"data": [
{ "id": "typesafe/jev-latest", "object": "model", "owned_by": "typesafe" },
{ "id": "typesafe/jev-preview", "object": "model", "owned_by": "typesafe" }
]
}jev-latest is the current stable model and jev-preview is the newest build, stable or not. Both resolve to a concrete version, which the response reports back in its model field. Pin that concrete version once you've tuned thresholds against it.
The routing logic doesn't need to know how any of those models are implemented. It only needs category → model.
Step 2: Ask Jev to Classify the Prompt
The user prompt becomes the state. The categories become a choice question whose criteria map each option name to a description of when it applies. Describe your criteria rather than just naming them — a bare option key works, but a sentence about when it applies works better, and a structured description better still.state. The categories become a choice question with a criteria object — each option name mapped to a short description that tells Jev what belongs there.
import requests
EDENAI_API_KEY = "..."
DECISIONS_URL = "https://api.edenai.run/v3/alpha/decisions"
def classify(user_prompt: str) -> dict:
response = requests.post(
DECISIONS_URL,
headers={
"Authorization": f"Bearer {EDENAI_API_KEY}",
"Content-Type": "application/json",
},
json={
"model": "typesafe/jev-latest",
"state": user_prompt,
"questions": {
"task_type": {
"type": "choice",
"instructions": "What kind of task is the user asking for?",
"criteria": {
"simple": "Short factual questions, lookups, small edits",
"coding": "Writing, debugging or explaining code",
"reasoning": "Multi-step analysis, math, planning, hard problems",
"creative": "Stories, marketing copy, brainstorming, tone work",
},
}
},
},
timeout=5,
)
response.raise_for_status()
return response.json()
Note that state doesn't have to be a string. Pass an object or an array when the shape itself carries meaning and the model will read the structure — useful if you're routing on more than the raw prompt (user plan, conversation length, attachment types).
The response wraps everything under answers, keyed by the names you chose, and reports the concrete model version plus the exact cost of the call:
{
"model": "jev-1.13.0",
"answers": {
"task_type": {
"type": "choice",
"choice": "coding",
"confidence": 0.91,
"probabilities": {
"coding": 0.91,
"reasoning": 0.05,
"simple": 0.02,
"creative": 0.02
}
}
},
"usage": { "input_tokens": 118, "output_tokens": 24 },
"cost": 0.00000496
}
Pulling the decision out is two lines:
answer = classify(prompt)["answers"]["task_type"]
category = answer["choice"]
confidence = answer["confidence"]
Notice what didn't happen. Jev generated no explanation, produced no final answer, and called no LLM. It made exactly the decision the application asked for — and told you what it cost.
Step 3: Send the Prompt to Eden AI
Once the model is selected, the original prompt goes to Eden AI's OpenAI-compatible chat completions endpoint. Same key, different path:
from openai import OpenAI
eden = OpenAI(
api_key=EDENAI_API_KEY,
base_url="https://api.edenai.run/v3"
)
response = eden.chat.completions.create(
model=MODEL_BY_CATEGORY[category],
messages=[{"role": "user", "content": user_prompt}],
)
answer = response.choices[0].message.content
One caveat worth knowing: the decisions endpoint is not a base-URL swap away from chat completions. Eden AI's docs are explicit that you point your client at /v3/alpha/decisions directly rather than swapping a base URL — the request and response bodies match TypeSafe's own, but the path does not. So the decision call stays on requests, while the generation call uses the OpenAI SDK.
Two clean responsibilities:
/v3/alpha/decisions
↓
"What should handle this?"
/v3/llm/chat/completions
↓
"Let that model handle it."
Step 4: Add Confidence-Aware Routing
The router gets genuinely useful once you use the distribution rather than just the winner. A choice answer carries its own confidence alongside the full probability distribution, so there's nothing to compute. Suppose Jev returns:
coding: 0.49
reasoning: 0.44
simple: 0.04
creative: 0.03
Picking coding automatically is aggressive , the model is telling you it can't separate two categories. Use confidence as a routing signal and send low-confidence decisions to a human or to a bigger model rather than treating every answer as final:
if confidence >= 0.80:
model = MODEL_BY_CATEGORY[category]
else:
model = FALLBACK_MODEL # more capable, more expensive0.80 is not a universal value. Log your routing decisions alongside outcomes for a week, then pick a threshold based on what a misroute actually costs you, and record which model version you tuned against, since the response reports the concrete version it came from.
One asymmetry to remember: a noul answer has no confidence field, because the number is already the answer and its own confidence. Use how far its probability sits from 0.5:
def noul_confidence(p: float) -> float:
return abs(p - 0.5) * 2
Step 5: Go Beyond Categories
One request can carry as many questions as you like, answered together over the same state. Asking three questions costs barely more than asking one, because the state is only read once. So ask more than one:
"questions": {
"task_type": {
"type": "choice",
"instructions": "What kind of task is this?",
"criteria": { ... },
},
"complexity": {
"type": "score",
"instructions": "How complex is this request?",
"criteria": ["trivial", "moderate", "hard", "research-level"],
},
"requires_code": {
"type": "noul",
"instructions": "Does answering this require writing or reading code?",
},
"requires_vision": {
"type": "noul",
"instructions": "Does this depend on an image or visual input?",
},
}
Score criteria must be ordered lowest to highest, because the index is the score. The returned value is the probability-weighted average, so it can land between levels, and a legend echoes your rubric back so you can read the number:
{
"complexity": {
"type": "score",
"score": 2.4,
"confidence": 0.78,
"legend": {
"0": "Trivial: a single lookup or one-line answer",
"1": "Moderate: needs a few steps or some context",
"2": "Hard: multi-step, ambiguous, or domain-specific",
"3": "Research-level: open-ended, needs deep analysis"
},
"probabilities": { "0": 0.01, "1": 0.09, "2": 0.39, "3": 0.51 }
},
"requires_code": { "type": "noul", "noul": 0.97 },
"requires_vision": { "type": "noul", "noul": 0.02 }
}
A 2.4 sits between "hard" and "research-level". Your policy can then combine the signals — note that a noul value comes back under the key noul, not probability:
if answers["requires_vision"]["probability"] > 0.8:
model = VISION_MODEL
elif answers["requires_code"]["probability"] > 0.8 and answers["complexity"]["score"] < 1.5:
model = FAST_CODING_MODEL
elif answers["complexity"]["score"] > 2.0:
model = REASONING_MODEL
else:
model = DEFAULT_MODEL
Phrase questions positively where you can. A decision model reads instructions literally, and negations and implications are easy to get wrong: "Does this require code?" routes better than "Is this not a coding task?".
This is where Jev begins to look less like a replacement for an LLM and more like a programmable intelligence layer.
The Complete Router
Everything Jev-specific lives in pick_model, so an alpha shape change is one edit:
import requests
from openai import OpenAI
EDENAI_API_KEY = "..."
DECISIONS_URL = "https://api.edenai.run/v3/alpha/decisions"
DECISION_MODEL = "typesafe/jev-latest"
FALLBACK_MODEL = "anthropic/claude-sonnet-4-5"
THRESHOLD = 0.80
MODEL_BY_CATEGORY = {
"simple": "google/gemini-2.5-flash",
"coding": "anthropic/claude-sonnet-4-5",
"reasoning": "openai/gpt-5",
"creative": "anthropic/claude-sonnet-4-5",
}
CRITERIA = {
"simple": "Short factual questions, lookups, small edits",
"coding": "Writing, debugging or explaining code",
"reasoning": "Multi-step analysis, math, planning, hard problems",
"creative": "Stories, marketing copy, brainstorming, tone work",
}
eden = OpenAI(
api_key=EDENAI_API_KEY,
base_url="https://api.edenai.run/v3/llm",
)
def pick_model(user_prompt: str) -> tuple[str, float | None]:
"""Ask Jev which model should handle this prompt.
The only place that knows the decisions endpoint's shape. The endpoint is
in alpha, so keep the coupling here and nowhere else.
"""
try:
r = requests.post(
DECISIONS_URL,
headers={
"Authorization": f"Bearer {EDENAI_API_KEY}",
"Content-Type": "application/json",
},
json={
"model": DECISION_MODEL,
"state": user_prompt,
"questions": {
"task_type": {
"type": "choice",
"instructions": "What kind of task is the user asking for?",
"criteria": CRITERIA,
}
},
},
timeout=5,
)
r.raise_for_status()
answer = r.json()["answers"]["task_type"]
category = answer["choice"]
confidence = answer["confidence"]
except (requests.RequestException, KeyError, ValueError):
# Decision layer unavailable or shape changed: fail safe, not closed.
return FALLBACK_MODEL, None
if confidence < THRESHOLD:
return FALLBACK_MODEL, confidence
return MODEL_BY_CATEGORY.get(category, FALLBACK_MODEL), confidence
def route_and_answer(user_prompt: str) -> str:
model, confidence = pick_model(user_prompt)
print(f"→ routed to {model} (confidence: {confidence})")
response = eden.chat.completions.create(
model=model,
messages=[{"role": "user", "content": user_prompt}],
)
return response.choices[0].message.content
if __name__ == "__main__":
print(route_and_answer("Why does my useEffect fire twice in React 18?"))
Three design notes worth keeping. If the decision layer fails, the router degrades to a capable default rather than erroring, a router that can take down your whole application is worse than no router. MODEL_BY_CATEGORY.get(...) with a fallback means a future category added to CRITERIA but forgotten in the map degrades instead of throwing. And because you pay for input only, retrieve before you judge: send the relevant slice of state, not your whole document store.
On cost, the decision call is close to free next to the generation it protects. Decision models are billed on input only, with output free, at $0.042 per million input tokens; Eden AI's own worked example bills 430 input tokens and 73 output tokens at $0.00001806. Every response carries a cost field in USD, so you can log exactly what the routing layer is costing you and compare it against what the misrouting used to cost.
Why Put the Router Outside the LLM?
You could just ask an LLM which model to use, and for many applications that's fine. But if the router is itself a generative model, the routing step adds another generative inference call; extra latency, extra tokens, parsing overhead, variable output formats, and another output to validate.
Instead of:
Prompt → Generative LLM → Text explaining routing → Parser → Model selection
you can have:
Prompt → Jev → Typed decision → Model selection
Neither architecture is universally better. The point is that the router's job is fundamentally different from the generator's job, and Jev is explicitly built around that distinction.
Beyond Model Routing
Once structured decisions are cheap, they become a primitive you can use everywhere. TypeSafe's own examples include choosing the next tool or subagent in an agent loop, deciding whether to continue, retry, ask the user, or stop, scoring urgency or risk before an action, and verifying model outputs to enforce guardrails.
Agent routing. An agent uses Jev to pick which tool or workflow runs next, without burning a generation call on every hop.
RAG acceleration. Before an expensive retrieval or generation step, decide whether retrieved chunks are relevant, whether another retrieval pass is needed, or which index to query.
Query → Jev → Relevant?
├── yes → continue
└── no → retrieve againHigh-volume classification. Email triage, document sorting, moderation queues,where the output is just sales, support, billing, spam.
Automated review. Use confidence as a gate before a stronger model or a human reviewer. Particularly valuable when a wrong automated decision costs far more than an escalation.
Real-time loops. Interactive systems, games and agent loops need many small decisions without waiting on a large generative response each time.
Where Jev Fits in a Modern AI Stack
The architecture separates two questions: what should happen? and which model should do it? Jev handles the first. Eden AI provides the infrastructure for the second.
The Trade-Off
A general-purpose LLM can produce almost anything. Jev deliberately cannot, its output space is fixed before inference. That's a limitation when you need free-form generation and a strength when you know exactly what decisions you need.
Three caveats worth stating plainly before you design around it:
Accuracy is good, not superhuman. On TypeSafe's own four-workflow benchmark, Jev reaches roughly 68% accuracy, close to mid-tier LLMs, but far cheaper and faster. The win is economics and latency, not raw capability.
Type safety is not correctness. Jev can't emit a value outside your defined answer space, which eliminates schema and parse failures — but it can still be confidently wrong.
The endpoint is alpha. Eden AI serves Jev today, so there's no waitlist to clear; but the decisions endpoint is explicitly marked alpha: its request and response shapes, the model ids it exposes, and its pricing can change in breaking ways without a deprecation period. It's safe to experiment with and risky to put on a critical path. Keep the call behind a small adapter of your own, as the router above does, so a shape change is one edit rather than many. And note that Jev itself remains proprietary: no published weights, no self-hosted or on-prem option, so if you need data residency guarantees, this isn't yet the tool.
The useful framing isn't LLM versus Jev. It's LLMs plus decision models.
Final Takeaway
The industry has spent years making models better at generating language. Jev asks a different question: what if models were designed from the start to make decisions that software can consume directly?
The answer is a model built around typed outputs, calibrated probabilities, and parallel evaluation instead of open-ended text. That doesn't make generative LLMs obsolete — it suggests a more modular architecture, where a generative model writes the answer, a decision model decides which model should write it, and a gateway like Eden AI supplies the model layer underneath.
The result isn't one model doing everything. It's software in which different kinds of intelligence become composable primitives.
Ready to build the execution layer? Create a free Eden AI account and get one API key for 500+ models across 50+ providers, or browse the V3 API documentation to get your first chat completion running in under a minute.



%20(1).png)
