top of page

TypeSafe AI Jev: What Typed Decision Models Replace, and What They Do Not

18 hours ago
15 min read
Diagram of connected decision nodes representing TypeSafe AI's Jev typed classification model, TriSeed

A model class shipped this month that does not generate text at all. TypeSafe AI released Jev on September 15, 2026, and the coverage since has been mostly explainers of what it is. The more useful question for anyone deciding whether to build on it is narrower. Where does a typed decision model actually belong in a production pipeline, what does it displace, and where does it fail in ways the launch material does not mention.


Answering that abstractly produces another explainer, so the sections below work through one demanding domain instead: the classification steps inside a quality of earnings engagement in financial due diligence. It is a useful stress test in both directions. The categories are known in advance and the volume is high, which is exactly the shape the architecture is built for. The cost of a wrong answer is also high enough that mostly right is not good enough, which exposes the limits quickly. The code and thresholds below are illustrative. They are a worked example, not a description of a system anyone is running in production today.

Vendors already automating this work draw the line in the same place. QoEAgent.ai automates proof of cash, trial balance mapping, statement structuring, and document extraction, and states plainly that EBITDA adjustments, meaning the decision about what qualifies as an addback, stay with the human advisor. That specific exclusion is what the worked example below targets.


The judgment layer in that kind of engagement is not one hard problem. It is a very large number of small, repetitive determinations over transaction-level data. Is this professional fee tied to the sale process or is it a normal recurring cost. Is this owner compensation discretionary. An experienced analyst makes each in seconds, and there are thousands of them. Teams that push that layer onto a general language model hit the same three walls, and none of them are about intelligence.


  • The output is a string. Your pipeline needs a category, so you prompt for JSON, then parse it, then validate it, then decide what to do when validation fails.

  • There is no honest uncertainty. A model that classifies correctly most of the time but never says which cases it was unsure about gives you no basis for deciding what a human should look at.

  • Cost and latency do not survive the line count. Per-item reasoning calls across a full general ledger add up in both dimensions.


Jev is aimed squarely at that shape of problem. It is worth a serious look, and it is worth being equally precise about what it does not solve, because in any domain where a wrong answer is expensive the second question matters more than the first.


What TypeSafe AI Jev Actually Is

TypeSafe AI was founded by Diogo Almeida, who worked at OpenAI on the instruction-following methods behind ChatGPT. The framing in the launch post is that models have been strong at chat for years while automation lagged, and that the gap is an interface problem rather than a capability problem.


Jev does not generate text. It evaluates a set of questions against a state you provide and returns typed values, so its outputs conform to a schema by construction rather than by parsing. Because there is no token-by-token generation, every question in a call is evaluated against the same state in a single pass. The company trains it with a method it calls Reinforcement Learning for Calibrated Decisions, aimed at producing probabilities that track real accuracy rather than outputs a human rater would prefer.


None of that is independently checkable yet. TypeSafe has not published Jev's architecture, weights, or a technical paper describing how Reinforcement Learning for Calibrated Decisions actually works, which is the most repeated complaint in developer discussion since launch. Every calibration and accuracy claim in this piece, including the ones from press coverage below, ultimately rests on the vendor's account rather than anything a third party can reproduce.


The API exposes three primitives, and any number can be combined in one call.

Primitive

Question it asks

What it returns

Choice

Pick one option from a list you define.

The selected option, the probability of each option, and a confidence value.

Score

Rate the state against a rubric you define.

A score, the probability of each level, a legend mapping levels back to their descriptions, and a confidence value.

Noul

Is this statement true of the state?

A single probability from 0 to 1. No separate confidence value.


The documentation is explicit that questions should be atomic. If a determination needs several independent factors weighed, the guidance is to ask each factor separately and combine them in your own code, so the weighting lives in a coefficient you can change rather than inside a prompt you have to rewrite.


Pipeline diagram: ledger extraction, out-of-scope filter, and Jev typed-decision call leading to auto-classified or human review.

Side by side against a general LLM call

Figures quoted below are the vendor's own published numbers. Read the latency and pricing rows as vendor claims rather than independent measurements.

Dimension

General LLM call

Typed decision model (Jev)

Output

Generated text your code must parse and validate before acting on it.

Typed values matching a schema you define in advance. No parsing step.

Uncertainty signal

