DEV Community

Programming Central
Programming Central

Posted on

Jev: The End of Text Generation: Why RLCD, and System One Models Are Rewriting AI Architecture

The software industry has spent the last three years trying to make large language models behave like functions. It has not gone well.

Every team that has shipped an LLM-powered feature has paid a heavy engineering tax in parsing layers, retry loops, JSON repair libraries, hallucination guards, and the quiet dread that their production system is one prompt rephrase away from a silent regression. We have spent an enormous amount of energy building complex, fragile scaffolding to force a generative text engine to spit out structured values for our software.

The mismatch is not one of capability; it is a category error in how we frame what a model is for. When a system is designed to produce text for humans and then asked to produce values for code, the interface between them becomes a lossy, statistically opaque pipe.

[The concepts and code demonstrated here are drawn directly from the comprehensive roadmap laid out in the book Jev: The Definitive Guide to System One AI here. Check also the many other ebooks]

Jev from https://typesafe.ai/ is an attempt to pay that tax once, at the foundation, and then never again. By introducing System One models trained via Reinforcement Learning for Calibrated Decisions (RLCD), Jev marks the end of text generation as the default output of AI inside software.

The Impedance Mismatch Between Text and Value

Any developer who has consumed a third-party API has felt an "impedance mismatch." It is the friction that appears when two systems have different notions of what a value is. SQL thinks in tables and rows; your application thinks in object graphs and pointers.

The mismatch between a large language model and a piece of software is the exact same kind of problem, but worse. Software thinks in typed values: enums, booleans, integers, discriminated unions. It branches on them, hashes them, and serializes them. Every value that crosses a software boundary has a strict shape. A boolean is true or false. There is no third option.

A large language model, by contrast, thinks in tokens. Its native output is a sequence of token IDs drawn from a vocabulary of tens of thousands of possibilities, one token at a time. If you want a model to say "yes" or "no," it will usually say one of those two words—or it might say "Yes!", "yes.", or "Certainly, yes." All of these are semantically "yes," but to your code, you suddenly have a text-parsing problem when you thought you had a boolean.

Every schema validation library bolted onto an LLM pipeline—Zod, Pydantic, Ajv—is a symptom of this mismatch, not a solution to it. Schema validity is necessary, but not sufficient. A model told to produce valid JSON under a schema can still produce JSON that is valid yet semantically wrong: a hallucinated field value, a fake date, or an enum member that satisfies the schema but fails the business logic.

Jev’s foundational bet is that this mismatch cannot be patched at the interface. It must be resolved at the model level. If your software needs a boolean, train a model whose native output is a probability for that boolean. If it needs one of five categories, train a model whose native output is a distribution over those categories. The model is no longer asked to generate an answer; it is asked to make a decision. And decisions have shapes that software can consume directly.

A Cognitive Mirror: System One and System Two

In Daniel Kahneman’s framework from Thinking, Fast and Slow, human cognition runs on two modes. System One is fast, automatic, intuitive, and largely unconscious. System Two is slow, effortful, deliberative, and conscious.

Reasoning models and chain-of-thought LLMs are, functionally, System Two engines. They think out loud, explore possibilities, and check their work. They are extraordinarily capable at mathematics, code generation, and multi-step planning. They are also slow, expensive, and completely unsuited for tasks that require immediate, binary routing judgments. Asking a reasoning model to decide whether an incoming support ticket is urgent is like asking someone to write a proof that the sky is blue.

Jev and System One models occupy the opposite end of the spectrum. They are trained exclusively for tasks that a knowledgeable person could decide in a fraction of a second. Which category does this document belong to? Does this message express urgency? How frustrated is this customer?

These judgments produce a decision, not a discussion. A System One model produces a well-calibrated probability distribution over a small, well-defined answer space.

When you combine both worlds, you build a two-speed system. The fast path executes the bulk of decisions in tens of milliseconds and at a fraction of a cent. The slow path executes only the decisions that genuinely require deliberation, such as writing a response, generating code, or drafting a legal document. The fast path routes into the slow path. It does not replace it.

What a Decision Actually Is

