コンテンツにスキップ

ハーネスレーシング

最初に 2 つのハーネスを同じ概要で競わせるとき、Codex と Claude Code のどちらが自分のコードベースに強いかが決められないという理由で行うでしょう。2 回目は、Aider が 40% 速くて diff も綺麗だったから — どのハーネスがどの種類のタスクで勝つかを知りたくなる。10 回目には、推測するより安いから競わせています。

SprintLoop における ハーネス は、概要を実行するエージェントランタイムです: Claude Code、Codex CLI、Cursor Compose、Aider、Devin、または harness adapter API 経由で接続する任意のハーネス。レーシング とは、同じ概要を兄弟レーン内で複数のハーネスに並列ディスパッチし、すべてに走らせ(あるいは最初の sign-off で止まり)、雰囲気ではなく diff comparator で勝者を選ぶことです。

なぜそもそも競わせるのか

真面目なコスト分析を生き延びる 3 つの理由:

  • 品質。 ハーネスごとに違うミスをします。Claude はコミットメッセージで過剰説明し、エッジケースのテストが薄くなる傾向。Codex はコメントが少なく、リファクタが過剰になる傾向。Aider は速くて外科的だが、曖昧な概要では停滞する。winner picker はそうしたスタイルの違いを気にしません — diff サイズ、テストカバレッジの差分、lint pass、Review Committee の判定で採点します。重要なランでフィールドのベストを得られます。
  • 速度。 レーシングディスパッチは、最初のハーネスがフロア(CI green、ブロッカー判定なし)を超える diff を出した時点で完了します。並列な作業では、ハーネスを直列に走らせ片方が失敗したらフォールバックするより、通常 30–50% 速くなります。
  • コスト抑制。 直感に反するのはここです。レーシングは N 倍のコストになると思いますよね。実際は 2 位のハーネスは予算の大半を使う前に殺されます — 我々のテレメトリで cancel された中央値のレーンは、勝者のトークンの 18% しか使いません。よって 3 ウェイレースは通常、単一ディスパッチの 1.4–1.6× で、3× にはなりません。

レーシングに反対する立場は、概要が瑣末(「この変数をリネーム」)なときや、特定の種類の作業で 1 つのハーネスを信頼するとき(「このリポジトリの小さなリファクタは常に Aider が勝つ」)には無駄だ、というものです。それで問題ありません — レーシングはディスパッチごとに opt-in で、ワークスペースはどの概要を競わせたか、競わせなかったかを覚えています。

comparator がどう勝者を選ぶか

レース内で終了した各レーンは スコア と共に exit します。スコアは以下の線形結合です。

シグナルウェイトソース
CI green0.30GitHub / GitLab status checks
Reviewer verdict0.25Review Committee (Architect, Security, QA)
Diff size delta0.15概要見積もりに対する LOC 追加/削減
Test coverage delta0.15カバレッジツール出力 (jest, pytest, go test)
Lint clean0.08リポジトリが宣言する linter
Wall time0.07First-to-finish ボーナス (90 秒で減衰)

ウェイトはワークスペースごとに Settings → Racing から設定できます。上記のデフォルトは、約 14,000 レースにわたる 6 か月の内部テレメトリでチューニングされています。規制業界に出荷するチームは通常、reviewer verdict のウェイトを上げ、diff size のウェイトを下げます。

comparator は、レース内の最初のレーンが「ready for review」を合図した時点で走ります。タイ(5% 以内)は picker を表示します — 人間のディスパッチャーが side-by-side diff ビューを得て選びます。タイバンドの外側は勝者を自動昇格し、負けた兄弟をキャンセルします。

何がキャンセルされ、何が残るか

comparator が勝者を選ぶと、兄弟レーンは canceled に遷移し、スコープクレームは即座に解放されます。彼らの tool log と署名済みエントリは監査台帳に永久に残り — 紙の跡なしのレーシングは最悪の無駄なので — キャンセルされたレーンの diff を後で開いて、敗者が試したことを確認できます。

キャンセルされた兄弟について 2 つ知っておくこと:

  • 彼らのコミットは push されません。 キャンセルされたレーンは PR を開きません。ブランチは SprintLoop ワーカー上でローカルに存在し、アーカイブされ、タグ付けしない限り 30 日で purge されます。
  • 彼らのツールコールとモデル消費は請求に残ります。 キャンセルが防ぐのは 新規 のトークン消費で、すでに消費されたものの遡及回収ではありません。だから comparator の first-to-finish ボーナスが効いてきます — 速い敗者は遅い敗者より安い。

よくあるレースと使いどころ

頻繁に見るレースのセット:

  1. 機能実装で Claude Code vs. Codex。 非自明な作業のデフォルト。2 つのハーネスには意味のある強みの違いがあり — Claude はアーキテクチャに、Codex はタイトでイディオマティックな実装に — comparator が綺麗にタイを破ります。
  2. 小さなリファクタで Aider vs. Codex。 機械的な作業と分かっているとき、Aider の小さな surface area が速さで勝つことが多く、Codex がリファクタがドリフトしていないかの sanity check を提供します。
  3. やっかいなバグで 3 ウェイ。 Claude Code、Codex、Cursor Compose。控えめに使う — 通常、単一ハーネスのディスパッチがすでに失敗した後。
  4. 1 つのハーネス、2 つのプロンプト。 同じハーネス、違う概要。主にプロンプトエンジニアリングの実験に使います — 役立ちますが、勝つプロンプトを選んだら止めるべきです。

実際に見るコスト

200 行の機能に対する 3 ウェイレースは、現在のモデル価格で典型的に $0.40–$1.20 のレンジに収まります — 競わせるハーネスと maxTokens 設定の積極性によります。負けレーンは勝者の CI シグナルから数秒で comparator に殺されるので、トークン消費の long tail は bounded です。

ワークスペース設定には日次レーシング予算が含まれます。超過すると、以降のレースは単一ハーネスディスパッチに degrade し、バナーを表示します。これは soft control で — インラインでオーバーライドできます — デフォルトを残したまま誰もが概要をレース化する暴走ループから何度かチームを救ってきました。

最初のレースのセットアップ

Cmd+N でディスパッチダイアログを開きます。ハーネスピッカーの下で Race をトグル。2 つか 3 つのハーネスを選びます(それぞれにキーが必要 — Get started を参照)。ワークスペースに予算上限があれば設定。Dispatch。

ディスパッチは N の兄弟レーン ID を返します。各々が Lanes パネルで自分のカードとしてレンダリングされ、カードは視覚的に “Race” ヘッダの下にグループ化され、ライブの勝者表示が付きます。どのカードをクリックしても、そのレーンの tool log と diff にドロップインできます。

勝者が選ばれると、レースヘッダは勝者のレーンカードに collapse し、残りは “Canceled siblings” disclosure にアーカイブされます。後でクリックして任意のレーンを inspect できます。