DEV Community

Cover image for Full Jev Tutorial for Beginners
bytebantz
bytebantz

Posted on

Full Jev Tutorial for Beginners

Originally published on Medium.

Jev is an AI model created by Diogo Almeida who co-invented ChatGPT.

Jev is apparently 200x faster and 400x cheaper than regular AI models.

But what makes Jev interesting isn’t just its speed or cost. It’s how it approaches AI.

Jev is built for software, not humans.

This means Jev is designed to return decisions that an application can act on directly, rather than text responses written for a person to read.

A general-purpose LLM can understand language, extract information, reason about problems, generate content, and transform unstructured input into structured output.

But in most cases, your application might only need a specific decision.

Imagine a customer support system that needs to determine which team should handle a complaint.

With a conventional LLM, you might prompt it to return JSON containing the team name. Your application then parses the response and extracts the decision.

Jev approaches the task differently.

You define the decisions your application needs, the accepted answer types, and the criteria for evaluating each answer.

Jev then returns structured decision results that your application can act on directly.

Instead of generating text that describes a decision, Jev is designed to return the decision itself.

Use Case Example:

Imagine you work at an online shop. Customers send complaints like these:

Press enter or click to view image in full size

You don’t want an employee to read every complaint and decide what happens next.

Jev helps your application do some of that work automatically and make decisions from the customer’s message.

Instead of writing a text response like most general LLMs explaining the complaint, Jev returns structured decisions that your application can use.

Press enter or click to view image in full size

When making a decision with Jev, you are required to provide 2 things:

🟡 State — the information Jev should evaluate.

🟡 🟡 Questions — the decisions you want Jev to make about that information.

Each question has 3 main parts:

  • type: the kind of answer you expect.

  • instructions: what you want Jev to determine.

  • criteria: how to interpret the possible answers.