To say that Jev makes decisions rather than generations requires unpacking what a decision is. A decision is a commitment to one of a small, closed set of outcomes, made under uncertainty, from which the rest of a system can take action. That definition contains four vital requirements:

  1. Commitment: A generation is open-ended; a decision is closed. It picks one answer from the set and stops.
  2. A small, closed set of outcomes: The model cannot invent a new category. If it tries to return something outside the supplied options, the type system rejects it before it ever reaches your business logic. This is the single biggest reason System One models are reliable in production.
  3. Uncertainty: A decision is inherently probabilistic because the answer is not purely algorithmic. It states: "The answer is X with probability 0.87."
  4. Actionability: A decision arrives pre-shapened with a known type and known distribution, allowing your code to branch on it immediately without text-parsing layers.

Calibration: The Contract That Makes Uncertainty Usable

Calibration is the property that makes a probability distribution trustworthy enough for a system to act on. A model is calibrated if, for every prediction it makes with probability pp , the true answer occurs with frequency pp in aggregate. If a model says an input is 90% likely to be category A across a thousand inputs, roughly nine hundred of those inputs should actually be category A.

The probabilities are not just numbers; they are promises. Without calibration, probabilities are just noise dressed up in decimal places. With calibration, you get a decision procedure: act automatically when the model is confident, and escalate to a human when it is not.

RLCD: The Training Loop That Produces Decisions

RLCD stands for Reinforcement Learning for Calibrated Decisions. It is the post-training paradigm designed to turn a pretrained language model into a system whose native output is a calibrated distribution over a closed answer set.

Neither RLHF (Reinforcement Learning from Human Feedback) nor RLVR (Reinforcement Learning with Verifiable Rewards) can achieve this. RLHF rewards responses that sound right to humans, actively discouraging honest uncertainty and causing mode dropping. RLVR requires a ground-truth verifier like a compiler or test suite, making it useless for nuanced real-world judgments like customer sentiment or intent routing.

RLCD, by contrast, trains the model for alignment between its stated probabilities and the observed frequencies of outcomes. When the model says 0.7, it is rewarded for being right 70% of the time.

Putting It Into Practice: A Production TypeScript Example

Let's look at what this architecture looks like in code. Below is a complete, type-safe implementation of an inbound customer support triage service using the Jev SDK. It evaluates multiple questions in a single network round trip, uses no text generation, and implements confidence-gated routing.

/**
 * @file ticket-triage.ts
 *
 * A minimal end-to-end Jev example.
 *
 * Takes one inbound support ticket, asks Jev four typed questions about it,
 * composes the answers with ordinary branching logic, and returns a routing
 * decision. Zero text generation. Zero parsing. One HTTP round trip.
 */

import {
  TypeSafeClient,
  noul,
  choice,
  score,
} from "@typesafe-ai/sdk";

interface SupportTicket {
  id: string;
  plan: "starter" | "growth" | "enterprise";
  mrrUsd: number;
  message: string;
}

const ticket: SupportTicket = {
  id: "TKT-10423",
  plan: "enterprise",
  mrrUsd: 4_200,
  message:
    "Our entire team has been locked out of the dashboard since our IdP " +
    "rotated its signing certs this morning. We are blocked on a live " +
    "customer demo in 40 minutes. Please escalate.",
};

const QUESTIONS = {
  is_urgent: noul(
    "Does `ticket.message` convey time-critical urgency?",
    {
      true: "An explicit deadline, active outage, or irreversibly blocked work.",
      false: "No sense of timing pressure — a routine question or request.",
    },
  ),

  department: choice(
    "Which team should own `ticket.message`?",
    {
      auth: "Login, SSO, SAML, session, or identity-provider problems.",
      billing: "Charges, invoices, plans, or subscription changes.",
      platform: "API errors, latency, outages, or integration problems.",
      success: "How-to questions, onboarding, or feature requests.",
    },
  ),

  frustration: score(
    "How frustrated does the sender of `ticket.message` appear?",
    [
      "Neutral: matter-of-fact, no complaint about the experience.",
      "Frustrated: annoyed, but still constructive.",
      "Angry: hostile language, or threatening to leave.",
    ] as const,
  ),

  is_enterprise: noul(
    "Is `ticket.plan` equal to `enterprise`?",
  ),
} as const;

