DEV Community

Pratik
Pratik

Posted on

Jev vs LLMs: Why AI Agents May Need a Decision Layer

Jev vs LLMs: Why AI Agents May Need a Decision Layer

Here's an uncomfortable pattern in modern AI applications:

User input
   ↓
LLM
   ↓
generated text
   ↓
parser
   ↓
application logic
   ↓
action
Enter fullscreen mode Exit fullscreen mode

We're often using a general-purpose language model to make a tiny decision.

Should we retry?

Should we escalate?

Which tool should we call?

Which model should handle this?

Should this request be blocked?

Those are not necessarily generation problems.

They're decision problems.

That's where Jev, TypeSafe AI's first System One model, gets interesting.

TypeSafe introduced Jev in September 2026 as a model designed around structured decisions rather than open-ended string generation.


The core idea

The simplest mental model is:

Traditional LLM:

state → generated string


System One:

state → typed decision
Enter fullscreen mode Exit fullscreen mode

Jev's developer documentation describes the interface as:

Input:
Text / JSON / text arrays

Output:
Choice / Score / Noul

Control flow:
Your application
Enter fullscreen mode Exit fullscreen mode

That last line matters.

The model doesn't own your application flow.

Your code does.


Jev vs LLM

Let's make the difference concrete.

LLM approach

Suppose an agent receives:

The customer says:

"I was charged twice for the same order.
Please refund the duplicate payment."
Enter fullscreen mode Exit fullscreen mode

You might ask an LLM:

Classify this request and return JSON.
Enter fullscreen mode Exit fullscreen mode

Then receive:

{
  "team": "billing",
  "urgent": true,
  "confidence": 0.96
}
Enter fullscreen mode Exit fullscreen mode

Looks great.

But your application is now depending on:

  • prompt instructions
  • generated output
  • schema adherence
  • parsing
  • interpretation
  • potentially unnecessary text generation

Jev approach

Define the decisions your application actually needs.

Question 1:
Which team should handle this?

Choices:
billing
technical
general
Enter fullscreen mode Exit fullscreen mode

And:

Question 2:
Should this request be considered urgent?

Noul:
yes / no
Enter fullscreen mode Exit fullscreen mode

And perhaps:

Question 3:
How frustrated is the customer?

Score:
0 = low
1 = medium
2 = high
Enter fullscreen mode Exit fullscreen mode

The result can be consumed directly by application code.

Conceptually:

state
  │
  ├── Choice → billing
  │
  ├── Noul   → 0.88
  │
  └── Score  → 1.7
Enter fullscreen mode Exit fullscreen mode

Jev's current developer materials document these three output types and probability/confidence information.


A practical agent architecture

Here's where this becomes more interesting.

Imagine an agent proposes:

{
  "tool": "delete_project",
  "project": "production"
}
Enter fullscreen mode Exit fullscreen mode

Don't let the model directly execute it.

Instead:

                 ┌───────────────┐
                 │   AI Agent    │
                 │   proposes    │
                 │   tool call   │
                 └───────┬───────┘
                         │
                         ▼
                 ┌───────────────┐
                 │     Jev       │
                 │   Decision    │
                 └───────┬───────┘
                         │
             ┌───────────┼───────────┐
             ▼           ▼           ▼
           ALLOW       REVIEW       BLOCK
             │           │           │
             ▼           ▼           ▼
           execute      human        stop
Enter fullscreen mode Exit fullscreen mode

The important architectural rule is:

Jev decides. Code controls.

Your deterministic application layer should still own authorization, thresholds, audit logs, and side effects.


Code example

The exact SDK syntax can change, so treat this as an architectural example rather than a copy-paste contract:

decision = jev.decide(
    state=agent_state,
    questions={
        "tool_policy": {
            "type": "choice",
            "instructions": "Should this tool call execute?",
            "choices": {
                "allow": "Safe and authorized",
                "review": "Human approval required",
                "block": "Do not execute"
            }
        }
    }
)

choice = decision["tool_policy"]["choice"]
confidence = decision["tool_policy"]["confidence"]

if choice == "allow" and confidence >= 0.90:
    execute_tool()

elif choice == "review":
    request_human_approval()

else:
    block_tool()
Enter fullscreen mode Exit fullscreen mode

Notice something important:

The model doesn't get to decide what 0.90 means.

The developer does.

That's the difference between an AI prediction and an application policy.


Why probabilities matter

Suppose Jev returns:

allow  = 0.94
review = 0.04
block  = 0.02
Enter fullscreen mode Exit fullscreen mode

Your application might decide:

if confidence >= 0.90:
    execute()
else:
    human_review()
Enter fullscreen mode Exit fullscreen mode

Another application might require:

if confidence >= 0.995:
    execute()
else:
    human_review()
