AI agents

Calibrating a Verification Score Against Reviewer Labels

Antonio Evans8 min read

A desk with a printed page of reviewer labels, a spreadsheet open beside it showing score ranges in one column and counts of true and false verdicts in the next.
Key points

Key points

  1. 1A verification score is only useful after you compare it against human labels, so collect a few hundred labeled examples before choosing any cut point.
  2. 2Sort scores into bins wide enough to hold at least 30 positive examples each, then read precision, recall and false positive rate per bin.
  3. 3Calibration and discrimination are separate properties, and a score can look well calibrated while still missing most positives.
  4. 4Pick the cut point only after the bin table shows where precision stops rising and recall starts falling, then confirm it on a held-out slice you did not use for binning.

Define the target event and the sampling unit first

Calibration work fails most often at the definition stage, not the math stage. Before anyone scores or labels anything, write down two things in one sentence each: the target event ("this answer is supported by the retrieved passage") and the sampling unit ("one question, one retrieved passage, one generated answer").

Mixing units quietly corrupts the whole table. If some rows are whole responses and others are individual claims, a single false positive can mean different things in different rows, and precision per bin becomes uninterpretable. Retrieval evaluation already separates the retrieval step from the generation step for exactly this reason: a failure at one stage cascades into the other, and you cannot attribute it unless you measure them separately (Anyscale RAG evaluation docs). The same logic applies to verification scores. Fix the unit, then keep it fixed.

A second decision is whether the target event is binary or graded. Binary labels ("supported" / "not supported") are easier to calibrate into precision and recall, which is what a cut point needs. Graded labels are useful for diagnosis but require you to collapse them later, and collapsing after collection invites arguments. If your team needs graded judgments, collect them, but declare the collapse rule (for example, "partially supported counts as negative") before labeling starts.

Finally, decide what counts as "no evidence." Systems that answer without support, or that abstain, produce a third outcome that is neither positive nor cleanly negative. Abstention calibration is a distinct problem from answer accuracy, and studies of unanswerable questions show that retrieval coverage alone does not prevent unsupported answers (evidence-calibrated RAG study). Decide up front whether abstentions are excluded from the calibration set or labeled as negatives, and note it in the table caption.

Collect reviewer labels with a rubric and an adjudication path

Manual relevance labeling is the standard ground-truth route for retrieval quality, and it is expensive, slow and subjective (Evidently RAG evaluation guide). Plan for that cost rather than discovering it halfway through.

A workable rubric has four parts:

  1. The target event, restated in one sentence.
  2. Three to five positive examples and three to five negative examples, drawn from your own data, including at least one borderline case.
  3. A rule for partial support, citations and hedged language.
  4. A rule for out-of-scope items (wrong language, truncated input, missing passage).

Label in two passes. First, have two reviewers label the same 50 to 100 items independently. Measure agreement with a chance-corrected statistic rather than raw percent agreement, because raw agreement overstates reliability when one label dominates; measure choice should match the annotation design, and agreement should be reported with confidence intervals (IAA metric selection paper). If agreement is low, the fix is almost always the rubric, not the reviewers. Rewrite the ambiguous rule, relabel, and only then scale up.

Second, route disagreements to adjudication. A single adjudicator who sees both labels and the rubric resolves them in a short session, and the resolution is recorded as the final label. Do not average or majority-vote binary labels with two reviewers; you will get ties and hidden ambiguity.

Keep reviewers blind to the score during labeling. A reviewer who can see "0.91" anchors on it, and the resulting labels will correlate with the score for reasons that have nothing to do with correctness. Export only the item and its context.

Sample deliberately, not uniformly. If positives are rare, a uniform sample gives you mostly negatives and too few positives per bin. Two acceptable designs: a stratified sample that over-samples from the score's upper range and reweights later, or a uniform sample large enough that every planned bin holds at least 30 positives. Document which one you used, because the reported precision is only valid under that design.

Choose bins that hold enough positives to mean something

The short answer's threshold, at least 30 positives per bin, comes from the need to estimate a proportion without the interval swallowing the signal. With 30 positives, a precision near 0.9 has a 95 percent Wilson interval of roughly 0.74 to 0.97; with 10 positives it is roughly 0.60 to 0.98, which cannot separate a good bin from a mediocre one.

Quantile bins (equal counts) and fixed-width bins (equal score ranges) answer different questions. Use the table below to choose.

Bin schemeWhat it guaranteesWhen it misleadsBest for
Equal-width (0.0-0.1, 0.1-0.2, ...)Comparable score ranges across systemsEmpty or tiny bins where scores clusterReading a calibration curve directly
Equal-count (deciles by score)Similar sample size per binBins that span wildly different score widthsPrecision and recall trends
Fixed positive count (merge until 30+ positives)Stable precision estimatesUneven score boundaries, harder to explainChoosing a cut point
Operator-meaningful bands (low, medium, high)Matches how the product will be usedCoarse; hides curvature inside a bandProduct and policy decisions

