Jev by TypeSafe AI: Fast, Typed Decisions for Classification

Imagine a support system reading a message: “I was charged twice, and I need a person to fix this today.” It does not need an essay. It needs to decide which team gets the ticket, whether the customer requested a human, and how urgent the issue is. TypeSafe AI’s Jev is designed for precisely this kind of work: it takes a state and a set of questions, then returns constrained answers and probabilities rather than generating a paragraph. That makes Jev interesting for low-latency classification and routing, provided you still measure errors on your own data.

1. What is Jev, and why does it matter?

Think of a conventional language model as a capable colleague asked to write the answer on a form. Jev is closer to a colleague asked to tick predefined boxes. Your program provides the boxes and decides what to do with the result. TypeSafe calls Jev its first System One model, borrowing the name from fast, intuitive judgment. This is a product category name, not a claim that the model thinks like a person.

An LLM can also produce JSON or select from a schema. Jev does not invent structured output. Its distinction is a decision-oriented interface: answers are constrained to the question types you specify, and multiple questions about the same input can be evaluated in one request without generating an explanation token by token. This removes the need to recover a decision from prose, but a valid output shape does not guarantee a correct judgment. A perfectly typed route to the wrong department is still a mistake.

This distinction matters especially inside an agent workflow. One model call may choose a tool, another may judge its result, and a third may decide whether to continue. If those calls only choose among known outcomes, a decision model can handle some of them while a generative model still does the writing, planning, and explanation. Jev is a companion to that model, not a substitute for it.

jev-state-to-code-decision

2. The three question types Jev answers

The TypeSafe primitives documentation defines three ways to ask about a shared state (the text or structured record under evaluation):

Question typeExample questionWhat comes backExample use
Choice (pick an option)Which team should handle this ticket?A selected team, probability for each option, and confidenceRoute the ticket to billing, technical, or another team.
Noul (yes or no)Did the customer ask for a person?Probability of “yes” from 0 to 1; no separate confidence fieldFlag a request for human review.
Score (ordered levels)How severe is the issue: minor, degraded, or blocking?Probability for each level, a weighted position on the scale, and confidenceAssess severity using a defined rubric.

For the team question, Choice could offer billing, technical, returns, and other. Include other so the model can indicate that none of the named teams fits. If a ticket could belong to more than one team, your code can use the probabilities to flag it for review rather than automatically trusting the top choice.

For the human-request question, Noul returns a probability of “yes,” not a separate confidence score. For severity, you define Score’s ordered levels, such as minor, degraded with workaround, and blocking without workaround. Score then places the ticket along that scale; it does not invent a new rating category.

You can ask all three questions about the same ticket in one call. Each question reads the ticket, but not the answers to the other questions. If a question needs an earlier answer or new information, make a second call. Otherwise, ask the questions together and let your code combine the results.

jev-three-answer-shapes

3. What the probabilities mean in Jev

Suppose a Choice question assigns probabilities $p_k$ to $K$ departments. They form a distribution:

$$
0 \le p_k \le 1, \qquad \sum_{k=1}^{K} p_k = 1, \qquad \hat{k} = \operatorname*{argmax}_k p_k.
$$

The selected department $\hat{k}$ is the most probable option, not necessarily a safe option for automatic action. For Noul, $p$ is the model’s probability that a yes/no statement is true; it is not the intensity of the underlying property. A Noul value of $0.5$ for “Is this customer angry?” means uncertainty about the proposition, not “half angry.”

For a Score with levels numbered $0$ through $L-1$, the returned score is the probability-weighted mean:

$$
s = \sum_{\ell=0}^{L-1} \ell\,p_{\ell}.
$$

If a severity rubric has probabilities $(0, 0.57, 0.43)$ across levels $0$, $1$, and $2$, then $s=1.43$. This is a position between rubric levels, not 1.43 incidents or a probability of harm. Two different distributions can produce the same score, so inspect the distribution before automating a consequential decision. TypeSafe’s confidence guide describes confidence for Choice and Score as a summary of how concentrated the returned probabilities are. Confidence is not the same as measured accuracy.

jev-score-expected-rubric-position