Only if you prompt for it, and TypeSafe notes in its own launch write-up that models tend to be overconfident and inconsistent when self-reporting.

A probability distribution plus a confidence value on every Choice and Score answer.

Stated rationale

Can explain why, citing the clause or the prior-period pattern it relied on. This is what a reviewer reads.

None. A category and a number. Any rationale has to be constructed by the surrounding system.

In-context capacity

Can take an entire credit agreement, LP memo, or chart-of-accounts rulebook as context.

Atomic questions push you toward short state strings and brief instructions.

Multi-document checks

Can cross-reference a GL line, an invoice PDF, and a bank statement in one step using tool calls.

Cannot, even if you concatenated all three into one state string. It has no multi-step reasoning to relate them, only an atomic judgment against whatever you hand it.

Portability

Broadly similar interfaces across providers, so switching models is a contained change.

A proprietary API and its own SDK. Moving off it means rewriting the classification layer.

Sampling

Sequential, one token at a time.

All questions evaluated against the same state in one call.

Latency

3 to 329 seconds end to end, per the vendor comparison.

70 to 500 ms end to end, per the vendor comparison.

Pricing shape

Input $0.20 to $10 per MTok, output priced roughly 5x input.

Input $0.042 per MTok, output tokens not billed.

Failure mode

Hallucination, schema drift, refusal, or a confidently wrong answer with no signal attached.

Cannot emit a type error, but that is a narrower guarantee than it sounds. A structurally valid answer that names the wrong category is functionally the same failure as a hallucination: confidently wrong, and nothing in the schema catches it.

Option cardinality

Effectively open ended.

Up to 255 options per Choice question, stated in the Choice documentation.

Strongest fit

Narrative drafting, novel cases, analysis spanning several documents, anything a reviewer must read a reason for.

High-volume repeated classification where categories are known ahead of time and a human still signs off.

Sources: TypeSafe AI launch post and docs.typesafe.ai, both read September 21, 2026. Every figure in the latency and pricing rows was checked against the launch post on Sep 21 and is quoted accurately; re-check pricing on the day of publishing in case it has changed.


Three rows deserve emphasis because they decide whether this belongs in a diligence workflow at all. The model states no rationale, so a reviewer gets a category and a number rather than a reason. It cannot reason across documents, so anything requiring corroboration stays outside it. And it is a proprietary interface, so the classification layer becomes a dependency on one vendor. None of these are reasons to dismiss it. They are the reasons it has to sit inside a controlled pipeline rather than replace one.


Two comparisons are missing from the table because they complicate rather than clarify it, but a fair reader should have them. The LLM pricing above is list price on uncached input; prompt caching on the major providers cuts repeated context by 75 to 90 percent, which narrows the cost gap for a pipeline that resends similar instructions on every call. And Jev is not the only alternative to a frontier LLM call. A fine-tuned local classifier, a small model such as DeBERTa or an 8B open-weight model trained on your own labeled data, can match Jev on cost and privacy for a fixed set of categories, at the price of a training pipeline that a hosted API does not need. Jev's case is that it needs no fine-tuning and no local infrastructure, not that it is the only cheap option.


What the published evidence shows, and what it does not

TechCrunch reported on September 18 that Vercel replaced OpenAI's Luna with Jev inside a safety classifier, and that engineer Pranit Sharma described the result as 5 to 18 times faster and more accurate for that workload. A production swap at a named company is stronger evidence than a vendor benchmark, though it is one narrow classification task.


Forbes reported on September 19 on a head-to-head run by Dan Shipper of Every, and this one is more instructive because the accuracy result cuts against the model. Across 12 passages with planted defects, the reported median was 0.35 seconds for Jev against 8.83 seconds for Claude Fable 5.1 at high effort, roughly 25 times faster at about one 580th of the cost. Jev caught six of the seven planted defects where the larger model caught all seven. Faster and cheaper, and slightly less accurate.


The same shape shows up in a second test in the TechCrunch piece. Bryo AI CTO Nikhil Mudholkar compared Jev against Gemini for classifying business emails and found Gemini slightly more accurate but 10 to 20 times more expensive, and singled out the confidence scores as the thing that mattered most to him. Two independent tests landing on the same trade, slightly lower accuracy for a large cost and speed gain, is a more useful signal than either one alone.


