DEV Community

Yuvaraj
Yuvaraj

Posted on

LLMs, Decision Models (Jev, CLM), and Extraction Models (Clairic): When Do You Actually Use Which?

Last month, Jev (from TypeSafe) and OpenAI's Decisions API sparked a wave of demos—from instant agent guardrails to generating UI screens straight out of a design system. Then Stanford's Hazy Research and NVIDIA open-sourced Contrastive Language Models (CLM-8B), and Cloudflare dropped Clairic, a "System One" extraction model.

If you feel overwhelmed by how fast new model categories are arriving, you are not alone. Why are we suddenly splitting AI into Extraction, Decision, and Generation models—and where do they actually fit in a real codebase?

Let's skip the hype and map out when to use which, how they work together, and where they fail.


The 30-Second Mental Model

In IBM Technology's breakdown, What Is Jev? The AI Model That Doesn't Generate Text, Martin Keen opens with a simple question:

"What if an AI model didn't need to generate text?"

For years, we used generative LLMs ("System Two" slow, token-by-token models) for tasks that don't require writing prose. If your backend only needs to pull an invoice date or route a ticket into one of four buckets, waiting 3 seconds for an LLM to print JSON character-by-character is wasted latency and token cost.

The modern AI stack splits fast, single-pass "System One" models into two layers in front of your LLM:

flowchart TD
    A["Messy Input<br/>PDF / Email"] --> B["1. Extraction<br/>Clairic"]
    B -->|Typed Values| C["2. Deterministic Code<br/>SQL / Math"]
    C -->|Verified State| D["3. Decision Model<br/>Jev / CLM-8B"]
    D -->|Probabilities| E{"Confidence Gate"}
    E -->|High P| F["Auto-Execute API"]
    E -->|Low P| G["Human Review / LLM"]

    classDef input fill:#475569,stroke:#334155,color:#fff;
    classDef extract fill:#047857,stroke:#022c22,color:#fff;
    classDef logic fill:#b91c1c,stroke:#7f1d1d,color:#fff;
    classDef model fill:#1d4ed8,stroke:#1e3a8a,color:#fff;
    classDef gate fill:#6b7280,stroke:#4b5563,color:#fff;
    classDef auto fill:#15803d,stroke:#14532d,color:#fff;
    classDef review fill:#ea580c,stroke:#9a3412,color:#fff;

    class A input;
    class B extract;
    class C logic;
    class D model;
    class E gate;
    class F auto;
    class G review;

1. Decision Models (Jev, CLM-8B): Routing & UI Catalogs

As Martin Keen explains in the IBM Technology video, the cleanest way to understand a Decision Model is:

  • A generative LLM writes an answer.
  • A decision model evaluates the answers you have already defined.

Every time your code hits an if/else statement that depends on messy human context, ask: "Do I need new content—or a judgment among known possibilities?"

Under the Hood: The Action Cache Speedup

How does a model pick an action in 50 - 150 ms without generating words? The open-weights Contrastive Language Model (CLM-8B) reveals the architecture. Instead of predicting the next word, a dual encoder compares a State vector against a catalog of Candidate Action vectors.

When you see demos generating UI screens from a design system, the model is not writing React tokens. Your design system components are embedded once and cached. At runtime, the model embeds the user's state and scores 1,000 candidate components in 58 ms.

%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#e2e8f0', 'primaryTextColor':'#111827', 'primaryBorderColor':'#6b7280', 'lineColor':'#6b7280'}}}%%
flowchart TD
    subgraph Cached Once at Startup
        A1[Component RefundBanner] --> E2[Action Encoder]
        A2[Component OrderTimeline] --> E2
        E2 --> V2[(Cached Action Vectors)]
    end
    subgraph Runtime
        S[Current User State] --> E1[State Encoder]
        E1 --> V1[State Vector]
        V1 & V2 --> Sim{Dot-Product}
        Sim --> Out[Probabilities per Component]
    end

    style V2 fill:#4b5563,color:#fff,stroke:#1f2937
    style V1 fill:#4b5563,color:#fff,stroke:#1f2937
    style Sim fill:#1d4ed8,color:#fff,stroke:#1e3a8a
    style Out fill:#15803d,color:#fff,stroke:#14532d

2. Extraction Models (Clairic): Typed Values Before the Decision

Decision models only work when you can list the options in advance. What if you need to pull a disputed_amount or transaction_date from a messy PDF? You can't put every possible number in a Choice enum.

That is where Cloudflare's Clairic fits. It extracts strongly typed values in a single pass, completely bypassing LLM JSON hallucination.

flowchart LR
    Input[Raw Bank Statement] --> Clairic{Clairic Extraction}
    Clairic --> O1[merchant Target span 27..33]
    Clairic --> O2[amount 145.50 Float]
    Clairic --> O3[tracking NULL p_null 1.0]

    style Clairic fill:#047857,color:#fff,stroke:#022c22
    style Input fill:#475569,color:#fff,stroke:#334155
    style O1 fill:#f59e0b,color:#000,stroke:#b45309
    style O2 fill:#f59e0b,color:#000,stroke:#b45309
    style O3 fill:#f59e0b,color:#000,stroke:#b45309

