Zum Inhalt springen

Harness Racing

Wenn du zum ersten Mal zwei Harnesses gegen denselben Brief race-st, machst du es, weil du dich nicht entscheiden konntest, ob Codex oder Claude Code an deinem Codebase besser ist. Beim zweiten Mal, weil Aider 40 % schneller war und der Diff sauberer — und du wissen willst, welche Harness bei welcher Art Aufgabe gewinnt. Beim zehnten Mal race-st du, weil es billiger ist als zu raten.

Eine Harness in SprintLoop ist die Agent-Runtime, die einen Brief ausführt: Claude Code, Codex CLI, Cursor Compose, Aider, Devin oder jede Harness, die du über die Harness-Adapter-API anbindest. Racing heißt, denselben Brief parallel an zwei oder mehr Harnesses in Geschwister-Lanes zu dispatchen, sie alle fertig laufen zu lassen (oder durch das erste Sign-off zu killen) und einen Sieger über einen Diff-Comparator zu wählen statt nach Bauchgefühl.

Warum überhaupt racen

Drei Gründe, die eine ernsthafte Kostenanalyse überleben:

  • Qualität. Verschiedene Harnesses machen verschiedene Fehler. Claude neigt dazu, in Commit-Messages zu over-erklären und Edge-Cases zu under-testen; Codex neigt zu under-kommentieren und over-refactoren; Aider ist schnell und chirurgisch, aber bleibt bei ambigen Briefs hängen. Der Winner-Picker schert sich nicht um diese stilistischen Unterschiede — er bewertet Diff-Größe, Test-Coverage-Delta, Lint-Passes und Verdicts des Review Committee. Bei den Runs, die zählen, kriegst du das Beste aus dem Feld.
  • Geschwindigkeit. Ein Racing-Dispatch endet, sobald die erste Harness einen Diff produziert, der den Floor schafft (CI grün, kein blockierendes Reviewer-Verdict). Bei paralleler Arbeit ist das typisch 30–50 % schneller als Harnesses sequenziell laufen zu lassen und auf Fallbacks zu setzen, wenn eine scheitert.
  • Kostenkontrolle. Das ist die kontraintuitive. Du würdest denken, Racing kostet N-mal so viel. In der Praxis wird die zweitplatzierte Harness gekillt, bevor sie den Großteil ihres Budgets verbraucht — die mediane gecancelte Lane in unserer Telemetrie verbraucht 18 % der Tokens des Siegers. Ein 3-Wege-Race kostet also tendenziell 1,4–1,6× eines einzelnen Dispatch, nicht 3×.

Der Fall gegen Racing ist, dass es verschwenderisch ist, wenn der Brief trivial ist („benenne diese Variable um”) oder du einer Harness für eine spezifische Art von Arbeit vertraust („Aider gewinnt immer kleine Refactors in diesem Repo”). Das ist okay — Racing ist pro Dispatch opt-in, und der Workspace merkt sich, welche Briefs du geracet hast und welche nicht.

Wie der Comparator einen Sieger wählt

Jede fertige Lane in einem Race exited mit einem Score. Scores sind lineare Kombinationen aus:

SignalGewichtQuelle
CI green0.30GitHub / GitLab status checks
Reviewer verdict0.25Review Committee (Architect, Security, QA)
Diff size delta0.15LOC hinzugefügt/entfernt vs. Brief-Schätzung
Test coverage delta0.15Coverage-Tool-Output (jest, pytest, go test)
Lint clean0.08Welchen Linter das Repo deklariert
Wall time0.07First-to-finish-Bonus (decayed nach 90s)

Gewichte sind pro Workspace konfigurierbar unter Settings → Racing. Die obigen Defaults sind auf sechs Monaten interner Telemetrie über grob 14.000 Races getuned; Teams, die in regulierten Industrien ausliefern, pushen üblicherweise das Reviewer-Verdict-Gewicht hoch und das Diff-Size-Gewicht runter.

Der Comparator läuft, sobald die erste Lane im Race „ready for review” signalisiert. Ties (innerhalb von 5 %) oberflächen einen Picker — der menschliche Dispatcher bekommt eine Side-by-side-Diff-Ansicht und wählt. Alles außerhalb des Tie-Bands promoviert automatisch den Sieger und cancelt die verlierenden Geschwister.

