Skip to content
VDAI with VD

September 20, 2026 · 6 min read

Jev in LangGraph: Bounded Answers for Bounded Questions

Jev is a model that never generates text — it answers typed questions with calibrated probabilities. Where that fits in a LangGraph agent, with code, and where I would not use it.

  • LangGraph
  • Model Routing
  • Agent Guardrails

Count the model calls in an agent you run. Not the ones where the model writes an answer for a user — the ones where it picks a route, judges a risk, or decides whether to call a tool. In the agents I build, those decision calls outnumber the conversational ones, and every one of them is a paragraph of generated text that I parse back down into one word.

We pay for prose to get a boolean.

Disclosure: This is a tool read, not a measurement. Jev is in early access behind a waitlist; I have not run it in my own stack. Every performance figure below is reported by TypeSafe AI and labeled as such. Treat them as claims to verify, not results.

What Jev is

Jev is the first model from TypeSafe AI, announced in September 2026. It is deliberately not an LLM: it never generates text. You send it a state — a string, a JSON document, or a conversation — plus a set of typed questions, and it returns typed answers with calibrated probabilities. Three question primitives cover the space:

  • Choice — pick one of up to 255 options; returns per-option probabilities and a confidence.
  • Score — rate on an ordered 2–10 level scale; returns the score, its distribution, and a confidence.
  • Noul — yes or no; returns P(true).

Because the answer space is declared in the schema, a malformed or out-of-vocabulary answer is impossible by construction. There is no parsing step, no retry-on-invalid-JSON loop, no "the model answered maybe".

The LangChain integration (langchain-typesafe, Python only at the time of writing) exposes this as a TypeSafeClassifier — a Runnable, not a chat model. It composes into chains, gets traced in LangSmith, and never pretends to be something you can have a conversation with.

The use case: two decision points in one agent

Take a support-operations agent — the pattern I run in my own systems. A request comes in, the agent investigates with tools, and it can issue a refund through a refund_order tool. Two decisions in that loop are bounded questions that I currently answer with a prompted LLM:

  1. Routing. Is this request simple enough for a small local model, does it need a frontier model, or should a human look at it? Today that is a chat model instructed to "reply with one word", wrapped in parsing and a fallback.
  2. Risk gating. The agent proposes refund_order(order_id, amount). Is this call risky or outside its authorization? Today that is either a hardcoded allowlist or another prompted judgment call with an unreliable self-reported confidence.

Both are exactly Jev's shape. Here is the pattern against the September 2026 langchain-typesafe docs — field names shown as shape, not executed:

from langchain_typesafe import TypeSafeClassifier, Choice, Noul
from langgraph.graph import StateGraph

classifier = TypeSafeClassifier(model="jev-latest")

ROUTE = Choice(
    "Which path should handle this request?",
    options=["small-model", "frontier-model", "human-review"],
)
RISK = Noul("Is this tool call risky or outside its authorization?")

def classify_request(state):
    result = classifier.invoke(state=state["messages"], questions={"route": ROUTE})
    answer = result.choices["route"]
    # Low confidence is a route, not an error.
    if answer.confidence < 0.8:
        return {"route": "human-review"}
    return {"route": answer.value}

def gate_tool_call(state):
    result = classifier.invoke(state=state["tool_call"], questions={"risk": RISK})
    if result.nouls["risk"].probability > 0.3:
        return {"tool_result": "refused: escalated for review"}
    return None  # let the tool run

graph.add_node("classify", classify_request)
graph.add_conditional_edges(
    "classify",
    lambda s: s["route"],
    {
        "small-model": "small_model",
        "frontier-model": "frontier_model",
        "human-review": "human_review",
    },
)

Two things are worth noticing. First, the decision points are ordinary nodes with typed outputs — the graph stays explicit, and every decision lands on the trace with its probabilities attached. Second, the confidence value is the interesting output, not the label. A calibrated probability lets you threshold: act automatically above the floor, escalate below it. That is the same shape as uncertain being a state, not an error — low confidence becomes a first-class route instead of a swallowed exception.

A decision model answering routing and risk questions at the decision points of an agent loop

