aakit: Assumption-Aware Measurement Kit

Het instrument voert drie experimenten uit, elk met één specifieke maatstaf:

#VraagMaatstafTheorie is verworpen indien
1Hoe vaak zijn stille assumpties onjuist en bepalend?load-bearing-wrong rate95% CI bovengrens < 5%
2Is 'divergence-gated' vragen beter dan nooit of altijd vragen?succes × vragen/taakgating verslaat beide niet
3Is gerichte intrekking goedkoper dan opnieuw beginnen?tokens bij gelijk pass-rategericht is niet goedkoper en even goed

Voor zover bekend is experiment #1 nog niet gepubliceerd voor organische werklasten. De beschikbare cijfers komen voort uit bewust geïnduceerde ambiguïteit, wat het probleem slechts naar boven toe begrenst met een onbekende marge. Dit gat in de kennis is de reden waarom aakit bestaat.

Geen van de drie experimenten heeft tot nu toe een publiceerbaar getal opgeleverd. Er is één run uitgevoerd; deze was klein en leidde voornamelijk tot inzichten over het instrument zelf (zie 'Resultaten tot nu toe'). Deze kit is ontworpen om ook negatieve resultaten te kunnen geven; dat zou immers een nuttige uitkomst zijn. Zie hiervoor PROTOCOL.md.

Het onderliggende concept: Assumptie-bewuste Intelligentie

Het doel is een systeem dat weet wanneer het moet aannemen, wanneer het moet onthouden en wanneer het moet imagineren, en dat expliciet aangeeft welke actie er is ondernomen.

Een assumptie-bewuste agent genereert naast zijn werk een record met de volgende gegevens:

  • Statement: De aanname (bijv. "het input-CSV bestand heeft een header-rij").
  • Provenance: De herkomst (invented | fromcontext | fromevidence | from_convention).
  • Support: Het citaat, bestand of commando waarop de assumptie rust. Leeg indien geraden.
  • Justifies: Welke code wordt gerechtvaardigd (bijv. parser.py:L14-L38, tests/test_load.py).
  • Defeater: Het bewijs dat de assumptie kan ontkrachten (bijv. head -1 data.csv).
  • Entrenchment: In hoeverre moet er opnieuw worden gewerkt als dit onjuist is (waarde tussen 0 en 1).

Het systeem werkt event-driven: zodra er bewijs komt dat een record tegenspreekt, wordt de 'blast radius' berekend en alleen het relevante deel opnieuw gegenereerd. Bewijs kan een falende test zijn, een bestand waarvan de inhoud afwijkt, of een correctie van de gebruiker.

Bestaande theorie (Prior Art)

De theoretische basis is niet nieuw:

  • Value of information: Howard, 1966.
  • The optimal error-reject tradeoff: Chow, 1970.
  • Deciding how much to think: Russell & Wefald, 1991.
  • Belief dependency tracking: Doyle's TMS (1979) en de Kleer's ATMS (1986).
  • The formal licence to assume: Reiter, 1980.

Wat nieuw lijkt, is dat geen enkel commercieel AI-product dit implementeert. Er is geen tool gevonden die een machine-controleerbaar en automatisch herzienbaar register bijhoudt van wat er is aangenomen. De Spec Kit van GitHub komt het dichtst in de buurt met een verplichte sectie 'Assumptions', maar deze bestaan uit tekstuele bullets die nooit worden gecontroleerd.

Resultaten tot nu toe

Er is één volledige run uitgevoerd. Experiment 2 heeft een volledig vooraf geregistreerd resultaat. Experiment 1 heeft geen definitief getal en Experiment 3 is nog niet uitgevoerd.

Experiment 2: Vraag-beleid (120 trials)

Testopzet: 10 taken × 4 beleidsvormen × 3 herhalingen, met maximaal 3 vragen via claude-sonnet-4-5.

BeleidSucces95% CIVragen/taakTokens/trial
gated_multi19/30 (63.3%)[45.5, 78.1]1.904,181
always18/30 (60.0%)[42.3, 75.4]2.473,186
divergence_gated13/30 (43.3%)[27.4, 60.8]0.673,971
never10/30 (33.3%)[19.2, 51.2]0.001,606

Verdict: GEEN WINST. Conform de criteria in PROTOCOL.md is dit een fail. Er is geen significant verschil met het 'never'-beleid; alle intervallen overlappen met die van never [19.2, 51.2].

De belangrijkste bevinding is dat de 'gate' (de filter om te bepalen of er gevraagd moet worden) duurder is dan de vragen die het bespaart:

  • always vraagt 2.47 vragen per taak en kost 3,186 tokens.
  • divergence_gated vraagt slechts 0.67 vragen (3.7x minder), maar kost 3,971 tokens (25% meer).

