We bouwen al maanden agents, maar we meten ze niet streng. Dit plan zet één open testbank (Inspect) en één transcript-microscoop (Docent) in ons lab, met echte codevoorbeelden en een gefaseerde uitrol. We have been building agents for months but we do not measure them rigorously. This plan brings one open test harness (Inspect) and one transcript microscope (Docent) into the lab, with real code examples and a phased rollout.
Eerste suite: 8 code-taken. Alle vijf agents haalden 1.000. Mooi, maar nutteloos: een meetlat die iedereen even hoog geeft, méét niets. Dit is de sleutel-inzicht van de hele methode: een benchmark is pas een benchmark als hij de kandidaten uit elkaar trekt. First suite: 8 code tasks. All five agents scored 1.000. Nice, but useless: a yardstick that gives everyone the same height measures nothing. This is the key insight of the whole method: a benchmark only becomes a benchmark when it pulls the candidates apart.
Ik schreef 6 randgeval-zware taken (wildcard-match, min-window, expressie-parser, geldige-haakjes, getal-naar-woorden, kolomtitel) en verifieerde eerst de asserts met eigen referentie-oplossingen (anders straf je goede code met een foute test). Zelfde harde scorer: de gegenereerde code wordt echt uitgevoerd tegen verborgen asserts. Toen trok de meetlat wél uit elkaar: I wrote 6 edge-case-heavy tasks (wildcard match, min window, expression parser, valid parentheses, integer-to-words, column title) and first verified the asserts against my own reference solutions (else you penalise good code with a broken test). Same hard scorer: the generated code is actually executed against hidden asserts. Now the yardstick did separate:
| agent | route / kostenroute / cost | makkelijk (8)easy (8) | zwaar (6)hard (6) | time-horizon |
|---|---|---|---|---|
| opus-4.8 | claude -p · €0 | 1.000 | 1.000 | insensitive* |
| gpt-5.5 | OpenAI · metered | 1.000 | 1.000 | insensitive* |
| gemini-3.1-pro | Google · metered | 1.000 | 1.000 | insensitive* |
| glm-5.2 | OpenRouter · cents | 1.000 | 1.000 | insensitive* |
| qwen-local | Thor · €0 | 1.000 | 0.667 | ~23 min |
* De vier frontier-agents halen nog steeds alles: hun horizon is op déze suite "insensitive" (geen spreiding), en dat is een eerlijk, niet-verzonnen resultaat. Het zegt: om die vier te rangschikken moeten de taken nóg zwaarder. De lokale Qwen-coder zakt naar 0.667: hij haalt patroon-, DP- en formatteer-taken maar valt op de twee stateful-algoritmes (min_window en calc). Zijn 50%-tijdshorizon is een echte fit: ~23 minuten mensenwerk.
* The four frontier agents still pass everything: their horizon on this suite is "insensitive" (no spread), an honest, non-fabricated result. It says: to rank those four, the tasks must get harder still. The local Qwen-coder drops to 0.667: it handles pattern, DP and formatting tasks but trips on the two stateful algorithms (min_window and calc). Its 50% time-horizon is a real fit: ~23 minutes of human work.
Dit is de kern: de meetlat zelf wordt geïtereerd tot hij scheidt. Verzadiging is geen succes, het is een signaal om te verzwaren. This is the core: the yardstick itself is iterated until it separates. Saturation is not success, it is a signal to harden.
claude -p (Max-plan) aanroept, niet de gemeterde console-API. SOTA in de meting, €0 marginaal.
Opus runs through a custom Inspect provider that calls our flat claude -p (Max plan), not the metered console API. SOTA in the measurement, €0 marginal.
Zonder deze truc zou onze primaire denker (Opus) buiten het leaderboard vallen, want Inspect's standaard Anthropic-pad tikt de gemeterde console-rekening aan, precies wat we vermijden. De provider (providers/claudep.py, 30 regels) haalt Opus binnen tegen €0. Dat is het verschil tussen "we meten de goedkope modellen" en "we meten álles, ook onze beste".
Without this trick our primary thinker (Opus) would fall outside the leaderboard, because Inspect's default Anthropic path hits the metered console bill, exactly what we avoid. The provider (providers/claudep.py, 30 lines) brings Opus in at €0. That is the difference between "we measure the cheap models" and "we measure everything, including our best".
De macro-scorer draait een gegenereerde macro echt headless en scoort op "draaide clean". Bij de eerste test vroeg STAR om een ccmpsuite-licentie die we niet hebben, en de .bat gaf tóch exit 0, dus een naïeve scorer had "OK" geloofd. Diagnose: het -power-vlag ontbrak (we hebben één ccmppowerplus-seat). Fix + succes gelezen uit de echte stdout-markers → scorer geeft nu correct True op een goede macro, False op een kapotte. Geen verzonnen getal, een gevangen gotcha.
The macro scorer runs a generated macro for real headless and scores on "ran clean". On the first test STAR asked for a ccmpsuite licence we do not have, and the .bat still returned exit 0, so a naive scorer would have believed "OK". Diagnosis: the -power flag was missing (we hold one ccmppowerplus seat). Fix + success read from the real stdout markers → the scorer now correctly returns True on a good macro, False on a broken one. No fabricated number, a caught gotcha.
Dit is het foundationele deel. Niet "we gebruikten Inspect", maar de manier van werken die je op elke agent, elk domein, kunt herhalen. This is the foundational part. Not "we used Inspect", but the way of working you can repeat on any agent, any domain.
claude -p. Anders meet je alleen de goedkope modellen en mist je je eigen referentie.Custom provider for Opus via flat claude -p. Otherwise you only measure the cheap models and miss your own reference.Dit recept geldt niet alleen voor code. Dezelfde zeven stappen meten straks CFD-macro-schrijvers, research-samenvatters, de zelf-evoluerende lus, elke plek waar we een goedkoop model een dure werkelijkheid laten nadoen. De vraag is telkens identiek: hoeveel bits verspillen we nog, en meten we het op de echte verdeling? Zodra jij dit goed snapt, bouwen we het dieper: grotere en zwaardere suites, domein-suites, en Docent als microscoop op de transcripten. This recipe is not just for code. The same seven steps will soon measure CFD macro writers, research summarisers, the self-evolving loop, every place we have a cheap model mimic an expensive reality. The question is always the same: how many bits are we still wasting, and are we measuring it on the real distribution? Once you grok this, we build it deeper: bigger and harder suites, domain suites, and Docent as a microscope on the transcripts.
Onze Heilige Regel zegt: de slimme modellen beslissen, de goedkope genereren, en generator ≠ verifier. Maar één schakel ontbreekt: bewijs. Toen de Qwen macro-writer van 8% naar 83% slaagkans ging, was dat een handmatige meting, één keer. We hebben geen herhaalbare meetlat die zegt of een modelwissel ons beter of stiekem slechter maakt. Our Sacred Rule says: the smart models decide, the cheap ones generate, and generator ≠ verifier. But one link is missing: evidence. When the Qwen macro-writer went from 8% to 83% pass rate, that was a manual, one-off measurement. We have no repeatable yardstick that tells us whether swapping a model makes us better or quietly worse.
Je kunt niet iteren tot het klopt als je niet meet of het klopt. You cannot iterate until it is right if you do not measure whether it is right.
Dit is precies het idee uit onze compressie-notitie, maar dan op onszelf toegepast: cross-entropy / perplexity is de afstand tussen wat een model zegt en de werkelijkheid. Een testbank meet diezelfde afstand op taakniveau. We hebben de theorie al; nu de meetopstelling. This is exactly the idea from our compression note, turned on ourselves: cross-entropy / perplexity is the distance between what a model says and reality. A test harness measures that same distance at the task level. We already have the theory; now the measurement rig.
| GereedschapTool | WatWhat | Verdict | Waarom voor onsWhy for us |
|---|---|---|---|
| Inspect UK AISI · MIT |
Open eval-framework, pip install inspect-aiOpen eval framework, pip install inspect-ai |
ADOPT | Pure Python, draait op Windows, stuurt lokale Qwen (vLLM) + Opus + Gemini + GPT door één interface met Docker-sandbox. Onze 8%→83% wordt een echte, herhaalbare score.Pure Python, runs on Windows, drives local Qwen (vLLM) + Opus + Gemini + GPT through one interface with Docker sandboxing. Our 8%→83% becomes a real, repeatable score. |
| Docent Transluce · Apache-2.0 |
Zelf-hostbare microscoop op agent-transcriptenSelf-hostable microscope on agent transcripts | TRIAL | Voor "ik heb duizenden runs, waar ging het mis". Achter de privacy-muur, of met de judge op lokale Qwen gericht.For "I have thousands of runs, where did it go wrong". Behind the privacy wall, or with its judge pointed at local Qwen. |
| Devin · Vivaria · Kiso · 0xPARC | cloud-agent · zwaar platform · consultancy · ZK-cryptocloud agent · heavy platform · consultancy · ZK crypto | SKIP | Cloud-only botst met de privacy-muur, of geen fit / geen product.Cloud-only breaks the privacy wall, or no fit / no product. |
Grappig detail: het bruikbaarste stuk stond niet eens op de sponsorlijst. METR (een sponsor) wijst zelf naar Inspect. We volgden het spoor tot het echte gereedschap. A funny detail: the most useful piece was not even on the sponsor list. METR (a sponsor) now points to Inspect itself. We followed the trail to the real tool.
Inspect zit náást onze orchestrator, niet erin. Opus blijft de baas die taken uitdeelt en oordeelt; Inspect is de onafhankelijke meetbank die elk model door dezelfde taken haalt. De scorer blijft een harde check (draait de STAR-macro headless, slaagt de test) en een eventuele LLM-judge draait op een ander merk dan het geteste model. Zo blijft generator ≠ verifier overeind. Inspect sits beside our orchestrator, not inside it. Opus stays the boss that hands out and judges tasks; Inspect is the independent bench that runs every model through the same tasks. The scorer stays a hard check (does the STAR macro run headless, does the test pass) and any LLM judge runs on a different vendor than the model under test. That keeps generator ≠ verifier intact.
De agent schrijft een macro; de scorer draait 'm headless op deze host en checkt of het echt werkt. Geen mening, een feit.The agent writes a macro; the scorer runs it headless on this host and checks it actually works. Not an opinion, a fact.
# pip install inspect-ai (Windows, Python 3.12 — draait lokaal) from inspect_ai import Task, task from inspect_ai.dataset import json_dataset from inspect_ai.solver import system_message, generate from inspect_ai.scorer import scorer, Score, Target, accuracy, CORRECT, INCORRECT import subprocess, re, pathlib def run_macro_headless(java: str) -> bool: # schrijf .java, draai STAR-CCM+ 21.02 -batch, check exit + verwacht resultaat p = pathlib.Path("_eval/gen.java"); p.write_text(java, encoding="utf-8") r = subprocess.run(["starccm+", "-batch", str(p), "-np", "4"], capture_output=True, text=True, timeout=1800) return r.returncode == 0 and "Command finished" in r.stdout @scorer(metrics=[accuracy()]) def macro_runs(): async def score(state, target: Target) -> Score: java = re.search(r"```java(.*?)```", state.output.completion, re.S) ok = run_macro_headless(java.group(1)) if java else False return Score(value=CORRECT if ok else INCORRECT) return score @task def starccm_macros(): return Task( dataset=json_dataset("starccm_tasks.jsonl"), # onze eigen taakset solver=[system_message("Je schrijft STAR-CCM+ 21.02 Java-macros. Gebruik de geverifieerde API."), generate()], scorer=macro_runs(), )
from inspect_ai import eval eval("tasks/starccm_macros.py", model=[ "openai/qwen-coder-awq", # lokale Qwen op Thor (OpenAI-compat, base_url=THOR-LAN:8000) "anthropic/claude-opus-4-8", "google/gemini-3.1-pro-preview", "openai/gpt-5.5", ]) # → inspect view opent een web-UI met de score per model, per taak, klikbaar.
Meet één keer hoe lang een mens over elke taak doet. Fit dan slaagkans vs log(mensentijd). Het punt waar de curve 50% kruist = de "tijdshorizon" van de agent. Eén getal, herhaalbaar bij elke modelwissel.Measure once how long a human takes per task. Then fit success-rate vs log(human-time). The point where the curve crosses 50% = the agent's "time horizon". One number, repeatable on every model swap.
import numpy as np from scipy.optimize import curve_fit def logistic(log_t, k, t50): return 1 / (1 + np.exp(k*(log_t - t50))) # human_minutes + pass(0/1) per taak, uit de Inspect-run popt, _ = curve_fit(logistic, np.log(human_minutes), passed, p0=[1.0, 2.0]) horizon_min = np.exp(popt[1]) print(f"50%-tijdshorizon: {horizon_min:.0f} min mensen-werk")
Voed onze multi-agent transcripten in Docent, schrijf een "rubric" in gewone taal, en krijg een gekwantificeerd percentage + klikbare voorbeelden. Direct bewijs voor de Sacred Rule.Feed our multi-agent transcripts into Docent, write a plain-language "rubric", and get a quantified rate + clickable examples. Direct evidence for the Sacred Rule.
# zelf-gehost (docker-compose + Postgres), judge → lokale Qwen rubric: "Markeer elke run waarin de generator stil naar een zwakker model downgradede, of de verifier een geplante bug miste." # → Docent scoort alle runs, geeft % + de exacte stappen waar het misging.
pip install inspect-ai, lokale Qwen als OpenAI-compat provider (Thor :8000), één speeltaak groen krijgen.pip install inspect-ai, wire local Qwen as an OpenAI-compat provider (Thor :8000), get one toy task green.
Nieuw Opus, nieuwe Qwen, nieuwe GLM: draai de suite, vergelijk het getal. Stille achteruitgang (waar we nu blind voor zijn) wordt een rode cel.New Opus, new Qwen, new GLM: run the suite, compare the number. Silent regressions (which we are blind to today) become a red cell.
"Welk model voor STAR-macro's" wordt beantwoord door de score op echte STAR-macro's, niet door een onderbuikgevoel of een marketingclaim."Which model for STAR macros" gets answered by the score on real STAR macros, not a gut feeling or a marketing claim.
Docent kwantificeert precies hoe vaak een dom model een slim besluit voedde, of een verifier een bug miste. De regel wordt meetbaar in plaats van een principe.Docent quantifies exactly how often a dumb model fed a smart decision, or a verifier missed a bug. The rule becomes measurable instead of a principle.
De compressie-notitie zei: intelligentie = de KL-kloof verkleinen. Een Inspect-scorer die perplexity of taak-slaagkans meet, is letterlijk die kloof, op onze eigen taken. Theorie en meetbank sluiten op elkaar aan.The compression note said: intelligence = shrinking the KL gap. An Inspect scorer measuring perplexity or task pass-rate is literally that gap, on our own tasks. Theory and bench line up.
We stoppen met raden of we beter worden, en gaan het meten. Dat is de Iterate-Until-Right-lus met eindelijk een echte meter. We stop guessing whether we are improving and start measuring it. That is the Iterate-Until-Right loop with, at last, a real gauge.
Zeg het woord en ik zet Fase 0+1 op: Inspect geïnstalleerd, lokale Qwen als provider, en de eerste STAR-macro-scorer groen op een handvol echte taken. Dan heb je binnen een dag het eerste mini-leaderboard om naar te kijken. Say the word and I stand up Phase 0+1: Inspect installed, local Qwen as a provider, and the first STAR-macro scorer green on a handful of real tasks. You would have a first mini-leaderboard to look at within a day.