For probabilities to guide decisions reliably, test calibration on labeled examples. If, among many cases assigned a probability near $0.8$, roughly $80\%$ are correct, those estimates are calibrated in that range. TypeSafe says Jev uses reinforcement learning for calibrated decisions (RLCD), but this training objective is not proof that probabilities will be calibrated on your domain. Plot predicted probability against observed frequency, evaluate proper scoring rules such as the Brier score, and inspect error rates and thresholds. See our guides to model calibration and classification metrics.

model-calibration-illustration

4. Why can Jev be fast?

An autoregressive LLM typically emits an answer one token at a time. According to TypeSafe’s description, Jev instead produces constrained decisions using a parallel sampling approach, so it need not write a long response before code can act. TypeSafe describes its training as RLCD. The published materials describe the interface and goals, but do not provide enough architectural or training detail to reproduce Jev, so we should not infer layer counts or a specific loss function.

Speed claims need context. In a LiteLLM routing benchmark published in September 2026, a pinned Jev version took 126.81 ms median for classification, compared with 688.40 ms for Claude Haiku 4.5, or about 5.43 times faster on that setup. LiteLLM ran 80 authored cases three times per classifier. The comparison measures classifier-call latency, not end-to-end answer speed or throughput; the expected tiers were written by the same author as the prompts and were not independently adjudicated. TypeSafe also advertises roughly 70–500 ms response times in its own evaluations, but geography, network, input size, question count, and load all matter. Its published model price is $0.042 per million input tokens, with no charge for output tokens; that is a provider rate, not the total cost of downstream models, network calls, failures, or manual review. Routing routine requests to lightweight classifiers is a key pattern for reducing LLM operational costs, but net savings depend on query distribution and downstream review overhead. Benchmark against the alternative you would actually deploy, including simple rules and conventional logistic regression when labeled data is available.

jev-vs-autoregressive-llm-classifier

5. Build a ticket router using Jev

The official quick start documents the Python SDK. With Python 3.10 or later, install it using pip install typesafe-sdk, obtain an API key from the TypeSafe dashboard, and set the TYPESAFE_API_KEY environment variable. The hosted request requires network access and an account; the code below does not make a call until you run it with a valid key.

Python
"""Route a support ticket using Jev's typed decisions."""

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient


def triage(ticket: str) -> dict[str, object]:
    # The same state is evaluated against all three questions in one call.
    with TypeSafeClient() as client:
        response = client.system_one(
            model="jev-latest",
            state=ticket,
            questions={
                "team": Choice(
                    instructions="Which team should own this customer's main issue?",
                    criteria={
                        "billing": "Duplicate charges, invoices, payments, refunds",
                        "technical": "Product errors, outages, broken integrations",
                        "returns": "Exchanges, returns, damaged goods",
                        "other": "None of the listed teams fits the main issue",
                    },
                ),
                "human_requested": Noul(
                    instructions="Does the customer explicitly ask for a human agent?",
                ),
                "severity": Score(
                    instructions="How severe is the reported service problem?",
                    criteria=[
                        "Minor issue with little impact",
                        "Feature degraded, but a workaround exists",
                        "Blocking issue with no known workaround",
                    ],
                ),
            },
        )

    team = response.answers["team"]
    human = response.answers["human_requested"]
    severity = response.answers["severity"]

    # Example policy, not a threshold endorsed or calibrated by TypeSafe.
    # A direct request for a person takes priority over automatic routing.
    if human.noul >= 0.8:
        action = "human_review"
    elif 0.2 < human.noul < 0.8 or team.confidence < 0.6:
        action = "human_review"
    elif team.choice == "other":
        action = "human_review"
    else:
        action = f"queue_{team.choice}"

    return {
        "action": action,
        "team_probabilities": dict(team.probabilities),
        "human_request_probability": human.noul,
        "severity_score": severity.score,
        "severity_probabilities": dict(severity.probabilities),
        "model": response.model,  # Log the resolved version, not just the alias.
    }


if __name__ == "__main__":
    ticket = "I was charged twice. Please let me speak to a person today."
    print(triage(ticket))

Notice what the code does not do: it does not issue a refund just because the ticket mentions one. It sends uncertain or explicitly escalated cases for review. It also preserves the probabilities for auditing. The jev-latest alias can change when TypeSafe releases a version, so record response.model and pin a version when comparing thresholds over time. The API accepts text state and structured textual fields, not raw images or audio.

