Trusting the numbers: calibration and shadow tests
- Define calibration and expected calibration error (ECE) in plain words
- Read the independent calibration findings on Jev, and their limits
- Calibrate a probability with a temperature fit, in code
- Design a shadow test that would catch the failures reviewers actually found
Refresher: what "calibrated" means
Suppose a weather app says "70% chance of rain" on 100 different days. If it is calibrated, it rained on about 70 of them. If it rained on 45, the app is overconfident: it sounds surer than it has earned.
A typed-decision model does the same. When it says 0.9 on a ticket, you want it right about 90 times in 100 such tickets. That property is what lets you write "handle anything above 0.9 automatically". If the property is false, that rule quietly lets errors through.
Expected calibration error (ECE) is a single number for how far off the model is: group answers by stated confidence, compare each group's stated confidence to its real accuracy, average the gaps. Zero is perfect. A model can be very accurate and still badly calibrated, and the reverse.
What independent testers found
One study, by scienthoon, deliberately used 900 support tickets generated by a script on 19 September 2026, so the model could not have seen them, plus three public benchmarks. Here are the reported numbers.
- OpenBookQA (500)accuracy 94.2% · ECE 0.024
- CommonsenseQA (1,221)accuracy 88.1% · ECE 0.032
- HellaSwag (2,000)accuracy 86.1% · ECE 0.029
Authors’ advice: do not threshold on the separate confidence field, calibrate per question rather than per model, and treat the output as a ranking until you have calibrated it locally.
The story is in the two tabs. On public benchmarks, which a model may have seen in training, the calibration error is small. On new tasks it is worse, and on the "priority" question, which depended on a company rule not present in the text, Jev averaged 0.74 confidence while being right 44.7% of the time. It was confidently guessing at something unknowable. (scienthoon)
The same study noted:
- Probabilities are quantised to 0.01 and often exactly 0 or 1, so a correct answer given zero probability cannot be recovered
- Choice and score answers were overconfident; yes/no was underconfident, so one fix does not suit all
- Do not threshold on the separate
confidencefield: it did worse than the highest probability - Calibrate per question, not per model
Another reviewer found the same direction across studies (median ECE of 0.071 on a 13-subset public suite as shipped, with the direction varying by domain), and noted that one temperature fitted on 50 labels cut a comparison model's median ECE from 0.180 to 0.080 (xbill). Fifty labels is a small ask.
Calibrate it yourself
The fix is cheap: keep a labelled sample, and learn a correction. This code measures ECE on synthetic overconfident data, then fits one temperature on a small sample. It runs as written.
import math, random
random.seed(5)
def ece(probs, correct, bins=10):
n, total = len(probs), 0.0
for b in range(bins):
lo, hi = b / bins, (b + 1) / bins
idx = [i for i, p in enumerate(probs) if lo <= p < hi or (b == bins - 1 and p >= hi)]
if not idx:
continue
conf = sum(probs[i] for i in idx) / len(idx)
acc = sum(correct[i] for i in idx) / len(idx)
total += len(idx) / n * abs(acc - conf)
return total
def scale(p, T):
"""Temperature: divide the log-odds by T. T above 1 makes it less confident."""
p = min(max(p, 1e-4), 1 - 1e-4)
return 1 / (1 + math.exp(-math.log(p / (1 - p)) / T))
# synthetic: stated confidence is high, but real accuracy is 15 points lower
def sample(n):
probs = [min(0.999, 0.6 + 0.4 * random.random()) for _ in range(n)]
correct = [1 if random.random() < max(0.0, p - 0.15) else 0 for p in probs]
return probs, correct
fit_p, fit_c = sample(50) # your small labelled sample
test_p, test_c = sample(2000) # traffic you evaluate on
def nll(T):
return -sum(math.log(scale(p, T) if c else 1 - scale(p, T)) for p, c in zip(fit_p, fit_c))
best_T = min([t / 10 for t in range(5, 60)], key=nll)
print("ECE as stated: ", round(ece(test_p, test_c), 3))
print("fitted temperature: ", best_T)
print("ECE after fitting: ", round(ece([scale(p, best_T) for p in test_p], test_c), 3))
Run it. The error falls once a temperature is fitted on just 50 labelled examples. On real data, do this per question type.
Wording is a release
A quieter finding from the same review: asking the identical question twice changed only 1.33% of answers, but swapping which rubric sat behind "yes" and "no" changed 32.5%.
Asking the identical question twice changed only 1.33% of answers, so the model is steady. But it is steady about the wording, not just the meaning. Small, reasonable-looking edits to your instructions can move a third of your decisions. That is why every prompt change here is a release, and why the Shadow Evaluation Harness matters more, not less.
Two practical rules follow:
- Pin the model version you tested. The launch material mentions "Jev 1.13"; a silent version change is a silent behaviour change.
- Every edit to your criteria is a release. Re-run your test set. This is exactly the Shadow Evaluation Harness rule.
A shadow test that would have caught the known failures
Run the typed-decision model beside your current process, on real traffic, deciding nothing. Then check:
| Check | Catches |
|---|---|
| Accuracy by confidence band | Overconfidence: does 0.9 really mean 90%? |
| Accuracy per language | The drops seen in Russian and Spanish |
| Accuracy on a "cannot know" set | Confident guessing at unknowable questions |
| Same items, reworded criteria | The 32.5% wording sensitivity |
| Same items, run twice | Repeatability |
| Errors that live passes and this fails | Regressions (block on these, whatever the average) |
| Latency from your region | Vendor speed claims vs your network |
Then a small canary behind an approval gate. One reviewer's whole pre-registered study ran 5,721 calls for $0.176 at list price (Beri). Testing is not the expensive part.
- Calibrated means stated confidence matches real accuracy; ECE measures the gap
- Independent tests found overconfidence on choice and score answers and underconfidence on yes/no; TypeSafe publishes no calibration metrics
- A temperature fitted on about 50 labels can help a lot; calibrate per question type
- Rewording criteria moved 32.5% of answers in one test: prompt edits are releases
- Shadow first, on your data, with confidence bands, languages, wording, repeatability and regressions; report accuracy with coverage
- The model says 0.9 on 200 tickets and is right on 150. What is its real accuracy there, and is it over- or under-confident?
- Why should you not set your auto-handle line from the number in a vendor's blog post?
- Your team changes a criteria sentence to be "clearer". What must you do before shipping, and why?
Sources
All pages read on 25 September 2026. Figures were pulled through a summarising fetch tool, so check any number on the linked page before you quote it.
- scienthoon, jev-ood-calibration. 900 out-of-distribution tickets plus three public benchmarks; per-type miscalibration; reproducible for about $0.06.
- xbill, Jev after eight days of independent tests. Median ECE, repeatability, the 32.5% option-swap result, language drops.
- Layer3 Labs, Jev benchmarks. What TypeSafe has not published; advice to validate on your own labels.
- Beri, phishing experiment. Shadow-evaluation advice and study cost.
- This site: Shadow Evaluation Harness, Trace Pipeline.