Was macht research-harness?
Das Modell ist selten der Grund, warum lange Experimentarbeit scheitert. Was scheitert, ist der Raum darum herum: ein Split, der sich stillschweigend geändert hat, eine handschriftlich eingetippte Zahl, ein Testsatz, der in das Training durchgesickert ist, eine sechste Variante einer bereits gescheiterten Idee, eine Polling-Schleife, die das Konto gesperrt hat. Dieses Skill verlagert diese Regeln aus Prosa in Dateien, Code und Hooks, angelehnt an die Harness/Loop/Graph-Struktur des Agent Engineering.
Die drei Ebenen, auf Experimente abgebildet
Harness (der Raum).
contract.json: Anspruch, Protokoll, Gate, Rechenregeln. Eingefroren.CLAUDE.md: eine kurze Karte des Projekts, kein Handbuch.frozen/: Split-Listen,eval.py, kopierte Baseline-Zahlen. Hash-gesperrt und schreibgeschützt.harness/launch.py: die einzige Möglichkeit, einen Lauf zu starten. Es erzwingt die GPU-Erlaubnisliste und die Leerlauf-Regel und startet den Job entkoppelt.traces.jsonl: eine Zeile pro Ereignis.state.json: die Entscheidung des Gates.lessons.md: Fehler, die bereits zweimal eine Korrektur erfordert haben.
Loop (die Zeit).
-
L1-Überprüfungsschleife:
frozen/eval.pybewertet jeden Lauf. Es ist die einzige Quelle für Metriken. -
Ausstiege werden vom Code entschieden (
harness/gate.py):- PASS: Der Kandidat übertrifft die Referenz um die Marge.
- BUDGET_EXIT: Maximale Anzahl an Varianten erreicht.
- STALL_EXIT: Kein Fortschritt für N Runden.
- REPRO_FAIL: Unsere Baseline-Reimplementierung weicht zu stark vom Paper ab.
Das Modell erklärt niemals selbst „fertig“.
-
L4 warte auf Änderung: Jeder Job schreibt zuletzt
runs/<id>/DONE. Warte auf diese Datei mit einem Hintergrund-Watcher, nicht mit wiederholtem Polling.
Graph (die Route). Bewusst klein gehalten:
Splits → einfrieren → Features → Referenzlauf (Baseline-Reimplementierung) → Kandidatenvarianten → Gate → Ausarbeitung.
Jeder Pfeil ist ein Dateivertrag (ein Split-TSV, eine Features-DONE.json, ein Lauf-scores/).
Einrichten eines Projekts
- Kopiere
template/in das Projekt auf dem Server. Kopiere den Aufgabencode insrc/(examples/aigi/ist ein vollständiges, durchgearbeitetes Beispiel für KI-generierte Bilderkennung). - Schreibe
contract.jsonaustemplate/contract.example.json:- Anspruch: ein Satz mit einer Zahl;
- Protokoll: genau wie im Quellpaper definiert; liste jedes nicht spezifizierte Detail und die getroffene Wahl in
open_questionsauf; - Gate: Referenz-Tag, Paper-Wert, Marge, Budget;
- Rechenregeln: Python-Pfad, Node/GPU-Erlaubnisliste, Leerlauf-Regel.
- Schreibe
paths.json(Datensatz-Wurzelverzeichnisse) und kopiere Baseline-Zahlen infrozen/baselines.json. Analysiere sie aus dem PDF mit einem Skript, das die Durchschnitte erneut überprüft; tippe sie niemals von Hand neu ein. - Einfrieren:
python harness/freeze.py add contract.json frozen/eval.py frozen/baselines.json. - Generiere Splits durch
launch.py, lies die Manifest-Zahlen und friere dann die Splits ein. - Installiere den Guard-Hook auf dem Rechner, der Claude Code ausführt:
- kopiere
hooks/research_guard.pynach<project>/.claude/hooks/; - schreibe
<project>/.claude/research_guard.jsonunter Verwendung des entfernten Projektverzeichnisnamens alsproject_markers-Eintrag; - merge
hooks/settings.snippet.jsonin<project>/.claude/settings.json.
- kopiere
Betriebsregeln
- Zahlen stammen nur aus
result.jsonoder der Gate-Zeile. Zitiere sie; berechne oder tippe Metriken niemals im Chat neu ein. Wenn eine Zahl nicht in einer voneval.pygeschriebenen Datei steht, existiert sie noch nicht. - Starte Läufe nur über
launch.py. Es verweigert wiederverwendete Lauf-IDs, geänderte eingefrorene Dateien und belegte GPUs und zeichnet die Code-Hashes für jeden Lauf auf. - Ein Lauf, eine Frage. Verwende die Lauf-ID und das Tag, um anzugeben, was getestet wird (
gfre_repro_s0,ml_l12-24_k256). Varianten der Kandidatenidee teilen sich dascandidate_tagdes Gates. Alles andere, wie Debugging oder Smoke-Tests, verwendet ein anderes Tag, damit es das Budget nicht verbraucht. - Respektiere das Gate.
- CONTINUE bedeutet, dass du eine weitere Variante versuchen darfst.
- BUDGET_EXIT, STALL_EXIT und REPRO_FAIL bedeuten: anhalten und die Beweise dem Menschen vorlegen. Korrigiere die Idee nicht ein sechstes Mal.
- Das eingefrorene Protokoll ändert sich niemals während eines Projekts. Falls es sich ändern muss (ein Bug in einem Split, ein vom Autor erfahrenes Protokolldetail), bearbeitet ein Mensch
FROZEN.sha256und ein neues Einfrieren beginnt. Frühere Ergebnisse bleiben mit ihrer eigenen Historie inresults.jsonl. - Warte auf
DONE-Dateien mit einem einzigen Hintergrund-Watcher. Jeder ssh-Aufruf innerhalb einer Schleife verwendet-o BatchMode=yesund stoppt bei Exit-Code 255. - Lies nach jedem Lauf die Ausgabe von
status.py, nicht die Roh-Logs. Öffnelog.txtnur bei Fehlschlag. - Wenn ein Fehler sich wiederholt, füge eine Zeile zu
lessons.mdhinzu und wandle ihn nach Möglichkeit in eine Prüfung um (einen Assert insrc/, eine Hook-Regel, eine Manifest-Prüfung).
Reviewer-Durchlauf (vor dem Vertrauen auf ein BESTANDEN)
Erzeuge einen Reviewer-Subagenten pro Perspektive. Gib jedem den Code und die Dateien, nicht deine Schlussfolgerung:
- Leakage: Überschneiden sich Trainings-, Validierungs- und Testdateien? Werden ausgeschlossene Muster wirklich ausgeschlossen? Gelangen Test-Labels jemals in den Trainingscode?
- Protokoll: Stimmen die Splits, Testsätze, der Schwellwert und die Metrik mit dem Quellpaper und
contract.jsonüberein? Werden die Entscheidungen zuopen_questionsoffengelegt? - Fairer Vergleich: Liegt die Referenz-Reimplementierung innerhalb der Toleranz? Stammen die kopierten Baseline-Zahlen aus demselben Protokoll? Sind neu gestartete Baselines gekennzeichnet?
Ein Reviewer ist genau so viel wert wie die Entscheidungen, die er ändert. Jede Perspektive liefert konkrete Datei/Zeilen-Beweise oder nichts.
Dateien
template/ in ein neues Projekt kopieren
CLAUDE.md Karte (Titel bearbeiten)
contract.example.json Anspruch / Protokoll / Gate / Rechenregeln
lessons.md
harness/ launch.py job.sh gate.py status.py freeze.py check_frozen.py trace.py common.py
frozen/eval.py Binary-Detection-Evaluator (ACC bei Schwellwert + AP pro Testsatz)
hooks/ research_guard.py + Beispielkonfiguration + Einstellungs-Snippet
examples/aigi/ KI-generierte Bilderkennung: GenImage + CNNDetection-Splits, CLIP-Feature-Caching,
GFRE-artiger Rekonstruktionsdetektor, GFRE-Tabellenparser
Quelle: Die Harness/Loop/Graph-Struktur folgt @0xwhrraris „Harness, Loop and Graph“ (November 2026).