ISMS Copilot
Engineering

De symmetrietest: een promptfix implementeren die je niet kunt reproduceren

Als een productiefout niet offline te reproduceren is, kun je een promptfix niet valideren door te controleren of deze werkt. Je valideert het door te controleren of je wijziging de uitvoer in een consistente richting verplaatst, of alleen maar bijdraagt aan de natuurlijke variatie van het model. Hier is de test die we uitvoerden op 126 blinde A/B-paren.

door ISMS Copilot··10 min read
De symmetrietest: een promptfix implementeren die je niet kunt reproduceren

Je kunt niet altijd bewijzen dat een promptfix werkt. Sommige productiefouten treden alleen op met de volledige context die ze veroorzaakt, en geen offline testopstelling kan ze reproduceren. Als dat het geval is, is de eerlijke vraag niet "werkt de fix?", maar "is mijn wijziging te onderscheiden van de natuurlijke variatie tussen runs van het model?" Als het antwoord nee is, is de wijziging veilig genoeg om te implementeren, ook al heb je het probleem nooit zien oplossen. Wij noemen deze controle de symmetrietest, en het is hoe een promptwijziging die we nooit konden laten mislukken onze poort passeerde.

Hieronder staat alles uit één interne evaluatie, gedateerd 2026-07-09, uitgevoerd op GLM-5.2, het model dat we gebruiken voor chat: een blinde A/B-regressietest over ons hele chatoppervlak. De metrics zijn van ons, gemeten op onze eigen testopstellingen, op die datum.

De bug die zich niet liet reproduceren

In één week zagen we twee defecten bij documentgeneratie in Duitse beleidsoutput. Bij de eerste gaf de assistent een beleidsdocument terug waarvan de hoofdsecties genummerd waren van 2 tot en met 6, zonder sectie 1. Bij de tweede ontbrak een bijgevoegd document in de context, en in plaats van dat toe te geven, fabriceerde de assistent een vervormde "herziene versie" die de lezer aanzag voor een enorme truncatie, zonder te vermelden dat het document niet daadwerkelijk was gelezen.

We schreven voor elk een promptregel: een nummeringsinvariant (hoofdsecties beginnen bij 1 en zijn aaneengesloten) en een anti-fabricatiergel (als het bijgevoegde document ontbreekt, vraag erom, fabriceer het niet). Vervolgens probeerden we de oorspronkelijke fouten te reproduceren met de oude prompt, zodat we konden zien hoe de nieuwe regels ze oplosten.

De nummeringsfout liet zich niet reproduceren. Bij meer dan twintig generaties met de oude prompt, inclusief de productieberichtenvorm die de melding triggerde, begon GLM-5.2 elke keer bij 1. De fout verscheen niet zonder de volledige context die de live sessie droeg: opgebouwde gebruikersherinneringen, een lange meervoudige conversatie en redeneringsmodus aan. Onze interpretatie is dat één of meer van deze factoren nodig is om de fout te triggeren. De offline testopstelling met één beurt had deze context niet, en de bug was gewoon niet aanwezig.

Dit is de valkuil. We hadden een fix voor een bug die we niet konden oproepen. We konden niet aantonen dat de fix iets verbeterde, omdat er in de testopstelling niets kapot was om te verbeteren. Implementeren op basis van geloof is geen bewijs. Voor altijd blokkeren omdat je de fout niet kunt nabootsen, levert niets op. Beide opties zijn verkeerd.

Herformuleer: beperk de impact, achtervolg de fix niet

De regel staat in de systeemprompt op elke chatbeurt, dus de impact is niet beperkt tot "documentnummering". Het gaat om elk gedrag van de assistent: framework-Q&A, cross-framework mapping, juridische disclaimers, weigeringen, meertalige output, toon. Een promptwijziging gericht op één foutmodus kan stilletjes een ongerelateerde modus beschadigen. Dat is het risico dat het waard is om te meten, en in tegenstelling tot de oorspronkelijke bug, is het meetbaar offline.

Dus stopten we met proberen te bewijzen dat de fix werkte en begonnen we het risico te meten dat de wijziging met zich meebracht. Het ontwerp: een blinde A/B-regressietest over het hele chatoppervlak, waarbij de oude prompt wordt vergeleken met de nieuwe op identieke inputs.

  • 42 testopstellingen die compliance-Q&A, advies, framework-mapping, service-omleidingen, veiligheidsweigeringen, juridische disclaimers, meertalige Duitse en Franse outputs, toon, documentgeneratie en dynamische testopstellingen met de secties voor aangepaste instructies en vastgepinde bestanden bevatten die echte gebruikers hebben.
  • 252 generaties, vormend 126 oude-versus-nieuwe paren (drie samples per testopstelling), allemaal op GLM-5.2, 2026-07-09.
  • Blindering. Elk paar is geschreven als A/B met een willekeurig gegenereerd label. Een manifest bevat de echte oude/nieuwe mapping en wordt nooit getoond aan de beoordelaars.
  • Twee beoordelingslagen. Een deterministische laag controleert must en must-not voorwaarden op de afgebakende testopstellingen (helpcenter-omleidingen werken, juridische disclaimers worden getoond, prompt-extractiepogingen worden geweigerd, umlauts blijven behouden, minimale lengtes worden gehandhaafd). Een blinde kwalitatieve laag laat beoordelaars elk paar lezen zonder te weten welke arm welke is of wat er is gewijzigd, en beoordeelt gelijkwaardig, A-beter of B-beter met een materialiteitslabel.