Bounded Choice and Noul questions move routing and risk decisions out of the chat model; generation stays with it.

Read diagram description

An incoming request first reaches a route decision answered by a decision model as a Choice question: small model, frontier model, or human review. The agent then proposes a tool call, and a second decision answers a Noul question, the probability the call is risky, against a confidence threshold. Below the threshold the tool executes; above it the call is refused and escalated. Both decisions land on a shared trace and evidence record. This is an illustrative sketch, not a deployment topology.

View full-size diagram(opens in a new tab)

The chat model still does what it is for: reading the request, writing the reply, proposing the tool call. The decision model answers the questions around it.

Reading the numbers honestly

TypeSafe's launch materials report internal "workflow evals" (security triage, invoice processing, customer service) against frontier LLMs:

ClaimJev (vendor-reported)Frontier LLM (vendor-reported)
Agreement with reference answers67.8%67.9–74.1%
Latency per decision~0.4s10–38s
Cost per decision~$0.0004$0.03–$0.18

Their harness, their reference answers, their adapter for the competing models — and TypeSafe is unusually candid that these gains are "on the higher end" and that pricing may be subsidized. The right reading is not "444× cheaper". It is narrower and more useful: a bounded-answer model can hold rough accuracy parity on classification-shaped work at a latency and price point that make per-request decisions cheap enough to put everywhere. If that survives independent benchmarks, the economics of routing and guardrails change. If it does not, the pattern in this post still stands — it just runs on a small local classifier instead.

Where I would not use it

No rationale. Jev returns a probability, not a reason. In the regulated work I do, an auditor does not accept "P(risky) = 0.87" as an explanation of why a refund was refused. You still need your own evidence trail for the why — the model gives you a decision, not a defensible one.

Bounded answers only. Anything open-ended — summarizing, drafting, extracting novel structure — still needs a generative model. This is a complement, not a replacement.

Data leaves your perimeter. The middleware pattern sends conversation state and tool-call arguments to TypeSafe's API. For agents touching client data, that is a procurement and privacy review before it is a code change.

Early access, one vendor. Waitlist today, one provider, pricing that may be subsidized. Nothing in my stack depends on it, and nothing should yet.

If you try it

  • Inventory your agent's decision points: routing, risk gates, retries, escalation.
  • For each, write the bounded question you are actually asking.
  • Check whether you need the reason or just the decision — that splits the list in half.
  • Threshold on confidence; route low-confidence to a human, never to a silent default.
  • Log the probabilities onto your traces so thresholds can be tuned from evidence.
  • Re-run the vendor's numbers on your own eval set before believing them.

The LangChain team has a harness walkthrough and the provider docs cover the integration surface. For the evaluation side of this pattern — scoring decisions after the fact without slowing the request down — see Tracing and Scoring RAG Without Slowing It Down.

Written by

Vishvdeep Dashadiya

Lead AI Engineer. Agentic AI, real-time ML systems, and cloud-native infrastructure.

About me

Keep reading

More posts

September 17, 2026 · 8 min read

“Uncertain” Is a State, Not an Error

Why ambiguous transaction outcomes must pause blind retries and move through evidence-led reconciliation.

Outcome ReconciliationIdempotency

September 5, 2026 · 8 min read

Tracing and Scoring a RAG Pipeline Without Slowing It Down

Every run of the pipeline becomes a nested Langfuse trace, and a judge model scores it with DeepEval. Neither adds a millisecond to the response, because scoring starts after the client already has the answer. The wiring: a per-request callback, a fire-and-forget task that cannot fail the request, a judge decoupled from the graph LLM, and an offline golden set for the metrics live traffic cannot compute.

LangfuseDeepEval

September 4, 2026 · 7 min read

Skills as Sub-Agents: One Graph, Many Personas

A skill is a folder with two files. SKILL.md becomes the system prompt, skill.yaml declares which sources the run may read, and the shared LangGraph pipeline runs unchanged on an isolated thread. Slash-invocable, like a command. Here is how a domain persona parametrizes four points of one graph without forking it, and the allowlist bug a code review found along the way.

LangGraphSkills

Working on something like this?

Tell me about it. I reply within one working day with a first take and no sales pitch.