"questions": {
    "is_bug": {
        "type": "noul",
        "instructions": "Is the customer reporting a software defect?",
        "criteria": {
            "true": "The customer describes broken or unexpected product behavior.",
            "false": "The customer is asking a question or requesting a feature."
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 1: Give Jev the customer’s complaint

"state": {
  "customer_tier": "enterprise",
  "ticket": "My checkout page shows a blank screen after I click Pay. I have tried two browsers."
}
Enter fullscreen mode Exit fullscreen mode

Think of state as a box containing information about the problem.

Step 2: Ask Jev the first question — is it a bug?

Your application needs to know whether the customer is reporting a software defect.

To help Jev determine exactly counts as a bug, you provide criteria:

"criteria": {
  "true": "The customer describes broken or unexpected product behavior.",
  "false": "The customer is asking a question or requesting a feature."
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Ask Jev the second question — which team should handle it?

Knowing that something is broken isn’t enough.

Your company may have different teams:

🔴Payments team

🟠Frontend team

🟡Account team

You need Jev to select one of them.

"criteria": {
  "payments": "Checkout, billing, or payment processing issues.",
  "frontend": "Rendering, layout, or browser compatibility issues.",
  "account": "Login, permissions, or profile issues."
}
Enter fullscreen mode Exit fullscreen mode

Complete implementation

You don’t need to make one request to determine whether the complaint describes a bug and another to identify the responsible team.

Both questions can be sent in the same request.

Files:

jev-demo/
├── triage.py          the demo
├── requirements.txt   one dependency: requests
Enter fullscreen mode Exit fullscreen mode

Setup

You need Python 3.9 or newer and an OpenRouter API key from https://openrouter.ai/settings/keys.

  1. Create a virtual environment and install the dependency

macOS / Linux

cd jev-demo
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Windows (PowerShell):

cd jev-demo
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode
  1. Set your API key

macOS / Linux:

export OPENROUTER_API_KEY=sk-or-...
Enter fullscreen mode Exit fullscreen mode

Windows (PowerShell):

$env:OPENROUTER_API_KEY = "sk-or-..."
Enter fullscreen mode Exit fullscreen mode

Run ▶

python triage.py
Enter fullscreen mode Exit fullscreen mode

What Jev might return:

Bug probability: 0.96
Team: payments (confidence 0.72)
  payments: 0.81
  frontend: 0.19
  account: 0.00
Decision: bug -> route to the payments team
Enter fullscreen mode Exit fullscreen mode

Types in Jev

Types Supported by Jev

A type tells Jev what kind of answer you want it to produce.

Press enter or click to view image in full size

⚪ Noul — Yes or no

Use it when your question requires a boolean response.

Example: Is this complaint reporting a software bug?

⚪ 🟡 Choice — Select an option

Use it when your question has several possible answers and you want one selected.

Example: Which team should handle the complaint?

⚪ 🟡⚪ Score — An ordered scale

Use it when your question asks for a position on a scale with ordered criteria.

Example: How urgent is the complaint?

Knowledge Check

Press enter or click to view image in full size

LLM + Jev NOT LLM vs Jev

In an e-commerce AI agent, when an LLM is the reasoning engine of your agent, one call usually does two jobs.

It extracts the entities, and it decides what the user wants (intent).

In the following example we ask for both entities and intent in one JSON response:

system_prompt = """
...
Return ONLY JSON matching this exact structure:
{
  "reasoning": "Short explanation of what was detected.",
  "entities": {
    "product_names":   ["item name 1", "item name 2"],
    "quantity":        3 | null,
    "color":           "red" | null,
    "size":            "10" | null,
    "cart_action":     "add" | "modify" | "view" | null,
    "list_categories": false,
    "list_orders":     false,
    "checkout_intent": false,
  }
}
"""
Enter fullscreen mode Exit fullscreen mode

Using an LLM alone for both jobs is prone to errors.

For example the model might return:

{
  "product_names": ["Nike shoes"],
  "quantity": 2,
  "cart_action": "add_to_cart"
}
Enter fullscreen mode Exit fullscreen mode

Your application expects “add”, but the model returns “add_to_cart”.

The meaning is clear to a human, but your code might reject the value because it is not the expected value.

Instead, use the LLM for entity extraction and Jev for decision-making.

Instead of asking the LLM to extract entities and decide the user’s intent in one JSON response, let it extract only the entities:

However you still parse and validate the LLM’s JSON, but it is now a smaller response that holds only entities.

{
  "product_names": ["item name 1", "item name 2"],
  "quantity":      3 | null,
  "color":         "red" | null,
  "size":          "10" | null
}
Enter fullscreen mode Exit fullscreen mode

Jev then handles the decisions by evaluating the message against predefined options and returning probabilities for each choice.

"questions": {
  "intent": {
    "type": "choice",
    "instructions": "What does the shopper want to do?",
    "criteria": {
      "add_to_cart":     "Wants to add a product to the cart.",
      "modify_cart":     "Wants to change or remove something in the cart.",
      "view_cart":       "Wants to see the cart.",
      "checkout":        "Wants to check out or pay.",
      "list_orders":     "Wants to see past orders.",
      "list_categories": "Wants to see the product categories."
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Press enter or click to view image in full size

If Jev runs first and identifies an intent that requires no entity extraction, such as view_cart, checkout, or list_orders, you can skip the LLM call entirely for that turn.

This means you save on:

🟡LLM API costs: No charge for an unnecessary model call.

🟡Latency: The user doesn’t have to wait for the LLM to extract entities that are not needed.

🟡Token usage: No input or output tokens spent on that LLM call.

Jev vs. ML Classifiers (Random Forest)

A classifier basically is a system that takes something as input and assigns it to a category.

A random forest and Jev can both look at a customer’s message and pick an intent: add_to_cart, view_cart, checkout or list_orders.

Both choose from a fixed set of answers, both return probabilities, and neither writes text.

Press enter or click to view image in full size

For Random Forest, you have to provide examples and answers, train the model, and use the resulting model for its learned task.

For instance, if you provide many messages labeled checkout. The model learns patterns from those examples and uses them to classify new messages.

However, if the task changes substantially, you may need to train another model.

For Jev, TypeSafe has already trained the general model.

You just have to describe the task and its possible answers in plain English when you make a request.

If the task changes, you can usually change the question and options instead of training a new model.

Conclusion

JEV is not trying to replace general LLM models such as GPT, Gemini or Claude.

JEV is built to generate decisions.

Use JEV when your app needs to choose and LLMs when you need to generate text responses.

Top comments (0)