Het uitvoeren van de divergentie-check (het genereren van twee interpretaties en deze vergelijken) is duurder dan simpelweg vragen stellen.

Experiment 1: Basispercentage

Een eerdere poging produceerde 0 assumpties over 2 taken, wat onvoldoende is voor een basispercentage. De LLM-extractor vond niets waar de heuristische backend 44 vond, wat aantoont dat de anti-inflatiemaatregelen werken. Voor een valide resultaat zijn minimaal 25 geadjudiceerde taken nodig.

Experiment 3: Niet uitgevoerd

De 'defeater loop' is nog niet op echte data getest. De code is aanwezig en doorstaan de smoke tests, maar er zijn geen gevalideerde claims over precisie of kostenbesparing.

Gevonden bugs tijdens instrumentatie

Tijdens het gebruik zijn drie bugs ontdekt:

  1. Truncatie van tool-resultaten: Een limiet van 1.800 tekens sneed het einde van bestanden af, waardoor bewijslast verdween en assumpties onterecht als 'invented' werden gemarkeerd. Dit is verhoogd naar 4.000 tekens (head+tail).
  2. Zelf-consumptie: De kit nam zijn eigen LLM-aanroepen op als taken. Dit werd gecorrigeerd door een sentinel in de prompt te gebruiken.
  3. Sessie-id exclusie: Bij het gebruik van de CLI backend kon claude -p de sessie-id van de parent erven, waardoor filtering onbetrouwbaar was.

Installatie en Gebruik

Vereisten: Python 3.10+, alleen standaardbibliotheken (stdlib).

git clone https://github.com/abhixhek/aakit && cd aakit
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
aakit init                  # maakt ~/.aakit aan
aakit status

Optionele extra's:

  • pip install -e ".[api]": Voor de Anthropic SDK (AAKIT_BACKEND=api).
  • pip install -e ".[duck]": Voor DuckDB (aakit export naar parquet).

Backends (AAKIT_BACKEND)

  • cli (standaard): Gebruikt Claude op je PATH via bestaande authenticatie. Langzaamst.
  • api: Vereist ANTHROPICAPIKEY. Snelst voor batch-runs.
  • heuristic: Geen model nodig. Draait volledig offline voor debuggen van de pijplijn; output is bewust matig.

Gedetailleerde Experimenten

Experiment 1: Het basispercentage

Workflow: ingestextractcalibratereviewmetricsreport.

  • Calibratie: Cruciaal om bias te voorkomen. Als de extractor geprimed is om assumpties te vinden, zal hij ze ook vinden waar ze niet zijn. Calibratie waarschuwt bij een verdachte distributie (bijv. minder dan 15% taken zonder assumpties).
  • Menselijke adjudicatie: Om model-artefacten te voorkomen, worden alleen door mensen beoordeelde resultaten (adjudicated_by='human') meegenomen in de hoofdstatistieken.

Experiment 2: De vraag-budget curve

Vier beleidsvormen op ondergespecificeerde taken:

  • never: Direct antwoorden, de rest aannemen.
  • always: Eerst vragen tot aan --max-questions.
  • divergence_gated: Exact één vraag stellen, en alleen als twee verschillende interpretaties van het verzoek leiden tot wezenlijk andere resultaten (ClarifyDelphi criterium).
  • gated_multi: Zelfde gate als hierboven, maar met hetzelfde budget als always.

Experiment 3: De defeater loop

Een monitor die binnenkomend bewijs observeert en bepaalt welke assumpties worden vernietigd.

Workflow:

  1. Bewijs registreren via aakit observe (bijv. een pytest run of handmatige tekst).
  2. Bepalen welke assumpties worden gedefeated via aakit defeats.
  3. Gerichte reparatie uitvoeren met aakit repair en vergelijken met een volledige rerun in tijdelijke repository-kopieën.

Projectstructuur

  • schema.py: Records en vocabulaire (gebaseerd op Reiter/Doyle/de Kleer).
  • config.py: Paden, backend selectie en redactiepatronen.
  • llm.py: Backends voor CLI, API en heuristiek.
  • store.py: SQLite opslag.
  • transcripts.py: Conversie van Claude Code JSONL naar taken.
  • extract.py: De extractor prompt met anti-inflatiemaatregelen.
  • review.py: Menselijke adjudicatie loop.
  • defeater.py: ATMS-lite voor detectie en reparatie.
  • askpolicy.py: Runner voor Experiment 2 inclusief oracle en blinde grader.
  • metrics.py: Wilson-intervallen en kill-criteria.
  • report.py: HTML rapportage.
  • cli.py: Entry point.

Privacy

Alle data blijft lokaal in SQLite (~/.aakit). Alleen de data die naar het gekozen model-backend wordt gestuurd, verlaat de machine. De config.redact_patterns verwijdert API-keys en persoonlijke gegevens uit traces voordat extractie plaatsvindt.