Enter fullscreen mode Exit fullscreen mode

Same model.

Different risk tolerance.

This makes the model a component inside a larger control system rather than the system itself.

And that's exactly the kind of workflow TypeSafe describes for System One models.


Choice vs Score vs Noul

A useful way to think about Jev's interface is:

Choice

Use when you need:

A / B / C
Enter fullscreen mode Exit fullscreen mode

Example:

Which model should process this request?

fast
deep
human
Enter fullscreen mode Exit fullscreen mode

Score

Use when you need:

How much?
Enter fullscreen mode Exit fullscreen mode

Example:

How urgent is this request?

0 = low
1 = medium
2 = high
Enter fullscreen mode Exit fullscreen mode

Noul

Use when you need:

Yes / No
Enter fullscreen mode Exit fullscreen mode

Example:

Should this request be escalated?
Enter fullscreen mode Exit fullscreen mode

Jev's current documentation describes Noul as a value from 0 to 1 for binary questions.


Where Jev could fit

This architecture opens up some interesting use cases.

1. Agent routing

request
   ↓
Jev
   ↓
simple ──────→ cheap model
complex ─────→ reasoning model
uncertain ───→ human
Enter fullscreen mode Exit fullscreen mode

2. Tool verification

proposed tool call
       ↓
      Jev
       ↓
allow / review / block
Enter fullscreen mode Exit fullscreen mode

3. Retry control

failed request
      ↓
     Jev
      ↓
retry / change strategy / stop
Enter fullscreen mode Exit fullscreen mode

4. Support automation

message
   ↓
Jev
   ├── billing
   ├── technical
   └── general
Enter fullscreen mode Exit fullscreen mode

5. Search ranking

query + result
       ↓
      Jev
       ↓
relevance score
Enter fullscreen mode Exit fullscreen mode

The Jev community is already experimenting with agent routing, browser automation, compaction, MCP tools and other integrations.


But Jev isn't a replacement for an LLM

This is probably the most important point.

Don't think:

Jev > LLM
Enter fullscreen mode Exit fullscreen mode

Think:

Jev + LLM + code
Enter fullscreen mode Exit fullscreen mode

A general-purpose LLM is still the natural component for things like:

  • writing
  • conversation
  • code generation
  • open-ended reasoning
  • planning
  • summarization

A decision model is useful when the application already knows the possible decisions.

So:

LLM:
"Write a response to the customer."

Jev:
"Which queue should handle this?"

Code:
"Actually execute the routing."
Enter fullscreen mode Exit fullscreen mode

Different problems.

Different interfaces.


What makes this technically interesting?

TypeSafe describes Jev as using a different architecture and training approach called Reinforcement Learning for Calibrated Decisions (RLCD). The company says Jev produces probabilities in parallel rather than autoregressively generating a string token by token.

That's a fundamentally different optimization target.

Instead of:

maximize useful generated sequence
Enter fullscreen mode Exit fullscreen mode

the goal becomes closer to:

produce useful + calibrated decisions
Enter fullscreen mode Exit fullscreen mode

The tradeoff is obvious too:

You give up general string generation.

In exchange, the model is specialized for the decision interface.


The performance claim

TypeSafe currently advertises Jev as dramatically faster and cheaper than LLMs for its System One workflows, including a headline comparison of 193.6× faster and 444.6× cheaper on its site.

Those are TypeSafe's reported results, not an independent benchmark.

That's an important distinction.

Before putting Jev in a production workflow, I'd measure:

latency
accuracy
calibration
cost
failure modes
distribution shift
human escalation rate
Enter fullscreen mode Exit fullscreen mode

on your own data.

The Jev developer materials also recommend representative testing and human review for uncertain/high-impact cases.


The bigger idea

We've spent years making AI models increasingly good at producing text.

But production software isn't made entirely of text.

It's made of decisions:

route
retry
approve
reject
escalate
rank
stop
continue
Enter fullscreen mode Exit fullscreen mode

Maybe the next evolution of AI applications isn't:

One giant model that does everything.

Maybe it's:

             ┌────────────┐
             │     LLM    │
             │  Generate  │
             └─────┬──────┘
                   │
                   ▼
             ┌────────────┐
             │    Jev     │
             │   Decide   │
             └─────┬──────┘
                   │
                   ▼
             ┌────────────┐
             │    Code    │
             │   Control  │
             └─────┬──────┘
                   │
                   ▼
                 ACTION
Enter fullscreen mode Exit fullscreen mode

LLMs generate.

Decision models decide.

Code controls.

That's a much more interesting architecture for AI agents than simply throwing a bigger prompt at a bigger model.

And that's why Jev is worth experimenting with.

Try it, benchmark it, break it, and see where the decision primitive actually belongs in your stack.

Top comments (0)