0Pricing
Claude Architect · Lección

Muestreo estratificado y calibración

Muestree por segmento y calibre con conjuntos de validación etiquetados.

Muestreo estratificado y calibración es una lección gratuita de Claude Architect en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Claude Architect, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Claude Architect incluye 4 lecciones en total.

Partes de esta lección aún no han sido traducidas y se muestran en inglés.

Why Aggregate Accuracy Lies

You ship a Claude extraction pipeline and report 97% accuracy. Leadership approves full automation. Three weeks later, every refund invoice with a foreign-currency line is wrong.

The headline number was real — but it was an average. Aggregate accuracy can hide catastrophic failure on a specific document type or a specific field, because the common cases drown out the rare ones.

This lesson is about the discipline that keeps you honest before you automate: stratified sampling to measure where you actually fail, and calibration on labeled validation sets so your confidence scores mean something.

The Core Rule

Memorize the exam-level principle from the oversight domain:

Aggregate accuracy can hide poor performance on a specific document type or field. Use stratified random sampling plus field-level confidence calibrated on labeled validation sets before automating.

Two moves, in order:

  • Stratify, then sample — partition the population into segments, sample within each, so rare-but-critical slices are actually measured.
  • Calibrate confidence — make the model's per-field confidence correspond to real-world correctness, proven against ground-truth labels.

Skip either step and you are guessing, not governing.

Why Random Sampling Isn't Enough

Plain random sampling oversamples whatever is common. If 95% of your invoices are simple single-currency receipts, a random sample of 200 will be ~190 easy cases and maybe a handful of the hard foreign-currency ones — too few to detect a 40% error rate on that slice.

Stratified sampling fixes this: define segments that matter (document type, language, vendor, field presence), then draw a sample from each segment. Now the rare slice is measured with enough statistical power to fail loudly if it's broken.

You measure the population you're worried about, not the population that happens to be biggest.

Choosing Your Strata

Good strata isolate the dimensions where behavior plausibly diverges. For a structured-extraction pipeline (Scenario 6), useful segments include:

  • Document type — invoice vs. receipt vs. statement.
  • Field — totals, dates, currency, line items. Field-level matters because 97% overall can mask 60% on the currency field.
  • Edge conditions — multi-page docs, scanned/low-quality, multilingual, or records where an optional field is absent.

That last one ties to a schema rule: never mark a possibly-absent field as required, or the model fabricates it. Stratify by presence/absence so you catch fabrication.

Drawing a Stratified Sample

Concretely, group your validation pool by segment and pull a fixed quota from each — enough per stratum to trust the per-stratum metric, not proportional to the population.

import random
from collections import defaultdict

# Each record carries the dimensions we stratify on.
def segment_key(rec):
    return (rec["doc_type"], rec["has_currency_line"], rec["is_multilingual"])

buckets = defaultdict(list)
for rec in validation_pool:
    buckets[segment_key(rec)].append(rec)

# Fixed quota per stratum -> rare slices get real coverage,
# not just a couple of incidental samples.
PER_STRATUM = 40
sample = []
for key, recs in buckets.items():
    random.shuffle(recs)
    sample.extend(recs[:PER_STRATUM])

print({k: min(len(v), PER_STRATUM) for k, v in buckets.items()})

Field-Level Confidence, Not Just a Verdict

To calibrate, the model has to emit a confidence per field, not one blanket score. Force structured output so confidence is a typed field you can audit — not prose you parse.

Use tool_choice to guarantee the model returns the schema. "any" forces it to call some tool; {"type":"tool","name":"X"} forces a specific one. A JSON Schema eliminates syntax errors and enforces required fields.

extract_tool = {
    "name": "emit_extraction",
    "description": "Return extracted fields, each with a per-field confidence in [0,1].",
    "input_schema": {
        "type": "object",
        "properties": {
            "fields": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "value": {"type": "string"},
                        "confidence": {"type": "number"}
                    },
                    "required": ["name", "value", "confidence"]
                }
            }
        },
        "required": ["fields"]
    }
}

resp = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=[extract_tool],
    tool_choice={"type": "tool", "name": "emit_extraction"},
    messages=[{"role": "user", "content": invoice_text}],
)

What Calibration Actually Means

A model is calibrated when its stated confidence matches observed accuracy: of all fields it labels 0.90 confident, about 90% should be correct against ground truth.

Raw model confidence is usually over-confident — it says 0.95 but is right 70% of the time. You can't trust an auto-accept threshold built on uncalibrated scores; you'd auto-approve wrong data.

Calibration requires labeled validation sets: human-verified ground truth for your stratified sample. There is no shortcut — the model's self-rated confidence alone is exactly the kind of signal the exam tells you NOT to trust for automated decisions.

Measuring Calibration with Labels

Bucket predictions by stated confidence, then compare each bucket's stated confidence to its actual accuracy on the labeled set. The gap is your calibration error — and you compute it per stratum so a well-calibrated 'easy' slice can't mask a broken 'hard' one.