type Route = {
  queue: string;
  priority: "P0" | "P1" | "P2";
  sla: string;
  shouldDraftReply: boolean;
};

async function triage(ticket: SupportTicket): Promise<Route> {
  const client = new TypeSafeClient();

  const response = await client.systemOne({
    state: ticket,
    questions: QUESTIONS,
  });

  const { is_urgent, department, frustration } = response.answers;

  if (department.confidence < 0.65) {
    return {
      queue: "human-triage",
      priority: "P2",
      sla: "30m",
      shouldDraftReply: false,
    };
  }

  const veryAngry = frustration.score >= 1.8;

  let priority: Route["priority"] = "P2";
  if (is_urgent.noul >= 0.8 || veryAngry) {
    priority = "P0";
  } else if (is_urgent.noul >= 0.4) {
    priority = "P1";
  }

  const enterpriseFastLane =
    ticket.plan === "enterprise" && is_enterprise.noul >= 0.8;

  const sla =
    enterpriseFastLane && priority === "P0"
      ? "5m"
      : priority === "P0"
        ? "15m"
        : priority === "P1"
          ? "1h"
          : "8h";

  const shouldDraftReply = enterpriseFastLane && veryAngry;

  return {
    queue: department.choice,
    priority,
    sla,
    shouldDraftReply,
  };
}

triage(ticket)
  .then((route) => {
    console.log("route:", route);
  })
  .catch((err) => {
    console.error("triage failed:", err);
  });
Enter fullscreen mode Exit fullscreen mode

Detailed Breakdown

This script demonstrates how to replace an entire brittle pipeline of prompt templates, chained API calls, and JSON repair routines with a single, atomic, strongly typed decision operation.

1. Declaring the Decision Space A Priori (QUESTIONS)

Instead of describing desired behavior in unstructured natural language inside a system prompt, the developer defines a formal query schema using typed primitives:

  • noul (is_urgent, is_enterprise): Evaluates a binary proposition and yields a continuous value in the $[0, 1]$ interval—representing the model's calibrated probability that the condition is true. Explicit boundary definitions are passed alongside the question to eliminate semantic ambiguity.
  • choice (department): Constrains the outcome to a closed categorical space of exactly four variants (auth, billing, platform, success). The model cannot hallucinate alternate categories or return misspelled strings; TypeScript narrows the return type to this exact four-member union.
  • score (frustration): Discretizes an ordinal judgment across a defined three-tier scale (from 0: Neutral to 2: Angry), converting qualitative sentiment into a mathematically actionable scalar.

2. Atomic Evaluation in a Single Round Trip (client.systemOne)

The entire ticket payload (state) and the schema of four questions are dispatched to the System One engine in a single network request:

  • Zero Text Generation: The model does not sample sequential tokens or construct JSON strings. It computes calibrated probabilities directly over the target spaces.
  • Zero Parsing Overhead: The values returned under response.answers require no validation wrappers (like Zod or Pydantic) or JSON parsing libraries; they conform natively to the static types inferred from the schema.

3. Confidence-Gated Business Logic & Dynamic Routing

Because the outputs are calibrated probabilities rather than raw text, business logic can branch deterministically on uncertainty:

  • Confidence Gating: If department.confidence < 0.65, the system acknowledges its own ambiguity and routes the ticket to human-triage. This prevents silent misclassification before it affects SLAs.
  • Deterministic Prioritization: Priority tiers (P0, P1, P2) are assigned via standard TypeScript branching logic evaluated against numerical thresholds (is_urgent.noul >= 0.8 or frustration.score >= 1.8).
  • Selective Generative Offloading: The generative flag shouldDraftReply evaluates to true only for high-value Enterprise accounts experiencing severe friction (veryAngry). Standard, low-urgency inquiries bypass generative LLMs entirely, drastically reducing token spend and response latency.

Advanced Application Script: Building a Supervisor Node

Let's scale this pattern into a real-world production service. The following script acts as a Supervisor Node for a multi-tenant SaaS copilot. It receives a chat turn, makes five calibrated judgments about it in a single Jev round trip, and routes the turn using ordinary TypeScript branching logic.

// app/api/copilot/route.ts
import { NextRequest, NextResponse } from "next/server";
import {
  TypeSafeClient,
  choice,
  noul,
  score,
} from "@typesafe-ai/sdk";
import { WORKERS } from "@/lib/workers";
import { redactSecrets } from "@/lib/redact";

const jev = new TypeSafeClient({
  apiKey: process.env.TYPESAFE_API_KEY!,
  defaultModel: "jev-latest",
  timeout: 5_000,
});

const SUPERVISOR_QUESTIONS = {
  worker: choice("Which specialist handler should own the turn in `message`?", {
    logs: "CI/CD, pipeline failures, runtime errors, deployments, infrastructure telemetry.",
    docs: "Product behaviour, policy, onboarding, or any 'how do I' question with a documented answer.",
    code: "Write, review, refactor or explain source code for `repoLanguage`.",
    billing: "Plans, seats, invoices, usage limits, subscription changes.",
    escalate: "Unprecedented, ambiguous, or sensitive enough that a human should own it.",
  }),

  complexity: score(
    "How much multi-step reasoning would a competent engineer need to fully resolve `message`?",
    [
      "A single fact lookup or a one-line answer.",
      "A short explanation, or a single small code change.",
      "Multi-step reasoning, or a change that spans several files.",
      "An open-ended investigation with unknown variables.",
    ],
  ),

  destructive: noul(
    "Does `message` ask the assistant to perform an irreversible action on a live system?",
    {
      true: "The request is to delete, drop, revoke, force-push, rotate, or otherwise permanently alter production data or infrastructure.",
      false: "The request is read-only, additive, or purely informational.",
    },
  ),

  contains_secret: noul("Does `message` contain a credential-shaped value?", {
    true: "An API key, bearer token, private key, password, or similar secret appears verbatim.",
    false: "No credential-shaped value is present.",
  }),

  needs_generative: noul(
    "Does resolving `message` require an authored, free-form answer?",
    {
      true: "The user expects prose: an explanation, a review, a draft, a comparison.",
      false: "A templated reply, a deterministic lookup, or a refusal would satisfy the turn.",
    },
  ),
} as const;

type Supervisor = SystemOneResult<typeof SUPERVISOR_QUESTIONS>;
type WorkerId = Supervisor["answers"]["worker"]["choice"];

type Verdict =
  | { kind: "reject"; reason: "secret" }
  | { kind: "escalate"; reason: "destructive" | "uncertain" }
  | {
      kind: "answer";
      worker: Exclude<WorkerId, "escalate">;
      generative: boolean;
    };

const CONFIDENCE_FLOOR = 0.55;
const DESTRUCTIVE_CEILING = 0.15;
const SECRET_CEILING = 0.4;

function route({ answers }: Supervisor): Verdict {
  if (answers.contains_secret.noul >= SECRET_CEILING) {
    return { kind: "reject", reason: "secret" };
  }
  if (answers.destructive.noul >= DESTRUCTIVE_CEILING) {
    return { kind: "escalate", reason: "destructive" };
  }
  const { choice: picked, confidence } = answers.worker;
  if (confidence < CONFIDENCE_FLOOR || picked === "escalate") {
    return { kind: "escalate", reason: "uncertain" };
  }
  return {
    kind: "answer",
    worker: picked,
    generative: answers.needs_generative.noul >= 0.5,
  };
}

export const runtime = "nodejs";

export async function POST(req: NextRequest) {
  const body = await req.json();
  const state = { ...body, message: redactSecrets(body.message) };

  const t0 = performance.now();
  const supervisor = await jev.systemOne({
    state,
    questions: SUPERVISOR_QUESTIONS,
  });
  const jevMs = Math.round(performance.now() - t0);

  const verdict = route(supervisor);

  if (verdict.kind === "reject") {
    return NextResponse.json({ path: "blocked", jevMs, reply: SECRET_REPLY });
  }

  if (verdict.kind === "escalate") {
    return NextResponse.json({
      path: "human",
      jevMs,
      reason: verdict.reason,
      evidence: supervisor.answers,
    });
  }

  const worker = WORKERS[verdict.worker];
  const reply = verdict.generative
    ? await worker.explain(state)
    : worker.lookup(state);

  return NextResponse.json({
    path: "answered",
    jevMs,
    worker: verdict.worker,
    generative: verdict.generative,
    reply,
  });
}

