Notities uit de Release-cyclus — Deel VI
Een scored-QA-suite begon het medische Q&A-model van een klant te markeren. Het kopcijfer — geaggregeerde kwaliteit over alle slices — daalde van de ene op de andere dag met 6 punten. Het team besteedde twee dagen aan het debuggen van het model. Ze draaiden fine-tunes opnieuw. Ze rolden terug naar de vorige release. De cijfers bewogen niet.
Op de ochtend van dag drie merkte iemand op dat de eval-suite was bijgewerkt in dezelfde nacht dat de regressie begon. Drie nieuwe prompts over pediatrische dosering waren toegevoegd aan de testset, en het model had pediatrische dosering nog nooit in training gezien. De “QA-storing” was geen modelregressie. Het was een slice-dekkingsgebeurtenis: de eval begon iets te vragen wat het model nooit had hoeven weten.
Over onze klant-uitrolprojecten is dit het dominante patroon. Een “QA-storings”-alert is het symptoom. De oorzaak is het model ongeveer één op de zeven keer. De andere zes keer zit de bug ergens upstream: in het eval-ontwerp, in de judge-kalibratie, in de prompt-SHA, in de preprocessing-pijplijn, in de datasetversie of in de retrieval-index. Elk van deze klassen van bugs ziet er identiek uit vanuit het alert — een getal ging omlaag — maar heeft een volledig andere oplossing.
Deze post is de diagnostische boom die we op volgorde doorlopen wanneer een alert afgaat. Zes stappen die niet-model-oorzaken uitsluiten, voordat de zevende stap het model zelf overweegt. Elke stap heeft een concrete API-call of query die hem beantwoordt. Tegen de tijd dat je de zes hebt voltooid, weet je ofwel precies wat je moet repareren, of je hebt het recht verdiend om naar het model te kijken.
De beslisboom
De boom is sequentieel omdat de stappen lopen van goedkoop naar duur. Stap 1 is een git diff van de eval-suite; stap 7 is een fine-tune-cyclus. Je wilt tien minuten besteden aan elk van de zes goedkope checks voordat je een week besteedt aan de dure.
Stap 1 — Dekte de eval deze slice?
Het symptoom. Geaggregeerde kwaliteit daalt, maar de per-slice-uitsplitsing toont dat één slice instort terwijl de andere vlak zijn. Of — verwarrender — elke slice daalt licht, allemaal met vergelijkbare hoeveelheden.
De diagnose. Diff de eval-suite-manifest-SHA tegen die van de vorige release. Als de eval-suite veranderde en je het model niet veranderde, zit de regressie in de eval, niet in het model.
# Vergelijk de eval-suite-manifest-SHA tussen releases
curl https://api.divinci.ai/v1/releases/rel_a01c66 | jq '.eval_suite_sha256'
curl https://api.divinci.ai/v1/releases/rel_8f72b1 | jq '.eval_suite_sha256'
# Verschillend? Je eval is veranderd. Audit wat is toegevoegd.De oplossing. Ofwel draai de eval-suite-wijziging terug (als die onbedoeld was), ofwel breid de trainingsdekking uit om overeen te komen met de nieuwe eval (als de nieuwe slice een echte productiezorg is). Lever geen modelregressie-fix voor een eval-dekkingsprobleem — je maakt het model slechter op waar het daadwerkelijk goed in was.
Waar dit zich verbergt in onze pijplijn. Fase 1 — Register bindt de eval-suite-SHA in het release-manifest. De bovenstaande diagnose is gewoon het diffen van twee manifesten. De reden dat de bug het medische-Q&A-team twee dagen kostte, is dat ze geen manifest-niveau diff hadden — ze vergeleken model-checkpoints, niet release-manifesten.
Stap 2 — Is de judge gekalibreerd tegen mensen op deze slice?
Het symptoom. Een slice die nieuw is in de eval-suite scoort slecht, maar menselijke beoordeling van de outputs van het model op die slice beoordeelt ze als prima. De judge denkt dat het model faalt; mensen niet.
De diagnose. Bereken Spearman ρ tussen de beoordelingen van de LLM-judge en een kleine menselijk beoordeelde steekproef (50 items) op de falende slice. Als ρ < 0.4, meet de judge niet wat mensen meten op deze slice.
curl -X POST https://api.divinci.ai/v1/judges/<judge_id>/calibrate \
-d '{ "slice": "pediatric-oncology-dosing", "human_ratings_csv": "..." }'
# → { "spearman_rho": 0.31, "interpretation": "judge_uncalibrated_for_slice" }De oplossing. Ofwel kies een ander judge-model voor deze slice, ofwel gebruik een chain-of-judges met een arbiter. MT-Bench[1] laat zien dat GPT-4-as-judge gemiddeld in >80% van de gevallen overeenstemt met mensen, maar met per-categorie variantie van 86% (coderen) tot 36–44% (schrijven/menswetenschappen). De variantie is het werkzame getal; “gemiddeld goed” verbergt slices waar de judge ernaast zit.
Waar dit zich verbergt in onze pijplijn. Fase 2 — Gate eist per slice een gekalibreerde judge. De post Calibrating the AI Judge documenteert de procedure. Als de slice aan de eval is toegevoegd zonder een kalibratiestap, heb je een structureel onbetrouwbare gate.
Stap 3 — Komt de prompt-template-SHA overeen met productie?
Het symptoom. Kwaliteit daalt, maar de model_ref en dataset_ref zijn ongewijzigd. Niets aan de training is veranderd. Het model is hetzelfde model. En toch.
De diagnose. Vergelijk de prompt_template_ref-SHA in het falende release-manifest met die van de vorige release. Een bewerking van 38 tekens aan een system prompt die “beknoptheid verbetert” kan downstream-gedrag meer veranderen dan een volledige hertraining.
curl https://api.divinci.ai/v1/releases/rel_a01c66 | jq '.prompt_template_ref'
curl https://api.divinci.ai/v1/releases/rel_8f72b1 | jq '.prompt_template_ref'
# Verschillend? Trek de diff. Bekijk hem zorgvuldig.De oplossing. Behandel prompts als code. De 10 release failures-post behandelt de dashboard-edit-faalmodus — Tianpan’s Semver Lie-postmortem[2] noemt dit als het dominante faalpatroon van 2026. Als je kunt bewijzen dat de prompt veranderde, heb je je bug gevonden.
Stap 4 — Komt de preprocessing-pijplijn overeen met productie?
Het symptoom. Model slaagt lokaal voor de eval. Hetzelfde model faalt voor dezelfde eval in productie. Zelfde model_ref, zelfde prompt, zelfde dataset.
De diagnose. Trek de preprocessing_ref-SHA uit het productie-manifest en verifieer dat de eval is uitgevoerd met dezelfde. Het klassieke geval: training normaliseert witruimte en zet om naar kleine letters; productie niet. De eval liep door de productie-preprocessing; alles checkte. Totdat iemand preprocessing aan slechts één kant updatete.
curl https://api.divinci.ai/v1/releases/rel_a01c66 | jq '.preprocessing_ref'
# Vergelijk met de preprocessing die je trainings/eval-harness daadwerkelijk gebruikte.De oplossing. Containeriseer preprocessing als een geversioneerd artefact. Refereer ernaar vanuit het manifest. Weiger te deployen als de preprocessing-SHA van de gate verschilt van die van productie.
Stap 5 — Komt de dataset-SHA overeen met productie?
Het symptoom. Gate-eval-scores van de falende release verschillen van gate-eval-scores van hetzelfde model de dag ervoor.
De diagnose. Diff het dataset_version-veld tussen de twee releases. De eval-suite hield dezelfde naam, maar de dataset-inhoud werd bijgewerkt en opnieuw getagd. Zelfde naam, andere SHA, andere scores.
diff <(curl .../rel_a01c66 | jq '.dataset_version') \
<(curl .../rel_8f72b1 | jq '.dataset_version')De oplossing. Content-hash je datasets. De datasetnaam is geen versie; de SHA is dat.
Stap 6 — Komt de retrieval-index-SHA overeen met productie?
Het symptoom. Alleen voor RAG-workloads. Kwaliteit daalt op vragen die afhankelijk zijn van opgehaalde context. Vragen die direct beantwoord worden, zijn ongewijzigd.
De diagnose. Trek de retrieval_index_ref-SHA uit het manifest. Vergelijk met de retrieval-index van de gate-evaluatie. De RAG-index werd ’s nachts bijgewerkt (een verse ingestion-run); de gate-evaluatie cachte een oudere retrieval; de productie-canary gebruikte de nieuwe.
curl https://api.divinci.ai/v1/releases/rel_a01c66 | jq '.retrieval_index_ref'De oplossing. Bind de retrieval-index-SHA in het manifest, precies zoals we preprocessing binden. De geautomatiseerde index-rotatiecadans van AutoRAG maakt dit extra de moeite waard om te controleren — de index zal zich op je bijwerken, of je dat nu hebt geautoriseerd of niet, als je hem niet pinnt.
Stap 7 — Eindelijk het model zelf
Zes stappen verder. De eval dekt de slice. De judge is gekalibreerd. De prompt-SHA komt overeen. De preprocessing komt overeen. De dataset komt overeen. De retrieval-index komt overeen.
Nu — en alleen nu — heb je het recht verdiend om naar het model te kijken.
De diagnose voor deze stap is een per-slice Spearman-vergelijking tegen de vorige release, waarbij beide releases worden geëvalueerd tegen dezelfde manifest-vastgepinde dataset, preprocessing en retrieval. Het getal dat je produceert is een schoon signaal: een echte per-slice regressie, zonder upstream verstorende factoren.
curl -X POST https://api.divinci.ai/v1/releases/<failing_id>/diff-eval \
-d '{ "baseline_release_id": "<prior_id>", "slices": ["legal-IP-licensing"] }'
# → { "spearman_rho_failing": 0.41, "spearman_rho_baseline": 0.68, "delta": -0.27 }Als de delta een echte regressie bevestigt: auto-rollback gaat af (als je hem niet al handmatig hebt aangeroepen), en het falende model wordt hertraind tegen een uitgebreid slice-dekkingscorpus. Als de gate die deze release promoveerde de slice in de eerste plaats miste, is de gate ook de bug — capability 4 ontbreekt in je release-pijplijn.
Hoe de verdeling er werkelijk uitziet
De “1 op 7”-framing van eerder was geen retorisch middel. Het is ongeveer de verdeling die we zien over klant-uitrolprojecten. Van elke zeven QA-alerts:
De twee grootste slices zijn eval-dekkingslacune en judge-miskalibratie. Samen zijn ze verantwoordelijk voor de helft van de QA-alerts. Geen van beide is een modelprobleem. Het zijn beide problemen met hoe je het model meet.
Wat dit niet oplost
Drie eerlijke beperkingen:
De verdeling is van ons, niet van jou. De bovenstaande percentages komen uit ons klantencohort en de tooling van onze pijplijn. Als je een ander soort workload uitvoert — zwaar multi-modaal, zwaar agent-georkestreerd, zwaar single-shot generatief — zal je verdeling er anders uitzien. De diagnostische volgorde zou nog steeds moeten standhouden; de getallen achter elke stap niet.
De “eval-dekkingslacune” van stap 1 is het moeilijkst op te lossen. Het toevoegen van de ontbrekende slice aan je trainingscorpus, het bouwen van een gekalibreerde judge ervoor, en het opnieuw uitvoeren van de canary is op zichzelf een project van meerdere weken. De diagnose is snel; de remediatie niet.
Een echte regressie kan op een niet-model-bug rijden. De gevallen waarin je zowel een prompt-drift ALS een echte modelregressie hebt, zijn de ergste, omdat stap 3 de prompt-drift vindt, je hem repareert, en het alert opnieuw afgaat. De diagnostische volgorde in deze post handelt ze af, maar voegt verstreken tijd toe. Er is geen shortcut voor “de bug zat op twee plaatsen tegelijk.”
FAQ
Waarom produceert mijn LLM verschillende outputs voor vergelijkbare prompts?
Prompt-gevoeligheid is echt, maar het is niet altijd de oorzaak van een QA-alert — soms is het een symptoom van een upstream-bug. Loop de diagnose. Als de prompt-template-SHA overeenkomt en de preprocessing overeenkomt en de dataset overeenkomt, dan ja — het model heeft brede variantie op deze slice en je hebt een meer deterministisch decodeerpad of een andere judge nodig. Als er iets upstream is veranderd, repareer dat eerst.
Hoe vaak moet je je LLM-benchmarks opnieuw evalueren?
Her-evalueer de benchmark-inhoud elke keer dat de vorm van het verkeer van een productie-slice betekenisvol verandert. Her-evalueer de judge-kalibratie van de benchmark minstens elk kwartaal — judge-modellen driften sneller dan je zou denken. De grootste bron van valse QA-alerts is een benchmark die voor het laatst 18 maanden geleden is gevalideerd en nu iets meet wat je productie niet meer doet.
Wat veroorzaakt hallucinaties in custom language models?
Hallucinaties hebben meerdere upstream-oorzaken — retrieval-storingen (stap 6 in de boom hierboven), trainingsdekkingslacunes (stap 1, indirect), en decodeerpad-problemen (een echte modelzorg in stap 7). AutoRAG adresseert de retrieval-zijde-oorzaken door de retrieval-index in het release-manifest te binden en bij elke release opnieuw vast te pinnen. De andere twee vereisen pijplijnbrede fixes upstream van het model.
Hoe weet je of je trainingsdata het probleem is?
Als de dataset-SHA in de falende release overeenkomt met de dataset-SHA in de vorige goede release (stap 5 van de boom), is de data niet de directe oorzaak. Als ze verschillen, heb je hem gevonden. De moeilijkere vraag — “is de dataset volledig voor onze productie-slice-dekking?” — is wat stap 1 test. Een dataset die volledig is voor de eval, maar onvolledig voor productieverkeer, is een slice-dekkingsprobleem.
Kun je QA-storingen oplossen zonder het hele model te hertrainen?
Ja — zes op de zeven keer is de oplossing geen hertraining. Stappen 1–6 in de boom hebben fixes die het model niet raken: werk de eval bij, herkalibreer de judge, registreer de prompt-SHA opnieuw, repareer preprocessing, pin de dataset opnieuw vast, of pin de retrieval-index opnieuw vast. Hertraining is stap 7, de duurste fix, gereserveerd voor echte modelregressies. Het audit trail van de release-pijplijn laat je deze upstream-fixes doen met dezelfde provenance-discipline die je zou gebruiken voor een modelwijziging.
References
- LLM-as-judge per-category variance. Zheng et al., Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (NeurIPS 2023). >80% overall GPT-4-vs-human agreement with per-category variance from coding (86%) down to writing (36–44%). Anchor for step 2 — why judge calibration has to be measured per slice rather than assumed from a published headline number.
- The Semver Lie. Tianpan — The Semver Lie: how an LLM minor update breaks production (April 2026). The dominant 2026 failure-mode writeup. Names dashboard-edit prompt drift as the most-cited cause of production LLM incidents. Anchor for step 3.
- NIST AI RMF — Measure function. NIST AI Risk Management Framework. The "Measure" function explicitly covers benchmark-validity and evaluation-coverage as part of governance, not as a separate engineering concern. Cited as the institutional anchor for treating eval design as the first diagnostic step.
- RAGAS — retrieval-augmented generation evaluation. Es et al., RAGAS: Automated Evaluation of Retrieval Augmented Generation (arXiv:2309.15217). The reference framework for RAG-side evaluation. Anchor for step 6 — separating retrieval failures from generation failures requires a RAG-aware eval discipline.
- Internal — root-cause distribution across customer rollouts. The percentages in the pie chart are our internal observation across Divinci customer rollouts, not from a controlled benchmark. Your distribution will vary by workload type, fine-tune cadence, and team discipline. The relative ordering (steps 1–2 dominating) is stable across the cohort we've measured; the exact percentages are not portable to your environment without your own data.
- The four-stage release pipeline. How to Build an LLM CI/CD Pipeline With Divinci AI. Each diagnostic step in this post corresponds to a manifest field bound at Stage 1 — Register. Without the manifest discipline upstream, the diagnostic loses its grip; you can't diff what you didn't bind.
Volgende in deze serie: Automated Regression Testing for Custom LLMs in 2026. Deze post gaat over diagnose nadat een QA-alert is afgegaan. De volgende gaat over de regressie-test-discipline die het alert in de eerste plaats heeft veroorzaakt — wat je in de eval moet stoppen, hoe je hem eerlijk houdt, en wat te doen wanneer de regressietest begint te botsen met je judge.
Ready to Build Your Custom AI Solution?
Discover how Divinci AI can help you implement RAG systems, automate quality assurance, and streamline your AI development process.
Get Started Today