De deterministische laag kwam schoon terug: nul falende reacties op beide armen, nul asymmetrische fouten. Niets wat de regel moest beschermen, brak aan beide kanten.

De kwalitatieve laag is waar de interessante beweging zit.

De symmetrietest

De blinde beoordelaars beoordeelden 118 van de 126 paren als gelijkwaardig. Van de overige acht hadden er zeven een materieel verschil en één een klein, niet-materieel verschil. Op een naïeve lezing zijn zeven divergenties in een veiligheidsevaluatie een mislukking.

Het is de verkeerde lezing, en de reden is richting. Een materieel verschil heeft een teken: of de nieuwe arm was slechter of de oude arm was slechter. Als je promptwijziging regressies veroorzaakt, scheeftrekken de materiële verschillen naar één kant, richting nieuwe-arm-slechter. Als ze gewoon de natuurlijke variatie tussen runs van het model zijn en niets met je wijziging te maken hebben, landen ze ongeveer gelijkmatig op beide armen. Tel dus niet alleen de materiële verschillen. Ontblinde ze en tel de richting.

Dat hebben we gedaan. De zeven splitsten zich in drie nieuwe-arm-slechter, vier oude-arm-slechter. Drie tegen vier is zo dicht bij een gelijkmatige verdeling als zeven maar kan zijn, het patroon dat je zou verwachten van natuurlijke variatie tussen runs in plaats van een gerichte regressie. Geen van de zeven had een plausibele connectie met een documentnummeringsregel:

Materieel verschilSlechtere armWat we observeerden
ISO 27001-clausale identiteitnieuweA.8.2 gelezen als een risicobeoordelingscontrole (correct in de andere twee samples van deze testopstelling)
PCI DSS-segmentatienieuwesegmentatie overdreven als strikt vereist
PCI DSS-segmentatieoudeeen gefabriceerde "Appendix A1-segmentatievereiste"
Duits document (CJK-lek)oudeeen vreemde Chinese token in Duitse sluittekst
Duits document (CJK-lek)oudeChinese karakters in een Duitse samenvattingssectie
Concision-instructienieuwebrak een "extreem beknopte" aangepaste instructie
Concision-instructieoudebrak een "extreem beknopte" aangepaste instructie

Het meest opvallende, ons enige hardnekkige voorbeeld, zijn de CJK-lekken: in twee van onze Duitse testopstellingen bevatte de output een vreemde Chinese token (in één geval de karakters voor "informatiebeveiliging") in een verder Duits document. Dat token-lekgedrag is op beide armen opgedoken in onze Duitse runs. Hier landden beide gevallen op de oude arm. Als de nieuwe regel Duitse output zou degraderen, zou je verwachten dat ze op de nieuwe arm zouden verschijnen; dat was niet het geval.

De gevallen met regelgevende precisie wijzen dezelfde kant op. In ISO/IEC 27001:2022 (gepubliceerd 25 oktober 2022), Annex A-controle 8.2 is "Geprefereerde toegangsmogelijkheden"; één sample van de nieuwe arm las het als een risicobeoordelingscontrole, en kreeg het in de andere twee samples van die testopstelling wel goed. Onder PCI DSS v4.0 (PCI Security Standards Council, maart 2022) is netwerksegmentatie geen algemene vereiste, het is een scope-reductietechniek die de Council beschrijft als een manier om systemen buiten de beoordelingsscope te plaatsen, geen verplichte controle; één sample van de nieuwe arm overdreef het als vereist, en één sample van de oude arm fabriceerde dat "Appendix A1" een segmentatievereiste is. Appendix A1 is eigenlijk de aanvullende vereisten voor multi-tenant serviceproviders. Dit zijn het soort feitelijke wankelingen die een probabilistisch model produceert op harde domeinvragen, en in deze run vielen ze over beide armen verspreid, niet geconcentreerd op de onze.