jev-ticket-router-review-gates

6. Where Jev adds value, and where it does not

Agent decisions, without replacing the agent

In a structured agent harness, a supervisory wrapper manages execution state, tool policies, and model dispatch. LangChain’s Jev integration shows two uses: choosing a model for a request and flagging risky tool calls. Jev can judge whether a task is simple or complex, or whether a proposed command needs review. Application code then makes the routing or approval decision, acting as part of broader guardrails for LLMs to prevent unintended actions. Jev cannot enforce permissions: use access controls and sandboxes for that. Use real test results, not a model’s judgment, to determine whether tests passed.

Search and high-volume classification

Search can first find a shortlist of passages. Jev can then ask whether each passage answers the query and use its yes-probability to reorder the list, as shown in TypeSafe’s re-ranking walkthrough. It cannot find a passage that search missed. See also reranking in RAG. Jev can similarly classify tickets or documents in bulk.

When another tool is better

Deciding when to use deterministic code, specialized discriminative models, or generative LLMs follows the principles of our compass for choosing rules, ML, and GenAI:

  • Use code for arithmetic, exact matches, permissions, tests, and other verifiable rules.
  • Use a generative model for open-ended answers or reasoning that depends on earlier steps. If the parts are independent, ask Jev separately and combine the results in code.
  • Extract unknown identifiers first. Jev can judge known candidates, but Choice cannot invent a new option, and Score stays within its defined rubric.

For Jev questions, provide only relevant state rather than a long, unrelated history.

jev-code-llm-right-component-workflow

7. Practical evaluation and deployment checklist

  1. Define the decision. Choose Choice, Noul, or Score; distinguish options, include other when needed, and define Score levels. Version the questions and criteria.
  2. Evaluate before rollout. On held-out real cases, measure confusion matrices, error costs, calibration, and median and 95th-percentile latency. Include long, ambiguous, multilingual, and multi-intent inputs. Compare with rules or classical ML, then shadow-test before live routing.
  3. Set cost-aware thresholds. For a calibrated yes-probability $p$ and only false-positive and false-negative costs $C_{\mathrm{FP}}$ and $C_{\mathrm{FN}}$, act when $p > C_{\mathrm{FP}}/(C_{\mathrm{FP}}+C_{\mathrm{FN}})$. Otherwise, use a review band and validate it on real cases.
  4. Fail safely. Set deadlines and fallbacks for rate limits, outages, and invalid responses. Keep API keys server-side; require independent controls for payments, access, and safety-critical actions.
  5. Monitor and retest. Log resolved model, question and criteria versions, input mix, decisions, reviews, outcomes, total cost, and end-to-end latency. Replay a held-out set before releases; watch for data and concept drift and retest or recalibrate after model or rubric changes.

Jev is a decision component, not a chatbot, rule engine, or proven domain classifier. TypeSafe’s model documentation lists text input, moving aliases, English as its strongest language, and no per-customer weight fine-tuning. Use another tool for long explanations or multi-step reasoning, or combine independent judgments explicitly in code.

Summary

Jev turns a state and well-defined questions into typed decisions: Choice for categories, Noul for yes/no probabilities, and Score for ordered rubrics. It can complement an LLM by handling bounded judgments around generation, but schema correctness and model confidence are not substitutes for accuracy. Start with one low-stakes routing task, shadow-test it against representative tickets, compare it with your current baseline, and let observed errors and end-to-end cost guide whether Jev belongs in production.

Machine Learning Engineer at HP | Website |  + posts

Happy is a seasoned ML professional with over 15 years of experience. His expertise spans various domains, including Computer Vision, Natural Language Processing (NLP), and Time Series analysis. He holds a PhD in Machine Learning from IIT Kharagpur and has furthered his research with postdoctoral experience at INRIA-Sophia Antipolis, France. Happy has a proven track record of delivering impactful ML solutions to clients. Check more about him here: https://sites.google.com/site/slhappyin/

Silpa brings 5 years of experience in working on diverse ML projects, specializing in designing end-to-end ML systems tailored for real-time applications. Her background in statistics (Bachelor of Technology) provides a strong foundation for her work in the field. Silpa is also the driving force behind the development of the content you find on this site.

Subscribe to our newsletter!