The pragmatic default is equal-count bins, merged from the top and bottom until each holds at least 30 positives. If your labeled set has 400 items and 80 positives, that is at most two or three bins. That is fine. Two well-populated bins tell you more than ten noisy ones.

Plot the reliability diagram alongside the table. A calibration curve bins predictions and plots the fraction of positives per bin against the mean predicted score in that bin, which is the standard way to see whether a score of 0.8 really means 80 percent (scikit-learn probability calibration). Overconfidence looks like a curve below the diagonal; underconfidence looks like a curve above it.

Compute precision, recall and false positive rate per bin with intervals

For a score threshold t, every labeled item with score at or above t is predicted positive. Compute the four counts and derive the rates. Precision is the proportion of predicted positives that are truly positive; recall is the proportion of true positives that clear the threshold. These are the same definitions used for retrieval at a cut point, where precision at k measures the relevant share of the top k results and recall at k measures the share of all relevant items found in the top k (Anyscale RAG evaluation docs, retrieval metrics explainer).

from math import sqrt

def wilson(k, n, z=1.96):
    if n == 0:
        return (float("nan"), float("nan"))
    p = k / n
    denom = 1 + z**2 / n
    centre = (p + z**2 / (2 * n)) / denom
    margin = z * sqrt(p * (1 - p) / n + z**2 / (4 * n**2)) / denom
    return (max(0.0, centre - margin), min(1.0, centre + margin))

def bin_report(rows, threshold):
    # rows: list of (score, label) where label is 1 for the target event
    tp = sum(1 for s, y in rows if s >= threshold and y == 1)
    fp = sum(1 for s, y in rows if s >= threshold and y == 0)
    fn = sum(1 for s, y in rows if s < threshold and y == 1)
    tn = sum(1 for s, y in rows if s < threshold and y == 0)
    precision = tp / (tp + fp) if tp + fp else float("nan")
    recall = tp / (tp + fn) if tp + fn else float("nan")
    fpr = fp / (fp + tn) if fp + tn else float("nan")
    return {
        "threshold": threshold,
        "tp": tp, "fp": fp, "fn": fn, "tn": tn,
        "precision": round(precision, 3),
        "precision_ci": tuple(round(v, 3) for v in wilson(tp, tp + fp)),
        "recall": round(recall, 3),
        "recall_ci": tuple(round(v, 3) for v in wilson(tp, tp + fn)),
        "fpr": round(fpr, 3),
    }

labeled = [(0.95, 1), (0.88, 1), (0.81, 0), (0.72, 1), (0.55, 0)]
for t in (0.5, 0.7, 0.9):
    print(bin_report(labeled, t))

The Wilson interval is the right default for proportions near 0 or 1, which precision often is. Report the interval next to every point estimate. A bin showing precision 0.92 with an interval of 0.81 to 0.97 supports a decision; 0.92 with 0.55 to 0.99 does not.

Treat rates computed over thresholds, not disjoint bins. Cumulative rates from the top of the score range down are what a cut point actually uses. Per-bin rates are useful for spotting non-monotonic behavior, such as a middle band where precision dips, which often signals a subgroup the score mishandles.

Worked example: reading the table before choosing a cut point

Suppose you have 500 labeled items with 120 positives. Equal-count bins of 50 items each, merged from the top until each holds at least 30 positives, give four bins. The table below is illustrative, not measured.

Bin (score range)nPositivesPrecisionRecallFPR
0.90-1.0048400.83 (0.70-0.91)0.330.02
0.75-0.90132440.33 (0.26-0.41)0.370.20
0.50-0.75160220.14 (0.09-0.20)0.180.31
0.00-0.50160140.09 (0.05-0.15)0.120.36

Read it top down. Precision falls from 0.83 to 0.33 to 0.14. Recall accumulates as you lower the threshold: 0.33 at 0.90, 0.70 at 0.75, 0.88 at 0.50. The false positive rate climbs from 0.02 to 0.20 to 0.51.

The decision rule falls out of the product requirement. If a wrong verification is expensive (for example, it auto-approves content), you want precision high and the rate of false positives low, so the cut is at 0.90. If missing a true positive is expensive (for example, it drops a legitimate claim from a review queue), you accept the 0.75 cut, where recall nearly doubles and the confidence intervals on precision no longer overlap the 0.90 bin's. That non-overlap is the evidence that the drop is real rather than noise.

A worked number keeps this honest. To raise the 0.75 bin's precision from 0.33 to 0.83 by moving the threshold up, you gain 12 precision points and lose 37 percent of recall in absolute terms (0.70 down to 0.33), while the false positive count falls from 88 to 8. Whether that trade is acceptable is a product question, not a statistics question.