Ondertussen bleven de gedragingen die de wijziging daadwerkelijk moest aanpakken op beide armen gedurende de hele evaluatie intact: elk paar met een ontbrekend bijgevoegd document vroeg erom in plaats van het te fabriceren, en elk nummeringspaar produceerde een aaneengesloten structuur. Over de volledige evaluatie, de 126 blinde paren plus de deterministische scans over hetzelfde oppervlak, vonden we geen enkel falen dat toe te schrijven was aan de wijziging.

Wat dit wel en niet bewijst

Wees precies over de claim, want het is gemakkelijk om te overspelen. De evaluatie toont geen gerichte regressie bij deze steekproefgrootte aan, niet dat de fix werkt. We hebben nooit aangetoond dat de nummeringsregel de nummeringsbug oploste, omdat de bug productiecontext nodig heeft die we niet konden nabootsen. De regel wordt geïmplementeerd op twee pijlers: de productieforensiek die de fout zichtbaar maakt, en een niet-regressiesignaal dat toont dat de wijziging niets anders verstoort. Dat is een zwakkere claim dan "we hebben de bug gereproduceerd en zagen de fix hem doden", en het is de sterkste claim die de situatie toelaat.

De beperkingen zijn reëel en het is de moeite waard om ze één keer duidelijk te benoemen. Een grove gerichte scheefgroei zou zichtbaar zijn bij drie samples per testopstelling; een subtiele zou dat niet zijn, omdat een 55/45-verdeling verborgen blijft bij deze steekproefgrootte, en drie samples verspreid over 42 testopstellingen zijn gecorreleerd, geen 126 onafhankelijke proeven. We hebben geen oude-versus-oude controlearm uitgevoerd, dus de drie-tegen-vier-split is onze beste schatting van de basisfout, geen gemeten baseline, en zonder een van tevoren vastgestelde equivalentiemarge is dit een signaal van geen gerichte regressie, geen formele niet-inferioriteitstest. De testopstellingen zijn enkelvoudig, dus een interactie tussen de nieuwe regel en een lange productieconversatie valt buiten scope, wat precies de context is die de oorspronkelijke bug nodig had. Een symmetrische verdeling is bewijs dat de wijziging de outputs niet één kant op duwde, geen bewijs dat deze inert is. Wat de test je geeft, is een concreet beeld van de impact wanneer de alternatief een onderbuikgevoel was.

De draagbare checklist

Als je een promptfix hebt voor een productiefout die je niet offline kunt reproduceren, implementeer deze dan niet op basis van geloof en blokkeer niet. Beperk de wijziging in plaats daarvan:

  • Scheid de twee vragen. "Werkt de fix?" heeft de fout nodig die je niet kunt nabootsen. "Is de wijziging veilig?" niet. Beantwoord de vraag die je wel kunt beantwoorden.
  • Bepaal de impact eerlijk. Een regel in een gedeelde systeemprompt raakt elk gedrag, niet alleen het doelgedrag. Bouw testopstellingen over het hele oppervlak, inclusief de varianten met aangepaste instructies en vastgepinde context die echte gebruikers meedragen.
  • Voer het blind en gepaard uit. Dezelfde inputs, oude versus nieuwe, willekeurig gegenereerde A/B-labels en een manifest dat de beoordelaars nooit te zien krijgen. Blindering is wat voorkomt dat je de arm kiest waarvan je hoopt dat hij wint.
  • Tel de richting, niet alleen het verschil. Ontblinde de materiële verschillen en controleer het teken. Asymmetrisch richting nieuwe-arm-slechter is een regressie. Een ongeveer gelijkmatige verdeling over beide armen is het patroon dat een wijziging op dit bewijsniveau doorlaat.
  • Voeg een herhaalcontrole toe als de marge klein is. Een oude-versus-oude-arm meet de basisfout van het model direct, dus je vergelijkt je wijziging met een getal in plaats van een aanname.
  • Handhaaf een deterministische vloer. Koppel de kwalitatieve beoordeling aan harde must en must-not-controles op het gedrag dat nooit mag falen, zodat een symmetrisch-ruisverdict geen echte gebroken invariant maskeert.
  • Formuleer de claim die je daadwerkelijk hebt verdiend. Zeg "geen meetbare regressie" in plaats van "de fix werkt", wanneer niet-regressie het enige is wat je hebt bewezen.

De instinctieve reactie als een bug zich niet laat reproduceren, is om door te gaan met proberen hem te nabootsen tot hij verschijnt. Soms lukt dat nooit, en dan besteed je energie aan de verkeerde vraag. Of de fix wordt geïmplementeerd, hangt af van of je wijziging luider is dan de natuurlijke variatie van het model. Meet dat direct, en een promptwijziging die je nooit hebt zien slagen, wordt er één waar je toch vertrouwen in kunt hebben dat hij veilig is.

Gerelateerde artikelen