LLMModule 01 · Evaluation & decision-making

LLM evals with decision models: thresholds, trade-offs and calibration

Turning a model's 0–1 score into a reliable yes/no, and knowing when you can trust that score.

Source: Hamel Husain & Antaripa Saha, “How To Use Decision Models for Evals”, 20 Oct 2026 · X post · full post with interactive charts

In this module
  1. Summary
  2. Why this matters for robotics
  3. Deep dive: decision thresholds
  4. Deep dive: precision, recall and minimum bars
  5. Deep dive: tuning without fooling yourself
  6. Deep dive: performance vs. cost
  7. Deep dive: can you trust the probability?
  8. Playbook
  9. Self-check
  10. Glossary & further reading

1. Summary

TL;DR

A new class of decision models (TypeSafe Jev, Perplexity Decider, Liquid d1, Cloudflare Clef, OpenAI Decisions) are cheap, fast classifiers that return a failure probability. Most people use them with the default 0.50 cut-off. That's a mistake. Set minimum precision and recall for your use case, tune the threshold on labelled data with cross-validation, check calibration before treating scores as confidence, and only then compare models on cost.

2. Why this matters for robotics

Track: LLM. The source is about evaluating LLM agents with cheap classifier models. The same score-to-decision maths also drives robot perception and safety stops, as the robotics section below shows.

3. Deep dive: decision thresholds

A decision model outputs a score s ∈ [0, 1]. The API converts it into a label with a rule: flag as fail if s ≥ t. The default t = 0.50 assumes the scores are calibrated and that false alarms and misses cost the same. Neither is usually true.

The authors' example: a model gives every failure 0.40 and every pass 0.10. It separates the classes perfectly (any threshold between 0.10 and 0.40 is flawless) but at 0.50 it catches nothing. Ranking quality and threshold choice are separate problems.

In real data the two score distributions overlap. Moving the threshold slides a line across both. Try it:

Interactive: move the threshold

■ failing traces   ■ passing traces. Everything right of the line gets flagged.

Precision
–
Recall
–
F1
–
Best-F1 t
–

Simulated data: 30% failure rate, scores skewed low like many real models. Notice how often the best threshold isn't 0.50.

4. Deep dive: precision, recall and minimum bars

MetricQuestion it answersFormula
PrecisionOf what I flagged, how much was really a failure?TP / (TP + FP)
RecallOf all real failures, how many did I catch?TP / (TP + FN)
F1Balanced single number (harmonic mean)2PR / (P + R)
F-betaWeighted: β<1 favours precision, β>1 favours recall(1+β²)PR / (β²P + R)

Pick the trade-off from the business (or safety) consequences, not from habit:

The key move in the article is to set hard minimums before optimising, e.g. ≥80% on both for an alerting system. Plot precision and recall against threshold. The usable region is where both curves clear the bar. Models with no such region are eliminated, whatever their F1.

5. Deep dive: tuning without fooling yourself

With only 100 labelled examples, picking the threshold that looks best on all of them overfits. The authors use stratified five-fold cross-validation:

  1. Split the labelled traces into 5 folds, keeping the failure ratio equal in each (stratified).
  2. For each fold, choose the threshold on the other 4 folds, restricted to thresholds meeting both minimums.
  3. Measure precision, recall and F1 on the held-out fold.
  4. Use the same splits for every model so the comparison is fair.
  5. If no threshold qualifies, report it. Don't quietly relax the bar.

Important practical detail: save the scores once and reuse them. Tuning is free after the first API pass. They give a ready-made prompt for a coding agent:

Using my saved model scores and binary labels (1 means failure), tune a decision threshold to maximize F1 while requiring at least 80% precision and 80% recall. Use stratified five-fold cross-validation… Reuse the saved scores without making new model calls.
Python sketch (scikit-learn)
import numpy as np
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import precision_score, recall_score, f1_score

def tune(s, y, min_p=.8, min_r=.8, seed=0):
    ts = np.linspace(.01, .99, 99)
    out = []
    for tr, va in StratifiedKFold(5, shuffle=True, random_state=seed).split(s, y):
        ok = [(f1_score(y[tr], s[tr] >= t), t) for t in ts
              if precision_score(y[tr], s[tr] >= t, zero_division=0) >= min_p
              and recall_score(y[tr], s[tr] >= t) >= min_r]
        if not ok:
            out.append(None); continue
        t = max(ok)[1]
        p = s[va] >= t
        out.append((t, precision_score(y[va], p, zero_division=0),
                    recall_score(y[va], p), f1_score(y[va], p)))
    return out

Result in the article: the three candidate models gained a little from tuning. The weaker models (Liquid d1, Clef Flash) gained more but still fell below the minimums. Small precision/recall shifts can still matter a lot in production.

6. Deep dive: performance vs. cost

Candidate (met 80/80 bar)Tuned F1Cost / 100 evals
Perplexity Decider 1.1 27B0.790.82¢
Liquid d1-ultrabetween the twobetween the two
OpenAI Decisions (GPT-6 Luna)0.873.72¢

Use a Pareto frontier: for each quality level, the cheapest model that reaches it. Anything above and to the left of the frontier is dominated. Latency was left out because it depends on things outside the experiment, but in robotics it's often the binding constraint. A 300 ms classifier can't sit inside a 100 Hz control loop.

The authors' heuristic: start with a big model that performs acceptably, then try smaller ones to see if they match it for less. Also, narrower judges (one per failure mode) tend to shrink the gap between models.

7. Deep dive: can you trust the probability?

A score is calibrated if, among cases scored ~0.80, about 80% actually fail. Check with a reliability diagram: bin predictions (~20 traces per bin), plot mean predicted probability vs. observed failure rate.

Platt scaling fixes this by fitting a logistic regression on the log-odds of the score: p' = σ(a · logit(s) + b). Clip scores away from 0 and 1 first. Fit it inside cross-validation, and judge it with the Brier score (mean squared error of probabilities, lower is better).

Calibration isn't free improvement. It helped three models, barely changed two that were already good, and slightly hurt OpenAI. Measure it, don't assume it.

Calibration doesn't change ranking, so it won't change the best threshold's precision/recall. It matters when you use the number itself: risk scores, expected-cost decisions, fusion with other probabilities.

8. Playbook

  1. Write a clear pass/fail criterion and get it right first (prompt and labels).
  2. Label a set of real examples by hand.
  3. Set minimum precision and recall from the consequences of each error type. Drop models that can't meet them.
  4. Score everything once, save the scores, and tune each model's threshold with stratified CV on shared splits.
  5. If you'll use scores as confidence, check calibration and try Platt scaling. Keep it only if the Brier score improves.
  6. Compare surviving models on quality vs. cost (and latency). Pick from the Pareto frontier.
  7. Iterate. A new prompt means re-tuning the threshold and re-checking calibration.

9. Self-check

A model scores all failures 0.35–0.45 and all passes 0.05–0.15. What's its recall at t = 0.50?

0%. It flags nothing. Yet at t = 0.25 it's perfect. Ranking is great, the default threshold is wrong.

Your robot's human-proximity detector: favour precision or recall? Which F-beta?

Recall. Missing a person is far worse than a false stop. Use β > 1 (e.g. F2), plus a hard recall floor near 100%.

Why use the same CV splits for every model?

With small datasets, split luck swings results. Shared splits make sure differences come from the models, not from which examples landed in which fold.

Platt scaling improved a model's reliability diagram. Will its F1 at the tuned threshold change?

No, not materially. Platt scaling is monotonic, so ranking is preserved. The tuned threshold just moves to the equivalent spot. Calibration matters when the probability value itself is used.

When is a cheaper, lower-F1 model the right choice?

When it clears your minimum bars and the volume, latency or on-device budget makes the expensive one impractical, e.g. running on every log line or on a robot's onboard compute.

10. Glossary & further reading

TermMeaning
Decision modelSmall, fast classifier API returning a probability for a yes/no question. A cheap alternative to an LLM judge.
LLM judgeAn LLM prompted to grade another model's output.
TraceLog of an agent's conversation and actions (in robotics: a rollout or episode log).
ThresholdScore cut-off above which a case is flagged.
Pareto frontierSet of options where you can't improve one metric without worsening another.
CalibrationHow well predicted probabilities match observed frequencies.
Platt scalingLogistic-regression mapping that recalibrates scores.
Brier scoreMean squared error between predicted probability and the 0/1 outcome.