One caution: a score can be well calibrated and still discriminate poorly. A 70 percent prediction that is correct 70 percent of the time is calibrated, but if positives and negatives score similarly, no threshold separates them. Calibration and discrimination are distinct facets, and a model can be excellent at one and weak at the other (Cross Validated discussion). Check both: the reliability curve for calibration, the bin table for discrimination.

Confirm on a held-out slice and monitor after launch

Split your labeled set before you look at bins. Use roughly 70 percent for the bin table and 30 percent held out. Choose the candidate cut point on the first slice only, then compute precision, recall and false positive rate on the held-out slice. If the held-out precision lands inside the bin's confidence interval, the cut survives. If it lands far outside, the bin was too small or the sample was not representative, and you go back for more labels.

Run a sensitivity check too. Sweep thresholds in small steps around the candidate and record how much precision and recall change per step. A cut point sitting on a cliff is fragile; reviewers will notice the behavior change week to week.

After launch, keep the loop running. Log a random sample of production items with scores, send them to reviewers, and recompute the bin table on a regular cadence. Selective prediction systems make an explicit trade between coverage (the fraction of items the system handles) and risk (the error rate on those handled), and that trade shifts as inputs drift (selective prediction overview). Reviewers who disagree often reveal a rubric gap, so treat adjudication as a feedback channel into the rubric, not just a tiebreaker.

Two operational checks worth writing into the runbook. First, if any bin drops below 30 positives after a refresh, merge it. Second, if agreement on the held-out slice falls below the level you measured at the start, pause and re-review the rubric before trusting the new numbers.

If the scoring step itself is the bottleneck, running several models behind one interface cuts the plumbing: Quanta Inference (https://quantaintelligence.ai/inference) serves text, embedding and other models through one OpenAI-compatible API key, which keeps the collection and labeling pipeline stable while the scorer changes underneath. For teams that need the whole loop staffed, including reviewers and adjudicators, an engagement through Quanta Experts (https://quantaintelligence.ai/agents) can take the pipeline from rubric to bin table as a finished deliverable.

A final note on scope. Verification scores in question-answering systems are often computed over extracted spans, and span-level answers bring their own labeling quirks: answers can be multi-span, and exact-match definitions differ across studies (MultiSpanQA paper, experimental design study). If your target event is "the right span was extracted," decide how to score partially correct spans before labeling. That single decision will change your precision numbers more than any threshold you pick.

FAQ

FAQ

How many labeled examples do I actually need?

Enough that every bin you plan to report holds at least 30 positives. With a 20 percent positive rate, that means roughly 150 labeled items per bin, so three bins need about 450 labels. Start there, check the intervals, and add labels only where a bin's interval is too wide to support a decision.

Can I use an LLM as the labeler instead of people?

LLM judges are a reasonable way to scale coverage, and they are widely used for relevance and faithfulness scoring (Evidently RAG evaluation guide). Calibrate the LLM against a human-labeled slice first, and report its agreement with reviewers. If its agreement is low, its labels will move your bin table in ways you cannot explain to stakeholders.

My score looks well calibrated but recall is terrible. Is that a bug?

Not necessarily. Calibration is about whether the predicted probability matches the observed rate; recall is about separation. An 85 percent positive dataset where the model predicts near the base rate everywhere can be well calibrated and still miss most negatives, which is a known pattern in imbalanced settings (Cross Validated discussion). Look at the bin table before assuming a bug.

Should I report per-bin rates or cumulative rates?

Report both, labeled clearly. Cumulative rates from the top down are what a threshold uses, so they drive the cut point decision. Per-bin rates show curvature and subgroup problems that cumulative rates hide. Never mix the two in one table.

What do I do when reviewers disagree on the borderline cases?

Adjudicate them, record the decision, and then tighten the rubric with the new example. If disagreements cluster on a specific pattern, such as hedged claims or citations to a second document, that cluster is a signal that your target event definition is underspecified rather than that reviewers are unreliable (IAA metric selection paper).

Sources

Sources

  1. RAG evaluation
  2. Evidence-Calibrated RAG for Unanswerable Question ...
  3. A complete guide to RAG evaluation: metrics, testing and ...
  4. Selecting the Right Inter-annotator Agreement Metric for ...
  5. 1.16. Probability calibration
  6. Recall@K, Precision@K, MRR, MAP, NDCG #rag
  7. Poor balanced accuracy and minority recall but perfect ...
  8. Selective Prediction in Natural Language Processing
  9. MultiSpanQA: A Dataset for Multi-Span Question Answering
  10. Experimental Design of Extractive Question-Answering ...
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles