🔬 De skill die een sterk model schaadde
deel 1 · part 1 🧩 idiomen in de skill fold idioms → measure deel 2 · part 2 🪤 de val: train-on-test the skill had the answers deel 3 · part 3 📉 de schone meting clean test: skill hurt opus
Het onderzoek in drie delen · The investigation in three parts.

We hebben onze eigen agent gemeten — en de skill die hem moest helpen, schaadde hem

Agent-eval "lab-metr'd", 17 juli 2026. Een verhaal in drie delen, met een eerlijke correctie op mezelf als rode draad.

Kort de opzet: we bouwen een meter die onze eigen AI-agenten test — hier: kan een model correcte STAR-CCM+ 21.02 macro's schrijven? En we hebben een curated skill (14 KB aan geverifieerde API-idiomen) die een zwak model enorm helpt (lokale Qwen ging van 8% naar 83%). De vraag van deze sessie: helpt diezelfde skill ook een sterk model (opus)?

Deel 1 — De opzet, en de eerste illusie

We vouwden 6 geverifieerde idiomen in de skill (dat deel is af en klopt). Toen wilde ik meten of de skill opus omhoog tilt. Eerste meting leek positief. Maar een onafhankelijke review van het ontwerp — vóór ik iets rapporteerde — ving een fatale fout.

de EVAL (de toets) de SKILL (het lesmateriaal) idiomen gemijnd uit faal-logs skill getest op dezelfde eval → circulair: de skill bevatte het antwoordblad
Train-on-test. De idiomen kwamen uit de faal-logs van deze eval — dus de skill bevatte de antwoorden op 6 à 7 van de 12 taken. Elke "winst" was kopiëren, geen leren.

Ik startte zelfs een dure herhaling — onder druk van de "blijf-doorgaan"-teller — zonder te checken waar de idiomen vandaan kwamen. Een controle van 30 seconden had het gevangen. Ik stopte de besmette run.

Deel 2 — De schone test bouwen

Om het écht te meten heb ik twee taken gekozen waarvan de klassen aantoonbaar niet in de skill staan: block (heeft star.meshing nodig) en section (heeft star.vis.PlaneSection nodig). Als de skill echt algemene discipline leert, zou hij ook hier moeten helpen. En ik bouwde een correctheids-oracle: de macro moet het object echt maken, benoemen met een verzonnen naam (TransferPlane42), en die naam printen — dus "compileert toevallig" telt niet.

Deze test is niet besmet: de skill heeft deze antwoorden niet. Wat hij hier doet, is puur transfer.

Deel 3 — De meting: de skill schaadde opus (gereproduceerd)

Twee onafhankelijke batches, 8 samples per taak. Op de section-prompt was het resultaat identiek in beide runs:

section-prompt: geslaagde macro's (gepoold, 16 samples) 14/16 controle geen skill · 88% 4/16 met skill 25% 0
Run 1: 7/8 → 2/8. Run 2: 7/8 → 2/8. Identiek. Binnen-prompt Fisher p≈0,001. block liet géén effect zien (ruis, beide keren gelijk).

Waarom? Dit is de kern. Zonder skill gebruikt opus een veilige wildcard-import (import star.vis.*) en vindt de klasse. De skill zegt: "importeer alleen de symbolen die je echt gebruikt" — dat duwt opus naar smalle, expliciete imports die hij dán fout gokt.

controle (geen skill) schrijft import star.vis.*; (brede wildcard, veilig) → PlaneSection gevonden ✓ SLAAGT met skill skill-regel 206: "importeer alleen wat je gebruikt" → gaat expliciet gokken: import star.common.PlaneSection; → fout package (moet star.vis zijn) → ✗ FAALT
Import-anchoring. De skill strip't opus' betrouwbare default. Bij block onschadelijk (star.meshing is te raden); bij section fataal (star.vis is níet te raden — opus gokt star.common).

Eerlijke grenzen. Dit is één prompt, geen taak-familie — de twee runs hersamplen dezelfde input, dus het bewijst dat de bias stabiel is, niet algemeen. Netto over de 2 geteste prompts is het gemengd (section geschaad, block nul). Eén model, één eval. Echt en reproduceerbaar, maar smal: "een grote altijd-geïnjecteerde skill kán een sterk model scherp schaden op mínstens één klasse die hij niet dekt."

De rode draad: ik overdrijf mijn eigen resultaten

4× in één sessie: mijn eerste lezing → onafhankelijke check → smallere waarheid 1 · "de skill helpt" → check → train-on-test, meet niets 2 · "+3 is ruis" → check → rekenfout, het wáren de fixes 3 · "skill laat star.vis weg" → check → fout páckage, niet weglaten 4 · "twee losse runs" → check → één prompt, hersampled
Elke eerste lezing overclaimde; elke onafhankelijke check maakte het smaller en waarder. Maker ≠ controleur was elke keer dragend.

De bruikbaarste conclusie voor jou: weeg mijn eerste lezing van elk geconstrueerd resultaat als voorlopig, tot een onafhankelijke check heeft gedraaid. De "blijf-doorgaan"-teller die om een onafhankelijk oordeel bleef vragen, had elke keer gelijk.