from collections import defaultdict

# preds: list of {stratum, confidence, predicted, ground_truth}
bins = defaultdict(lambda: {"n": 0, "correct": 0, "conf_sum": 0.0})

for p in preds:
    b = round(p["confidence"], 1)              # 0.0..1.0 buckets
    key = (p["stratum"], b)
    bins[key]["n"] += 1
    bins[key]["conf_sum"] += p["confidence"]
    bins[key]["correct"] += int(p["predicted"] == p["ground_truth"])

for (stratum, b), s in sorted(bins.items()):
    stated = s["conf_sum"] / s["n"]
    actual = s["correct"] / s["n"]
    print(stratum, b, f"stated={stated:.2f} actual={actual:.2f} gap={stated-actual:+.2f}")

Setting Auto-Accept Thresholds Per Segment

Once calibrated, derive a confidence threshold for each stratum that meets your accuracy bar — say, auto-accept only where calibrated accuracy ≥ 99%. The threshold will differ by segment: easy single-currency invoices might auto-accept at 0.85, while foreign-currency lines need 0.98 — or stay human-reviewed entirely.

This is the bridge from measurement to oversight: low-confidence or low-accuracy strata route to a human; high-confidence calibrated strata automate. A single global threshold would either over-trust the hard slice or needlessly gate the easy one.

Self-Correction Strengthens the Signal

Confidence improves when the model can cross-check itself. For numeric extraction, have it emit both a calculated_total (sum of line items) and the stated_total printed on the document, then flag any discrepancy. A mismatch is a hard, deterministic signal — far more reliable than a self-rated confidence number.

Pair this with provenance: keep each claim's source (doc name, quote, page) so a flagged field can be traced and verified, not just re-guessed.

verify_schema = {
    "name": "emit_totals",
    "description": "Extract both the computed and printed total so discrepancies are detectable.",
    "input_schema": {
        "type": "object",
        "properties": {
            "line_items": {"type": "array", "items": {"type": "number"}},
            "calculated_total": {"type": "number"},
            "stated_total": {"type": "number"},
            "source_quote": {"type": "string"}
        },
        "required": ["calculated_total", "stated_total", "source_quote"]
    }
}

# Deterministic check beats trusting a self-rated score:
# discrepancy = abs(out['calculated_total'] - out['stated_total']) > 0.01

Run the Audit Off the Critical Path

Stratified calibration audits are large, non-blocking jobs — exactly what the Message Batches API is for: 50% cheaper, up to a 24-hour window, no latency SLA. Run your overnight calibration sweep as a batch; correlate results with custom_id and re-submit only the failures.

The boundary matters for the exam: never use the Batch API for blocking or time-sensitive checks (it has no latency SLA and does not support multi-turn tool calling). A pre-merge gate or a live extraction stays on the synchronous API; the periodic audit goes to batch.

requests = [
    {
        "custom_id": f"val-{rec['id']}",
        "params": {
            "model": "claude-sonnet-4-5",
            "max_tokens": 1024,
            "tools": [extract_tool],
            "tool_choice": {"type": "tool", "name": "emit_extraction"},
            "messages": [{"role": "user", "content": rec["text"]}],
        },
    }
    for rec in stratified_sample
]

batch = client.messages.batches.create(requests=requests)
# Overnight audit: no latency SLA, 50% cheaper. NOT for pre-merge gates.

Quick Check: Approving Automation

Apply the rule to a real go/no-go decision.

Recap: Measure Before You Trust

Key takeaways for the exam and for production:

  • Aggregate accuracy hides per-type and per-field failure — never automate on a headline average alone.
  • Stratified random sampling partitions by the dimensions that matter (doc type, field, edge conditions) and samples each, giving rare slices real statistical power.
  • Calibration aligns stated confidence with observed accuracy, proven on a labeled validation set; raw model confidence is over-confident and self-rated scores are not a trustworthy automation signal.
  • Set auto-accept thresholds per segment; automate calibrated high-accuracy strata, route the rest to humans.
  • Strengthen the signal with self-correction (calculated vs. stated total) and provenance; run the heavy calibration audit on the Batch API — never on a blocking, time-sensitive path.

Preguntas frecuentes

¿La lección «Muestreo estratificado y calibración» es gratis?

Sí — el texto completo de «Muestreo estratificado y calibración» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Claude Architect, actualiza a CoddyKit PRO. El curso de Claude Architect incluye 4 lecciones en total.

¿Qué aprenderé en «Muestreo estratificado y calibración»?

Muestree por segmento y calibre con conjuntos de validación etiquetados. Practicas Claude Architect con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Claude Architect?

No se requiere experiencia previa. Claude Architect en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Muestreo estratificado y calibración»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Claude Architect?

Sí. Cada lección de Claude Architect incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Correspondencia entre afirmaciones y fuentes
  2. Datos y fechas en conflicto
  3. Las métricas agregadas ocultan fallos
  4. Muestreo estratificado y calibración
← Volver a Claude Architect