const SECRET_REPLY =
  "I spotted what looks like a credential in that message. I've redacted it and will not forward it to any model. Please rotate the value.";
Enter fullscreen mode Exit fullscreen mode

Detailed Breakdown

This script implements the Supervisor Node architectural pattern within a Next.js App Router endpoint. It acts as an ultra-fast, deterministic traffic controller and safety perimeter, evaluating incoming turns before any expensive generative worker or high-privilege tool is invoked.

1. Sanitization and Parallel Multidimensional Profiling

When the HTTP POST request arrives:

  • The payload undergoes initial heuristic cleaning via redactSecrets(body.message).
  • The supervisor runs five independent, calibrated evaluations across the message in a single System One network hop:
    • worker: Classifies the domain-specific handler best suited to resolve the turn.
    • complexity: Measures the depth of reasoning required (from a single fact lookup to multi-file investigations).
    • destructive: Calculates the probability that the user is attempting an irreversible production change (e.g., dropping databases, rotating keys, force-pushing).
    • contains_secret: Detects credential-shaped patterns that escape standard regex filters.
    • needs_generative: Evaluates whether the user requires natural prose or if a deterministic response suffices.

2. Calibrated Safety Guardrails (route())

The pure function route() handles security and validation using a TypeScript discriminated union (Verdict):

  • Leak Prevention (SECRET_CEILING = 0.4): If the probability that the prompt contains a raw secret meets or exceeds 40%, the request is halted immediately (kind: "reject"). The payload is barred from passing downstream to subsequent models, logs, or databases.
  • Disaster Prevention (DESTRUCTIVE_CEILING = 0.15): Because destructive operations carry severe consequences, the tolerance threshold is set aggressively low (15%). Any elevated likelihood of irreversible action diverts the turn to human authorization (kind: "escalate").
  • Ambiguity Fallback (CONFIDENCE_FLOOR = 0.55): If the model's confidence in assigning a specialist worker drops below 55%, or if it selects escalate directly, the system avoids routing hallucinations. It hands off execution to human operators, attaching the full distribution of probabilities as audit metadata (evidence: supervisor.answers).

3. Two-Speed Execution: Fast Path vs. Slow Path

Once a safe verdict is confirmed (kind: "answer"), the router enforces cognitive decoupling:

  • Fast Path (Deterministic): If generative === false, the supervisor invokes worker.lookup(state). The answer is resolved via SQL queries, vector cache lookups, or pre-rendered documentation in tens of milliseconds, with zero token-generation latency.
  • Slow Path (Generative): Only when needs_generative.noul >= 0.5 does the endpoint hand execution over to worker.explain(state), engaging an LLM to author a contextual response.
  • Telemetry & Observability: Every response includes jevMs, tracking decision-phase latency to guarantee that the supervisor layer maintains sub-100ms response times in production.

Conclusion: Designing Workflows, Not Prompts

When you internalize the shift from text generation to calibrated decisions, the entire nature of AI engineering changes.

Prompt engineering, complex parsing layers, validation libraries, and fragile JSON repair loops begin to disappear from your daily work. Not because those skills stop mattering, but because the heavy lifting has moved where it always belonged: to the model, the API, and the type system at the boundary.

What is left for the engineer is what should have been left there all along: designing the workflow, choosing the questions to ask, weighting the answers, and deciding what programmatic action to take next. That is a much cleaner, more predictable design space—and it is the foundation upon which the next generation of software will be built.

The concepts and code demonstrated here are drawn directly from the comprehensive roadmap laid out in the book Jev: The Definitive Guide to System One AI here. Check also the many other ebooks.

Top comments (0)