Why this beats LLM JSON mode:

  1. Zero Hallucinated Strings: text fields return exact start/end character offsets (span 27..33) from the source document.
  2. Explicit p_null: Instead of making up a tracking number, Clairic returns p_null 1.0 so your code explicitly knows it is missing.

3. Putting It All Together: RAG + System One + LLM

How do these actually work together in a modern enterprise app? Let's look at a practical Banking Dispute Workflow.

A practical flow is:

  1. RAG retrieves the relevant contract, policy, email, or document.
  2. Clairic extracts fields from that retrieved document, such as amount, date, account number, or risk indicator.
  3. Your application uses those fields for validation, workflow routing, or a final LLM-generated response.

For a banking use case: RAG finds the customer’s dispute policy and case history; Clairic extracts the disputed amount, transaction date, merchant, and card ID from the uploaded statement; then a decision model or workflow determines approve, request_documents, or escalate.

%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#e2e8f0', 'primaryTextColor':'#111827', 'primaryBorderColor':'#6b7280', 'lineColor':'#6b7280'}}}%%

sequenceDiagram
    autonumber
    participant App as Banking Backend #047857
    participant RAG as Vector DB
    participant Ext as Clairic Extraction
    participant Dec as Jev Decision

    App->>RAG: Query Target merchant dispute policy
    RAG-->>App: Policy requires receipt if over 100

    App->>Ext: Raw PDF Bank Statement
    Ext-->>App: merchant=Target, amount=145.50

    Note over App: Code verifies transaction in SQL DB

    App->>Dec: State: Extracted Data + RAG Policy
    Note over Dec: Evaluates defined outcomes
    Dec-->>App: Choice request_documents, conf 0.94

    Note over App: threshold > 0.85 triggers Workflow

The Elephant in the Room: The "Well-Formed but Wrong" Trap

Here is the main problem with both Jev and Clairic: their structured output can be perfectly well-formed, but factually wrong.

Because they guarantee schema compliance (e.g., they will always return a valid JSON boolean or a strict Enum), it is dangerously easy for developers to get lazy and pipe that output directly into a production database.

These System One models are incredibly fast and cheap for narrow tasks, but they are not reliable replacements for:

  1. Deterministic Code: If you can parse something with a regex or a basic string split, write the code. Don't use AI.
  2. Domain Logic: Clairic is great at extracting an invoice total, but it shouldn't be calculating tax. Let your deterministic code do the math.
  3. Full Reasoning (System Two): If a ticket requires multi-step troubleshooting, looking up docs, or crafting a nuanced reply, Jev can't do it. You still need a heavy reasoning LLM.

Treat System One models as highly efficient fuzzy-matchers, but keep your deterministic code as the final gatekeeper.

The "When To Use What" Cheat Sheet

flowchart TD
    Start[Task: Process Messy Text] --> Q1{Need Exact Math?}
    Q1 -->|Yes| Code[Deterministic Code]
    Q1 -->|No| Q2{Exact choices known?}
    Q2 -->|Yes: Routing| Jev[Decision Model Jev]
    Q2 -->|No: Extracting values| Clairic[Extraction Model Clairic]

    style Code fill:#ef4444,color:#fff,stroke:#991b1b
    style Jev fill:#3b82f6,color:#fff,stroke:#1e40af
    style Clairic fill:#10b981,color:#fff,stroke:#047857
    style Start fill:#475569,color:#fff,stroke:#334155
    style Q1 fill:#475569,color:#fff,stroke:#334155
    style Q2 fill:#475569,color:#fff,stroke:#334155

💡 The Simple Rule

  • Use RAG when you need to answer: "Where is the information, and what does it mean?"
  • Use Clairic when you need to answer: "What are the exact structured values in this document?"
  • Use Jev when you need to answer: "Which of these predefined routes should we take?"

Over to You: Are You Feeling Model Fatigue Too?

In less than two months, we went from "just prompt an LLM" to juggling Extraction models (Clairic), closed Decision APIs (Jev, OpenAI Decisions), open-weights Contrastive models (CLM-8B), and Reasoning LLMs.

  • Are you also feeling overwhelmed by how fast these new AI model classes are arriving?
  • Have you tried putting Jev, CLM-8B, or Clairic in front of an LLM in your own projects—or found an interesting use case where a fast probability gate beats text generation?

Drop your thoughts, skepticism, or architecture war stories in the comments!


References

  1. IBM Technology: What Is Jev? The AI Model That Doesn't Generate Text
  2. Stanford Hazy Research & NVIDIA: Contrastive Language Models (CLM-8B)

Top comments (0)