That trade is the one a diligence workflow has to price, and it does not price the same way it does in software. Missing one defect of seven in a code review is recoverable in the next pass. An unflagged related-party transaction is not that kind of error. The conclusion is not that the model is unsuitable, but that the accuracy gap has to be handled by the architecture around it rather than assumed away.


Two caveats belong in the reader's hands. TypeSafe discloses in its own launch post that the workflow evaluations behind its headline multiples were built by its own model capabilities team, and that the reference answers are an average of two frontier models, which biases the comparison. Separately, the line most quoted about Jev comes from developer commentator Theo Browne, who calls it roughly as intelligent as a switch statement. That reads like a putdown out of context, but his assessment is enthusiastic, and the phrase is a description of what the model is rather than a complaint about it. The point underneath is the one that matters here: the intelligence sits in how you decompose the questions, not in the model reasoning on your behalf. For work that has to be reviewed, that is arguably the right property, because it puts the judgment in code someone can read rather than in a prompt.


Mapping the primitives to QoE classification

This section and the next are the worked example. Take a single general ledger line under review for addback treatment. Rather than one open question, the determination decomposes into independent questions asked in the same call. Note that the state is a string, so a structured ledger record has to be rendered into one first, and that rendering is part of your pipeline rather than something the model does for you.


from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient()

def render_state(row):
    """Structured ledger record to the plain-text state Jev expects."""
    return (
        f"GL account: {row.account_code} {row.account_name}\n"
        f"Vendor: {row.vendor_name}\n"
        f"Amount: {row.amount:,.2f}\n"
        f"Period: {row.fiscal_period}\n"
        f"Memo: {row.memo}"
    )

# Categories the model can judge from a single line and its memo.
# Out-of-period and non-cash-comp items are NOT in this list: judging
# them needs multi-period trend data or a cap table, neither of which
# fits in one line's state. Those are filtered upstream by the ledger
# extraction step, before a row ever reaches this call. See "Where
# this does not fit" below for why.
ADDBACK_CATEGORIES = {
    "transaction_costs": "One-time costs tied to a sale, financing, or
                          acquisition process",
    "severance_restructuring": "Severance, redundancy, or restructuring
                                charges not expected to recur",
    "owner_discretionary": "Compensation or perquisites at the owner's
                            discretion",
    "management_fee": "Sponsor or parent management fees subject to
                       normalization",
    "it_transition": "One-time system implementation or migration cost",
    "facilities_consolidation": "Site closure, relocation, or lease exit
                                 cost",
    "non_recurring_legal": "Legal or litigation cost not expected to recur",
    "ongoing_operating": "Normal recurring operating expense, not an
                          addback",
}

state = render_state(row)  # computed once, reused below for the
                           # workpaper record, not just this call

response = client.system_one(
    state=state,
    questions={
        "addback_category": Choice(
            instructions="Which addback category best describes this expense",
            criteria=ADDBACK_CATEGORIES,
        ),
        "recurrence_risk": Score(
            instructions="How likely this expense recurs in a normal year",
            criteria=[
                "Clearly one-time, tied to a discrete event",
                "Possible but not expected to recur",
                "Likely to recur in some form",
            ],
        ),
        "related_party": Noul(
            instructions="The counterparty appears to be a related party",
        ),
    },
)

category = response.answers["addback_category"]   # .choice, .confidence,
                                                  # .probabilities
recurrence = response.answers["recurrence_risk"]  # .score, .confidence,
                                                  # .probabilities, .legend
related = response.answers["related_party"]       # .noul, a probability 0 to 1

Request shape follows the TypeSafe Python SDK as documented at docs.typesafe.ai. Confirm the exact attribute names for Score and Noul answers against the SDK reference before shipping code.


Three things are worth noticing. The taxonomy is the firm's own, defined in code and versioned with the rest of the pipeline rather than buried in prompt text, and it deliberately excludes categories the model cannot judge from one line. Recurrence is asked as a separate graded question rather than folded into the category, so the weighting between them stays under your control and feeds the routing logic below. And the related-party test is its own question.


The confidence number, and what it is not

It is tempting to treat a returned probability distribution as an audit trail. It is not one. The model gives you a category and a number. It does not tell you that the memo said "Project Redwood," that Redwood was the sale process, and that the fee therefore sits with the transaction rather than with operations. That chain is what a reviewer actually reads, and Jev does not produce it.