Was wird gecancelt, was wird behalten

Wenn der Comparator einen Sieger wählt, transitionieren Geschwister-Lanes zu canceled und ihre Scope-Claims werden sofort freigegeben. Ihre Tool-Logs und signierten Einträge bleiben für immer im Audit-Ledger — Racing ohne Paper-Trail wäre die schlimmste Form von Verschwendung — und du kannst den Diff einer gecancelten Lane öffnen, um zu inspizieren, was der Verlierer versucht hat.

Zwei Dinge zu wissen über die gecancelten Geschwister:

  • Ihre Commits werden nicht gepushed. Eine gecancelte Lane öffnet nie ein PR. Der Branch existiert lokal auf SprintLoops Worker, wird archiviert und nach 30 Tagen gepurged, falls du ihn nicht taggst.
  • Ihre Tool-Calls und Modell-Spend bleiben auf deiner Rechnung. Cancellation verhindert neuen Token-Consumption, nicht die nachträgliche Rückholung des bereits Verbrauchten. Deshalb zählt der First-to-finish-Bonus des Comparators — schnelle Verlierer kosten weniger als langsame.

Häufige Races und wann sie zu benutzen sind

Die Race-Menge, die wir am häufigsten sehen:

  1. Claude Code vs. Codex auf einer Feature-Implementierung. Default für nicht-triviale Arbeit. Die zwei Harnesses haben bedeutungsvoll unterschiedliche Stärken — Claude bei Architektur, Codex bei dichten, idiomatischen Implementierungen — und der Comparator bricht den Tie meist sauber.
  2. Aider vs. Codex auf einem kleinen Refactor. Wenn du weißt, dass die Arbeit mechanisch ist, gewinnt Aiders kleinere Oberfläche oft auf Speed; Codex liefert einen Sanity-Check, dass der Refactor nicht gedriftet ist.
  3. Drei-Wege für einen haarigen Bug. Claude Code, Codex, Cursor Compose. Sparsam eingesetzt — meist nach einem fehlgeschlagenen Single-Harness-Dispatch.
  4. Eine Harness, zwei Prompts. Selbe Harness, andere Briefs. Hauptsächlich für Prompt-Engineering-Experimente — nützlich, aber abschalten, sobald du den Sieger-Prompt gewählt hast.

Kosten, die du wirklich siehst

Ein 3-Wege-Race auf einem 200-Zeilen-Feature landet typisch im $0,40–$1,20-Bereich mit aktuellen Modellpreisen — die Mileage hängt davon ab, welche Harnesses du race-st und wie aggressiv dein maxTokens-Setting ist. Die verlierenden Lanes werden vom Comparator innerhalb weniger Sekunden nach dem CI-Signal des Siegers gekillt, sodass der Long-Tail der Token-Spend gebounded ist.

Workspace-Settings enthalten ein Tages-Racing-Budget. Wenn du es überschreitest, degraden zukünftige Races zu Single-Harness-Dispatch und oberflächen ein Banner. Das ist eine Soft-Control — du kannst sie inline übersteuern — aber es hat ein paar Teams vor einer Runaway-Loop bewahrt, in der jeder Brief geracet wurde, weil jemand den Default angelassen hatte.

Dein erstes Race aufsetzen

Cmd+N öffnet den Dispatch-Dialog. Unter dem Harness-Picker togglest du Race. Wähle zwei oder drei Harnesses (du brauchst einen Key für jede — siehe Get started). Setze den Budget-Cap, falls dein Workspace einen hat. Dispatchen.

Der Dispatch returned N Geschwister-Lane-IDs. Jede rendert als eigene Card im Lanes-Panel; die Cards sind visuell unter einem „Race”-Header gruppiert mit einem Live-Sieger-Indicator. Klick jede Card an, um in ihr Tool-Log und Diff zu droppen.

Sobald ein Sieger gewählt ist, kollabiert der Race-Header in die Lane-Card des Siegers, und der Rest archiviert in ein „Canceled siblings”-Disclosure. Klick durch, um sie nachträglich zu inspizieren.