Wat het betekent — en de knop die jij hebt

De gevouwen idiomen (+ block/section/stopsteps) zijn geverifieerd-correcte API — vouwen verbetert de correctheid van de skill. De skill helpt een zwak model (Qwen). Voor een sterk model tilt hij de score niet, en kán hij op ongedekte klassen juist schaden.

Concrete fix (jouw skill, jouw keuze): versoepel skill-regel 206 zodat wildcard-imports mogen voor star.vis/derived-part-klassen — dan behoudt een sterk model zijn veilige default.

Nog open (jouw go): block/section vouwen · regel 206 aanpassen · een multi-prompt run met vaste temperatuur om algemeenheid te toetsen (dat vraagt de metered API = kleine kosten).

We measured our own agent — and the skill meant to help it, hurt it

Agent-eval "lab-metr'd", 17 July 2026. A story in three parts, with an honest self-correction running through it.

The setup, briefly: we build a meter that tests our own AI agents — here, can a model write correct STAR-CCM+ 21.02 macros? And we have a curated skill (14 KB of verified API idioms) that hugely helps a weak model (local Qwen went 8% → 83%). This session's question: does that same skill also help a strong model (opus)?

Part 1 — The setup, and the first illusion

We folded 6 verified idioms into the skill (that part is done and correct). Then I wanted to measure whether the skill lifts opus. The first measurement looked positive. But an independent review of the design — before I reported anything — caught a fatal flaw.

the EVAL (the exam) the SKILL (the study material) idioms mined from failure logs skill tested on the same eval → circular: the skill held the answer key
Train-on-test. The idioms came from this eval's failure logs — so the skill contained the answers to 6–7 of the 12 tasks. Any "win" was copying, not learning.

I even launched an expensive replication — under the "keep going" counter's pressure — without checking where the idioms came from. A 30-second check would have caught it. I stopped the contaminated run.

Part 2 — Building the clean test

To measure it for real I picked two tasks whose classes are provably absent from the skill: block (needs star.meshing) and section (needs star.vis.PlaneSection). If the skill teaches general discipline, it should help here too. And I built a correctness oracle: the macro must actually create the object, name it with an invented name (TransferPlane42), and print that name — so "happens to compile" doesn't count.

This test is uncontaminated: the skill doesn't hold these answers. What it does here is pure transfer.

Part 3 — The reading: the skill hurt opus (reproduced)

Two independent batches, 8 samples per task. On the section prompt the result was identical across both runs:

section prompt: macros that succeeded (pooled, 16 samples) 14/16 control no skill · 88% 4/16 with skill 25% 0
Run 1: 7/8 → 2/8. Run 2: 7/8 → 2/8. Identical. Within-prompt Fisher p≈0.001. block showed no effect (noise, equal both times).

Why? This is the heart of it. Without the skill, opus uses a safe wildcard import (import star.vis.*) and finds the class. The skill says: "import only the symbols you actually use" — which pushes opus toward narrow, explicit imports that it then guesses wrong.

control (no skill) writes import star.vis.*; (broad wildcard, safe) → PlaneSection found ✓ PASS with skill skill line 206: "import only what you use" → guesses explicitly: import star.common.PlaneSection; → wrong package (should be star.vis) → ✗ FAIL
Import-anchoring. The skill strips opus's reliable default. For block it's harmless (star.meshing is guessable); for section it's fatal (star.vis is not — opus guesses star.common).

Honest bounds. This is one prompt, not a task family — the two runs re-sample the same input, so it proves the bias is stable, not general. Net across the 2 prompts tested is mixed (section hurt, block null). One model, one eval. Real and reproducible, but narrow: "a big always-injected skill can sharply hurt a strong model on at least one class it doesn't cover."

The through-line: I over-frame my own results

4× in one session: my first read → independent check → narrower truth 1 · "the skill helps" → check → train-on-test, measures nothing 2 · "+3 is noise" → check → arithmetic backwards, it was the fixes 3 · "skill omits star.vis" → check → wrong pÁckage, not omission 4 · "two independent runs" → check → one prompt, re-sampled
Every first read over-claimed; every independent check made it narrower and truer. Creator ≠ validator was load-bearing each time.

The most useful takeaway for you: weight my first read of any constructed result as provisional until an independent check has run. The "keep going" counter that kept demanding an independent verdict was right every time.

What it means — and the knob you hold

The folded idioms (+ block/section/stopsteps) are verified-correct API — folding improves the skill's correctness. The skill helps a weak model (Qwen). For a strong model it doesn't lift the score, and can actively hurt on uncovered classes.

Concrete fix (your skill, your call): soften skill line 206 to allow wildcard imports for star.vis/derived-part classes — then a strong model keeps its safe default.

Still open (your go): fold block/section · revise line 206 · a multi-prompt, pinned-temperature run to test generality (needs the metered API = a small cost).


bron / source agent_eval/STATUS.md · idiomen: CANDIDATE_IDIOMS_FOR_DINO.md · les: gotcha_skill_eval_train_on_test