Geaggregeerde metrics verbergen fouten
97% in totaal kan één falend documenttype verbergen
Geaggregeerde metrics verbergen fouten is een gratis Claude Architect-les op CoddyKit. Dit is les 3 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Claude Architect. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Claude Architect bevat in totaal 4 lessen.
Het kopgetal liegt
Je extractiepijplijn rapporteert 97% nauwkeurigheid. Het dashboard staat op groen, de belanghebbenden zijn tevreden en iemand stelt voor om menselijke controle helemaal uit te schakelen.
Stop. Eén enkel geaggregeerd getal is een van de gevaarlijkste artefacten in een Claude-systeem in productie. Die 97% is een gemiddelde over een gemengde populatie. Gemiddelden zijn uitstekend in het wegwerken van precies de fouten die je het hardst raken.
In deze les leer je waarom nauwkeurigheid die alleen op aggregatie is gebaseerd een gedocumenteerd antipatroon is, en wat je in plaats daarvan moet meten voordat je menselijk toezicht automatiseert.
Anatomie van een misleidend gemiddelde
Stel dat je pijplijn drie documenttypen in gelijke aantallen verwerkt. De gecombineerde score is 97%. Ziet er gelijkmatig uit, toch?
Maar gecombineerde getallen worden gewogen op basis van volume, niet op basis van risico. Een klein documenttype met grote gevolgen kan volledig worden overstemd. Het geaggregeerde getal zegt niets over waar de 3% fouten terechtkomt — en in de praktijk zijn fouten vrijwel nooit gelijkmatig verdeeld.
# Same 97% aggregate, two very different realities
docs = {
"invoices": {"n": 1000, "correct": 990}, # 99.0%
"receipts": {"n": 1000, "correct": 985}, # 98.5%
"contracts": {"n": 1000, "correct": 935}, # 93.5%
}
total = sum(d["n"] for d in docs.values())
hits = sum(d["correct"] for d in docs.values())
print(f"aggregate = {hits/total:.1%}") # 97.0% — hides contracts
for name, d in docs.items():
print(name, f"{d['correct']/d['n']:.1%}")Eén falend documenttype
Dit is de foutmodus die je volgens het examen moet herkennen: geaggregeerde nauwkeurigheid kan slechte prestaties voor een specifiek documenttype of veld verbergen.
Contracten met 93,5% kunnen je documenten met de hoogste waarde en de grootste aansprakelijkheid zijn. Een handvol verkeerd uit contracten geëxtraheerde clausules kan meer kosten dan duizenden correct verwerkte kassabonnen ooit hebben bespaard. Toch rapporteert het dashboard vrolijk 97% en nodigt het je uit om te automatiseren.
Het getal is niet fout. Het beantwoordt alleen de verkeerde vraag. "Hoe goed zijn we gemiddeld?" is zelden de vraag die ertoe doet. "Waar zijn we het zwakst en hoeveel kost die zwakte ons?" is dat wel.
Fouten op veldniveau zijn nog moeilijker te zien
Het wordt subtieler. Zelfs binnen één documenttype kan de fout in één veld zitten. Een contractextractor kan partijen, datums en adressen perfect verwerken en toch in 20% van de gevallen stilletjes de termination_clause of liability_cap verminken.
Als je die velden samen gemiddeld, zie je nog steeds een comfortabele score. Deel daarom uit langs beide assen: op documenttype EN op veld. De cel waarin een kritisch documenttype samenkomt met een kritisch veld is waar je werkelijke risico zich concentreert.
# Stratify a labeled validation set by (doc_type, field)
import collections
stats = collections.defaultdict(lambda: [0, 0]) # [correct, total]
for row in labeled_validation_set:
key = (row["doc_type"], row["field"])
stats[key][1] += 1
stats[key][0] += int(row["pred"] == row["gold"])
for (doc, field), (ok, n) in sorted(stats.items()):
acc = ok / n
flag = " <-- REVIEW" if acc < 0.95 else ""
print(f"{doc:10} {field:18} {acc:.1%} (n={n}){flag}")Gestratificeerde willekeurige steekproeven
Hoe breng je deze verborgen cellen aan het licht? Niet door 100 willekeurige documenten te steekproeven — willekeurige steekproeven weerspiegelen je volumeverdeling, waardoor zeldzame maar kritieke typen vrijwel geen dekking krijgen.
Gebruik gestratificeerde willekeurige steekproeven: verdeel de populatie in strata (documenttype, bron, kritikaliteit van het veld) en neem vervolgens binnen elk stratum willekeurig steekproeven. Nu krijgt je contracttype met een laag volume een statistisch betekenisvolle steekproef in plaats van drie toevallige trekkingen.
Dit is de door het examen aanbevolen techniek om op te sporen wat aggregaten verbergen.
from collections import defaultdict
import random
def stratified_sample(docs, key_fn, per_stratum=50):
strata = defaultdict(list)
for d in docs:
strata[key_fn(d)].append(d)
sample = []
for stratum, items in strata.items():
k = min(per_stratum, len(items))
sample += random.sample(items, k) # random WITHIN stratum
return sample
audit_set = stratified_sample(all_docs, key_fn=lambda d: d["doc_type"])Geijkte betrouwbaarheid per veld
Gestratificeerde steekproeven vertellen je waar je offline staat. Om per document, in productie te beslissen of je automatisch accepteert of het naar een mens doorstuurt, heb je betrouwbaarheid per veld nodig die is geijkt op een gelabelde validatieset.
"Geijkt" is het cruciale woord. Een ruwe score die op betrouwbaarheid lijkt, betekent niets totdat je aan de hand van de juiste antwoorden hebt gecontroleerd dat documenten met een score van 0,9 in ongeveer 90% van de gevallen daadwerkelijk correct zijn. Kalibreer eerst; pas daarna betekent een drempel zoals "automatisch accepteren boven 0,97" wat je denkt dat die betekent.
# Calibrate, then gate per field
def route_extraction(field_name, value, confidence, thresholds):
# thresholds[field] derived from a LABELED validation set,
# tighter for high-stakes fields
if confidence >= thresholds[field_name]:
return "auto_accept"
return "human_review"
thresholds = {
"vendor_name": 0.92,
"liability_cap": 0.99, # critical -> stricter gate
"termination_clause": 0.99,
}Zelfcorrectie brengt afwijkingen aan het licht
Geijkte betrouwbaarheid is niet het enige signaal. Bij numerieke extractie kun je het model zijn eigen werk laten tonen, zodat je fouten deterministisch kunt opsporen.
Extraheer beide calculated_total (opgeteld uit de regelitems) en stated_total (het afgedrukte totaal). Wanneer ze van elkaar verschillen, heb je een afwijking gevonden die geen enkele geaggregeerde metriek ooit zou onthullen — een verifieerbare waarschuwing op documentniveau die rechtstreeks naar controle wordt doorgestuurd.
# Self-correction: extract both, compare deterministically
schema = {
"type": "object",
"properties": {
"line_items": {"type": "array", "items": {"type": "number"}},
"calculated_total": {"type": "number"}, # model sums line items
"stated_total": {"type": "number"} # printed on the doc
},
"required": ["line_items", "calculated_total", "stated_total"]
}
def needs_review(out):
return abs(out["calculated_total"] - out["stated_total"]) > 0.01Herhaal niet wat kalibratie aan het licht brengt
Wanneer een document met lage betrouwbaarheid of een afwijking aan het licht komt, wees dan precies over de oplossing. Opnieuw proberen met feedback herstelt opmaak-, structurele en rekenkundige fouten — stuur het oorspronkelijke document, de onjuiste uitvoer en de exacte validatiefout terug naar het model.
Opnieuw proberen helpt echter niet wanneer de informatie eenvoudigweg ontbreekt in de bron. Als het contract geen aansprakelijkheidslimiet vermeldt, zal geen enkele nieuwe prompt er een tevoorschijn toveren — en een model dat er een verzint, veroorzaakt precies de fout die je met je metrieken moet opsporen. Ontbrekende gegevens zijn een geval voor escalatie, geen geval om opnieuw te proberen.
def handle_low_confidence(doc, output, error):
if error.kind in ("format", "arithmetic", "schema"):
# retry with original doc + wrong output + exact error
return retry_with_feedback(doc, output, error)
if error.kind == "absent":
# info not in source -> never retry; route to human
return escalate_to_human(doc, reason="field absent in source")Schema's mogen niets laten verzinnen
Dit sluit aan op een regel voor gestructureerde uitvoer die rechtstreeks invloed heeft op je metrieken. Markeer een schema-veld alleen als verplicht wanneer het altijd aanwezig is. Maak een veld dat kan ontbreken nooit verplicht — het model zal een waarde verzinnen om aan het schema te voldoen, en een verzonnen waarde telt nog steeds als een zelfverzekerd antwoord.
Die verzonnen waarde kan een controle op geaggregeerde nauwkeurigheid moeiteloos passeren en tegelijk je veld met de grootste gevolgen vervuilen. Maak optionele velden optioneel en gebruik een enum met een waarde "other" plus een detailveld met vrije tekst voor uitbreidbaarheid.
{
"type": "object",
"properties": {
"vendor_name": {"type": "string"},
"liability_cap": {"type": ["number", "null"]},
"doc_category": {
"type": "string",
"enum": ["invoice", "receipt", "contract", "other"]
},
"category_detail": {"type": "string"}
},
"required": ["vendor_name", "doc_category"]
}Herkomstinformatie maakt fouten controleerbaar
Om een verborgen fout te onderzoeken, moet je elke geëxtraheerde claim kunnen terugleiden naar de oorsprong ervan. Houd koppelingen van claims aan bronnen bij: de naam van het brondocument, het exacte citaat, de locatie en de publicatiedatum.
Wanneer een gestratificeerde audit de contractstratum markeert, stelt herkomst een beoordelaar in staat rechtstreeks naar het citaat te springen dat een onjuiste liability_cap heeft opgeleverd — in plaats van het hele document opnieuw te lezen. Herkomst verandert "ergens lijkt onze metriek niet te kloppen" in "dit veld, uit dit citaat, op deze pagina, is onjuist."
extraction = {
"field": "liability_cap",
"value": 500000,
"provenance": {
"source_doc": "acme_msa_2026.pdf",
"quote": "liability shall not exceed five hundred thousand dollars",
"page": 7,
"published": "2026-01-15"
}
}Beslis op basis van bewijs, niet op gevoel
Breng dit samen tot een automatiseringsbesluit. Je mag het menselijke toezicht op een stratum alleen verminderen wanneer het bewijs voor die specifieke stratum dat ondersteunt.
- De gestratificeerde audit toont aan dat de stratum de beoogde nauwkeurigheid haalt.
- Het vertrouwen op veldniveau is gekalibreerd op gelabelde gegevens.
- Zelfcorrectie en herkomst vangen de resterende fouten op.
Let ook op wat niet op deze lijst staat: een door het model zelf ingeschatte betrouwbaarheid (1-10) of een sentimentscore is een slechte trigger voor escalatie. Goede triggers zijn drempeloverschrijdingen, hiaten in beleid, uitblijvende voortgang en expliciete verzoeken van mensen — niet de eigen, ongetrainde zelfinschatting van het model.
Korte controle: de 97% lezen
Een scenariovraag over metrieken en toezicht.
Samenvatting: maak verborgen fouten zichtbaar
Belangrijkste punten:
- Geaggregeerde nauwkeurigheid verbergt fouten per type en per veld — ze is gewogen naar volume, niet naar risico.
- Stratificeer voordat je vertrouwt: gestratificeerde willekeurige steekproeven per documenttype en veld brengen zwakke cellen aan het licht die een willekeurige steekproef mist.
- Kalibreer het vertrouwen op veldniveau op een gelabelde validatieset voordat je een drempel gebruikt voor automatische acceptatie.
- Zelfcorrectie (extractie van calculated_total en stated_total) en herkomst (citaat, pagina en datum van claim en bron) vangen resterende fouten op en verklaren ze.
- Stel mogelijk ontbrekende velden niet verplicht (verzinnen) en escaleer niet op zelf ingeschat vertrouwen of sentiment — gebruik drempeloverschrijdingen, hiaten in beleid, uitblijvende voortgang en expliciete verzoeken van mensen.
Verdien automatisering per stratum, op basis van bewijs. Het groene dashboard is het begin van het onderzoek, niet het einde.
Leer Python met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 26
- Lessen
- 104
Veelgestelde vragen
Is de les “Geaggregeerde metrics verbergen fouten” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Claude Architect, waaronder “Geaggregeerde metrics verbergen fouten”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Claude Architect bevat in totaal 4 lessen.
Wat leer ik in “Geaggregeerde metrics verbergen fouten”?
97% in totaal kan één falend documenttype verbergen Je oefent met Claude Architect door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Claude Architect te beginnen?
Ervaring vooraf is niet nodig. Claude Architect op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.
Hoe lang duurt de les “Geaggregeerde metrics verbergen fouten”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Claude Architect?
Ja. Elke les over Claude Architect bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Koppelingen tussen claims en bronnen
- Tegenstrijdige gegevens en datums
- Geaggregeerde metrics verbergen fouten
- Gestratificeerde steekproeven en kalibratie