What the distribution does give you is a defensible basis for allocating review effort. If the model puts 0.51 on transaction costs and 0.44 on ongoing operating, that is a genuinely close call, and a close call is worth an analyst's time in a way that a 0.98 is not. The workpaper is defensible because a human reviewed the right items and recorded why, not because a number was logged next to each one.

That distinction has a practical consequence. The pipeline has to record the question set and its version, the rendered state, the returned distribution, and the reviewing analyst's own conclusion for anything that was reviewed. The first three make the call reproducible. Only the fourth makes it explained.


Routing: category first, then cumulative exposure, then amount

The vendor documentation recommends three confidence bands: act when high, proceed with caution in the middle, route to a human when low. It also notes the threshold is not one number, and that different actions should be gated differently depending on the consequences of being wrong. That is sound, but a diligence pipeline needs two controls the bands alone do not provide.


The first is category-based routing. Related-party transactions and owner perquisites are often small and recurring, a monthly lease or a modest consultancy retainer. Gating on amount sends exactly those items through unreviewed, and they are frequently the findings that move a deal. Anything the model flags as related party goes to a human regardless of size.


Routing Logic infographic showing five checks to route items to an analyst, with yellow and blue steps and green auto-classified boxes.

The second is cumulative exposure. A single misclassified expense below the materiality threshold is immaterial by definition. Several hundred of them are not. If a category accumulates enough auto-classified value to matter in aggregate, the pipeline has to stop treating those items as individually immaterial.


# workpaper and exposure are assumed pipeline objects, not part of the
# SDK: workpaper is your own audit-log store, exposure tracks running
# auto-classified totals per category and MUST reset at the start of
# each new engagement, or the cap below fires almost immediately on a
# firm doing repeat work in the same categories.
QUESTION_SET_VERSION = "addback-v3"   # bump whenever criteria text changes
CONFIDENCE_FLOOR = 0.5                # below this, never auto-classify
HIGH_CONFIDENCE = 0.9
LINE_MATERIALITY = 50_000
CATEGORY_EXPOSURE_CAP = 250_000       # per engagement; recalibrate this
                                       # to your typical engagement size,
                                       # not left as a global constant
RELATED_PARTY_FLOOR = 0.15            # deliberately low: a hint is enough
RECURRENCE_REVIEW_FLOOR = 1.4         # on a 0-2 scale: leaning toward
                                       # "likely to recur", worth a look
                                       # even if the category call is clean

def route_line_item(item, state, answers, exposure):
    category = answers["addback_category"]
    recurrence = answers["recurrence_risk"]
    related = answers["related_party"]

    # Reproducibility record. Not a rationale, see above.
    workpaper.record(
        item_id=item.id,
        question_set_version=QUESTION_SET_VERSION,
        state=state,
        category=category.choice,
        confidence=category.confidence,
        probabilities=category.probabilities,
        recurrence_score=recurrence.score,
        related_party_p=related.noul,
    )

    # 1. Category risk overrides amount entirely.
    if related.noul >= RELATED_PARTY_FLOOR:
        return queue_for_analyst(item, reason="possible_related_party")

    # 2. Genuine model uncertainty on the category itself.
    if category.confidence < CONFIDENCE_FLOOR:
        return queue_for_analyst(item, reason="low_confidence")

    # 3. High recurrence risk on an addback is worth a second look even
    #    when the category call is confident: misclassifying a line
    #    that actually recurs compounds across every future period.
    if recurrence.score >= RECURRENCE_REVIEW_FLOOR:
        return queue_for_analyst(item, reason="high_recurrence_risk")

    # 4. Aggregate exposure, the control a per-item gate misses.
    if exposure.auto_classified_total(category.choice) > CATEGORY_EXPOSURE_CAP:
        return queue_for_analyst(item, reason="category_exposure_cap")

    # 5. Line-level materiality, last rather than first.
    if item.amount >= LINE_MATERIALITY:
        if category.confidence >= HIGH_CONFIDENCE:
            return classify(item, category.choice, review="sampled")
        return queue_for_analyst(item, reason="material_and_uncertain")

    exposure.add(category.choice, item.amount)
    return classify(item, category.choice, review="sampled_by_rate")

Threshold values are placeholders. The exposure cap in particular has to scale with engagement size; an under-sized cap will route routine items to review almost immediately. Calibrate every one of these against your own closed engagements before relying on them.



Where this does not fit

Some of these are structural limits of the architecture, and some are steps where using it would be actively unsafe.


Structural limits

  • No retrieval and no tool use. Pulling the supporting invoice or checking a vendor against a related-party register stays with the surrounding system.

  • No stated reasoning, as covered above. Anything a reviewer must read a justification for needs a different layer.

  • No multi-hop analysis. A determination that traces a transaction across three documents is not one atomic question, and decomposing it does not make it one.

  • A knowledge cutoff with no way to search around it, which matters more for a model with no retrieval path.

  • A cardinality ceiling of 255 options per Choice question, and a maximum of 10 levels on a Score. Fine for an addback taxonomy, not workable against a large chart of accounts without a two-stage design.

  • No narrative output. The memo, the exception write-up, and the client-facing explanation still need a language model or a person.

  • Closed architecture. No published weights, paper, or reproducible benchmark methodology. Every accuracy and calibration claim, including TypeSafe's own, is currently a claim you cannot independently check.


Steps where it should not be used at all

  • Out-of-period cutoff testing. Deciding whether an expense belongs in FY24 or FY25 requires trend analysis across surrounding ledger months. A single isolated line cannot support that judgment, and a confident answer here would be confidently wrong.

  • Revenue recognition and deferred revenue. Assessing unbilled receivables or deferred revenue releases requires validating contract schedules, not evaluating a memo string.

  • Anything where the classification itself is the deliverable rather than an input to a reviewed workpaper.


The useful conclusion is that this is a component and not a replacement. It takes the high-volume repeated judgments a language model was handling awkwardly, and leaves that model, and the analyst, the work each is actually suited to.


A practical way to test it

  1. Start in the playground. Paste one real anonymised ledger line as the state and write one Noul question against it. This tells you quickly whether the determination is even the right shape for the primitive.

  2. Write the taxonomy down in code as Choice criteria. The exercise is clarifying on its own, because ambiguity in your own taxonomy surfaces immediately.

  3. Run in shadow mode against closed engagements. Classify line items from work already complete and reviewed, and compare against what the analyst concluded. Never against a live engagement.

  4. Measure agreement and calibration separately. Agreement is how often the classification matched. Calibration is whether the confidence values were honest, meaning high-confidence items really were more accurate than low-confidence ones. Calibration determines whether you can gate on it at all, and it is the step teams skip.

  5. Measure aggregate error, not just per-item accuracy. Sum the value of everything misclassified below your materiality threshold and ask whether that total would have changed the earnings figure. This is the number that decides whether the exposure cap is set correctly.

  6. Set thresholds from that data, split by materiality band and by category risk, rather than adopting defaults.


The output of that sequence is a real number for your own workflow, which is worth considerably more than any figure reproduced from a launch post.


Closing

Typed decision models do not replace the language model in your stack, and the launch-week framing that suggests otherwise will not survive contact with a domain where errors cost something. What they change is narrower and genuinely useful. A classification that arrives with an honest probability attached can be routed, sampled, and escalated in a way a bare answer cannot, which means review effort lands where the ambiguity actually is rather than being spread evenly or allocated by size.


The worked example above is one domain. The same pattern applies anywhere you are making thousands of repeated categorical judgments against known categories and currently paying frontier prices for them.



Working through this in your own stack

We are working through these questions rather than selling an answer to them. TriSeed builds automation and decisioning systems for financial institutions, and the trade-offs in this post are the ones we are actively weighing in our own diligence tooling.


If you are weighing whether this architecture fits a classification workload of your own, the shadow-mode evaluation described earlier is the fastest way to find out: mapping the decision points, building the question set, measuring agreement and calibration against work your team has already completed, and deciding from your own numbers rather than vendor benchmarks.


TriSeed builds Earnest, a platform that automates the most labour-intensive steps of a financial due diligence engagement, including ledger extraction, flux analysis, lease term extraction, and bank statement processing. Some of that work is already classification: the flux module sorts accounts into recurring and non-recurring and flags transactions that deviate from account averages, with a written assessment attached to each finding. See how it works: triseed.co/projects/earnest


If you are weighing typed decision models against your own classification workload, or you want the mechanical half of your diligence prep handled first, start here.

Comments


bottom of page