DEV Community

Cover image for Jev Is Not an LLM. That Is the Point.
Safdar Ali
Safdar Ali

Posted on

Jev Is Not an LLM. That Is the Point.

Most "AI features" are not writing tasks. They are decisions.

Is this ticket urgent? Which queue owns it? Is this shell command safe to run? Should this request go to a small model, a large one, or a person?

A language model can answer all of those. It does it by generating text, one token at a time, even when you asked for JSON. Jev, from TypeSafe AI, does not generate text at all. You hand it a piece of state and a set of questions whose answers you already defined. It fills those answers in one pass and attaches a confidence score to each one.

That tradeoff is the product. Jev cannot write the email, the summary, or the code. Your program still decides what to do with the judgment.

What you are actually calling

TypeSafe calls Jev a System One model, after the fast, intuitive half of Daniel Kahneman's Thinking, Fast and Slow. The name Jev comes from William Stanley Jevons: when a resource gets cheap enough, people find far more uses for it. The bet is that a decision cheap enough to put inside ordinary control flow gets used in places a frontier chat model never will.

The interface is closer to a function than to a chat:

A language model Jev
Output A string you parse A value you declared up front
Sampling One token after another Every answer in the same request
Uncertainty Only if you ask, and often overconfident A confidence score on every answer
Failure mode Wrong words, broken JSON, a type you did not expect A wrong choice inside the types you allowed

TypeSafe's published pricing is $0.042 per million input tokens, with output tokens not billed. They report end-to-end times of about 70–500ms, and on their own workflow evals they cite figures around 190× faster and 440× cheaper than the large models they compared against. Those numbers are their benchmark, on workflows their own team wrote, scored against other labs' models. Treat them as a reason to measure your path, not as a number to put in a launch post.

Schema match is a harder claim, and a narrower one. Jev cannot return a string when the field is an enum. It can still pick sales when billing was right. You fixed the shape. You did not get correctness for free.

Put the question on the type, not in the prompt

If you have used Pydantic AI, the call looks like any other structured-output agent. Install the TypeSafe extra and set TYPESAFE_API_KEY.

pip install "pydantic-ai-slim[typesafe]"
export TYPESAFE_API_KEY="your-api-key"
Enter fullscreen mode Exit fullscreen mode

The habit that does not carry over from a language model: the prompt is only the material being judged. The questions live on the output type. A question written into the prompt is more text to judge, not an instruction.

from typing import Literal

from pydantic import BaseModel, Field
from pydantic_ai import Agent

class Ticket(BaseModel):
    """Triage a support ticket."""

    urgent: bool = Field(description="Does this need a reply within the hour?")
    area: Literal["billing", "bug", "account", "other"] = Field(
        description="Which team owns it?"
    )

agent = Agent("typesafe:jev-latest", output_type=Ticket)
result = agent.run_sync(
    "You charged me twice and my account is overdrawn. I need this reversed today."
)
print(result.output)
# urgent=True area='billing'
Enter fullscreen mode Exit fullscreen mode

Several fields go out together. That is where the latency win comes from: independent judgments are not separate generation rounds. Extra fields cost input tokens, not another round trip.

Ask one thing per field. "Is this a good ticket?" is several judgments wearing one name. Jev will still return something, often with low confidence, and you will notice too late. Split it. Combine the answers in code, where the rule is exact.

A str field, an unbounded number, or a datetime is rejected before the request is sent. If the answer is prose, this is the wrong model.

Confidence is the part you branch on

A boolean becomes True when Jev's probability of yes is at least typesafe_boolean_threshold, which defaults to 0.5. That default is a coin flip. It is the wrong bar when the two mistakes do not cost the same. Raising the threshold means a True has to be earned, which is what you want for "safe to run this command with no one watching."

The margin on each field is on the response, not on the model instance:

details = result.response.provider_details or {}
confidence = details.get("confidence", {})
# {'urgent': 0.91, 'area': 0.74}  — illustrative
Enter fullscreen mode Exit fullscreen mode

confidence here is a margin, not "the probability this label is correct." For a yes/no it measures how far the probability sits from the threshold that decided it. For a pick-one, the full distribution is in provider_details['probabilities'].

A practical split:

  • High margin: let code act.
  • Middle: send the same state to a stronger generative model.
  • Low: ask a person.

jev-latest moves when TypeSafe ships a release, and the numbers under a tuned threshold can move with it. Once a bar is calibrated on your own labels, pin a version such as typesafe:jev-1.13.0.

If the honest answer is sometimes "not enough information," put that in the type. A yes/no with no third option forces a side.

Where it fits, and where it does not

Use Jev for the small semantic branch that used to be either a brittle regex or a full model call:

  • Routing a ticket, a tool call, or a model.
  • Scoring a rubric you defined (ordered levels, each one described).
  • Checking an agent step: did it finish, did it leave the requested scope, does a human need to see this?
  • Guardrails around something a language model already wrote.

Keep a language model for generation and for reasoning that does not fit in one judgment. Keep ordinary code for rules you can write down: amount greater than a limit, a missing field, an allow-list. Jev sitting in the middle does not replace either of those.

Two design limits are worth knowing before you sketch an architecture. Choice lists top out at 255 options, and a high-cardinality pick may be scored in two stages. Fields in the same request are independent, so one answer cannot depend on another answer from that same call. If the second judgment needs the first, make them two steps.

A small architecture, not a new model in every slot

exact rule            → code
bounded judgment      → Jev
writing or reasoning  → a language model
high-stakes uncertainty → a person
Enter fullscreen mode Exit fullscreen mode

The useful question is not which model to standardize on. It is what kind of intelligence a given step needs. If the step is a decision with answers you can name in advance, generating those answers token by token is a lot of machinery for a branch.

Jev is in early access. The TypeSafe announcement has their evals and the caveats attached to them. The Pydantic AI TypeSafe docs are the practical reference for field types, thresholds, and provider_details.


☕ If This Helped You

I publish free tutorials and write-ups like this regularly.

If this article saved you time:

👉 Buy me a coffee:

https://buymeacoffee.com/safdarali

👉 Subscribe to my YouTube channel (free):

https://www.youtube.com/@safdarali_?sub_confirmation=1

More about how I work: safdarali.in/about
Projects and case studies: safdarali.in/projects

Top comments (0)