CTS-KB

ステアリング駆動開発を、ループエンジニアリングで包む — 人の注意力で止めるから、機械の停止条件で止めるへ【v0.32.0】

⏱ 約 19 分で読めます
#ステアリング駆動開発#ループエンジニアリング#Loop Engineering#ループ設計#バイブコーディング#自律ループ#ハーネスエンジニアリング#Claude Code#Codex#Dynamic Workflows#fail-closed#停止条件

📖 はじめに — 「ステアリングは、ループエンジニアリングではないのか」

社内では長らく、AI 駆動開発の各フェーズを「ステアリング」という言葉で語ってきた。ところが 2026 年の夏以降、業界の主語は「ループエンジニアリング」へ移っている。エージェントに都度プロンプトを打つのをやめ、エージェントを回すループそのものを設計する、という考え方だ。

そこで素朴な問いが立った。当社のステアリング駆動開発と、ループエンジニアリングは何が違うのか。ハーネスには、ループエンジニアリングとして何が足りないのか。

この問いは、ステアリング駆動開発の記事側で整理した見解を、共通ハーネス cts-harness の repo で裏取りするところから始まった。裏取りの結果、見解は大筋で正しく、ただし 2 箇所で現状を読み違えていた。そして足りないものは、正確に 3 つに絞れた。本稿はその 3 つを v0.32.0 として同日に出荷した記録である。

先に結論を書く。

v0.32.0 で、AI 自身に「もう止まってよいか」を判断させる箇所がゼロになった。 ただしこれは「完成」ではなく「到達」である。理由は後述する。

🧭 ループエンジニアリングとは — Anthropic の 4 型ループと「ループ設計の 6 要素」

ループエンジニアリングとは、エージェントに都度プロンプトを打つ代わりに、エージェントを起動し、検証し、止めるループそのものを設計する手法である。 2026 年 6 月に Google の Addy Osmani 氏が命名し、Anthropic は同月 30 日に公式ブログ「Loop engineering: Getting started with loops」でループの型と設計原則を整理した。

Anthropic はループを「停止条件が満たされるまでエージェントが作業サイクルを繰り返すこと」と定義し、起動の仕方で 4 型に分けている。

起動停止Claude Code での主な道具
turn-based人のプロンプトエージェントが完了と判断検証スキル
goal-basedゴール条件つきの 1 回起動ゴール達成、または最大周回/goal
time-based一定間隔取り消し、または完了/loop(ローカル)、/schedule(クラウド)
proactiveイベント・スケジュール個々のタスクはゴール達成、ルーチンは手動停止まで/schedule/goal、skills、Dynamic Workflows、auto mode の組み合わせ

同じ記事は「成功条件と停止条件を明確に定義する」「周回上限を置く」「トークン使用量を管理する」を求め、/goal の公式ドキュメントは進捗なし停止と resume 時の復元を仕様として持つ。これらを本稿では 周回上限、予算、進捗なし検出、再開経路 の 4 つに整理し、さらに 起動条件合格判定 を加えた 6 つを「ループ設計の要素」と呼ぶ。6 という数え方は本稿のもので、Anthropic の原文にこの並びがあるわけではない。

系譜としては、プロンプト → コンテキスト → ハーネス → ループの 4 世代で語られることが多い。用語集の定義を借りれば、ハーネスが「エージェント 1 体の 1 セッションを安全に走らせる装具」で、ループは「そのハーネスごとエージェントを繰り返し起動し、結果を測って次の回転に反映させる運用系」である。

🎯 バイブコーディングとの違い — 停止条件を誰が握るか

ここで社内から、もっともな反論が出た。

外側を AI に任せるのは、結局バイブコーディングではないのか。LLM はまだ暴走する。

答えは「違う」だが、その根拠を正確に言わないと本当にバイブになる。分かれ目は 停止条件を誰が握るか である。

  • バイブコーディングでは、AI が「できました」と言えば終わりで、人が雰囲気で次を指示する
  • ループ設計では、起動条件・周回上限・進捗なし検出・予算・合格判定・停止理由の記録をすべて hook・スクリプト・CI が持ち、AI はその内側で動くだけ

AI 自身に「もう止まってよいか」を判断させた瞬間、それはループ設計ではなくバイブになる。 逆に言えば、「外側を AI に任せる」のではなく「外側を人が書いた決定論のコードに任せる」のがループエンジニアリングだ。これは当社ハーネスが現在地記事で掲げた「agent に選ばせない、推測させない、自己申告させない」を、コードの中身だけでなく 制御フローにも適用する ことに等しい。

当社の tdd-team Dynamic Workflow(以下 DW)は、内側の判定を既に agent から取り上げている。

  • workflow スクリプトは agent に「判定しない。PASS / FAIL は出力の verdict に入っている。あなたが書き換えるものではない」と明示している
  • 判定は helper の JSON(verdict / summary / digest)で決まり、agent の散文は読まない
  • 起動条件も機械で、tdd-team-dw-precheck.sh が 0 トークンで検査し、PreToolUse hook が赤なら Workflow 起動を deny する
  • 外側のループ自体が人の書いた決定論の JS で、AI はその中の agent() 呼び出しとして動く

つまり 6 要素のうち 起動条件と合格判定の 2 つは、最初から機械側にあった

なお Claude Code の /goal は、停止してよいかを評価モデルが判定する goal-based ループである。当社はその判定を LLM に置かず、helper の JSON と hook という決定論の側に置く。同じ goal-based でも、停止条件の持ち主が違う。

🔍 repo を実測する — 見解 2 箇所のずれ

記事側の見解は「いつ回すかは人の勘に残っている」「差し戻し周回は計測している」と書いていた。harness の repo を grep すると、どちらも現状を読み違えていた。

見解実測判定
いつ回すかは人の勘に残っているprecheck hook が「回してよいか」を止める。人に残るのは「回すと決める行為」だけ過大評価。「回すと決める」はループ設計でも人の側に置く
差し戻し周回を計測はしている周回上限・予算・停止理由コードは 1 行も存在しない。round(周回)数の記録も workflow が書くものではなく、wf_*.json を手で読んで memory に書いた実測値過大評価。計測は roadmap で「LOGI/AD から始める」段階

2 つ目が痛い。現在地記事で「差し戻し周回が 1.70 → 1.20 周/バッチ」と書いた数字は、機械が記録したものではなかった。計測層を作ったと終章で書いた後でも、ループの周回そのものは台帳に載っていなかった のである。

🕳️ 足りなかったもの — 正確に 3 つ

要素現状(v0.31.1)置く場所
周回上限と進捗なし検出なし。FAIL の生ログを読まずに同じ入力で再 run を続けた実例あり(cts-ec 2026-08-21)precheck に検査コードを足し、周回台帳に round 数と前 run の結果を記録。変わっていなければ deny
run 単位の予算なし。観測値も手作業workflow 内で runtime の budget API を差分で読み、stage 境界で検査
停止理由コード申し送り TSV に id と状態はあるが理由コードなしrun の成果物である handoff manifest に列を足す

3 つとも、既存パターン(precheck の検査コード追加・marker 系スクラッチの項目追加・helper の引数追加)で収まる。新機構はゼロ だ。壁打ちの見積もりで「変更ファイル約 20」と出て、実績は 21 だった。

もう 1 つ、進め方の判断があった。roadmap の計装 4 指標(出戻り round 数・ゲート発火数・欠陥 family 検出数・オーナー裁定回数)と別件にしないこと。上限は計測できる値にしか置けない ので、「round 数を機械で記録する」と「round 上限で止める」は同じ改修である。

🛠️ v0.32.0 — 停止条件層の実装(周回上限・予算・停止理由コード)

オーナーの「ループエンジニアリングの域に押し上げられるか」という発案から、GO、実装、テスト、tag まで同日だった。

🛠️ v0.32.0 — 停止条件層の実装(周回上限・予算・停止理由コード)

PC-ROUNDS ✅

上限 / 進捗なし ❌

stage 境界でbudget.spent 検査

超過

完走

fingerprint に取り込む

approve-round(理由必須)

PreToolUse hookprecheck --record-round

Workflowtdd-team-back-half.js

deny(台帳に検査コード)

handoff のみ起動stop-reason=budget

handoff manifeststop-reason / output-tokens

1. PC-ROUNDS — 周回上限と進捗なし検出

precheck に検査コード PC-ROUNDS を追加した。判定と記録の主体は precheck だけで、書く契機は hook 経由の --record-round、つまり起動の瞬間に限る。preflight からの再実行は表示のみで、同じ起動を 2 度数えない。

  • 周回台帳<git-dir>/cts-workflow/rounds/<branch>.tsv。5 列(ts / event / run-id / fingerprint / detail)、event は launch / deny / approve
  • 上限は同一 marker に 3 起動。ファイル定数で、env による上書きは無い(3a-skip-config と同じ原則)
  • 台帳は marker と同じ寿命。レビュー解消でエポックが終わると round 1 に戻る
  • 進捗なし検出 は fingerprint の一致で行う。fingerprint は diff-sha、codex-mode、profile、HARNESS_VERSION、そして 前 run の handoff manifest の digest(stop-reason 込み)。これらのいずれも変わらない再起動は、同じ入力で run を燃やしても同じ結果になるので deny する
  • 例外経路は 1 本だけ--approve-round --reason "<理由>" が approve 行を 1 本 append し、次の 1 起動を許可する。理由は台帳に残る

deny 行には発火した検査コードが残り、approve 行には人の理由が残る。これがそのまま ゲート発火の計装オーナー裁定回数の計装 になる。

2. run 単位の出力トークン予算

workflow が runtime の budget API(budget.spent()、この turn の出力トークン累計)を run 開始時点との差分で読み、stage 境界 3 箇所(3b-1 前 / 3b-2 前 / finalize 前)で超過を検査する。超過なら reviewer / finalizer を起動せず、handoff(lock 解放 + manifest)へ抜けて status=FAIL / failed-gate=budget / stop-reason=budget で止まる。

上限は RUN_OUTPUT_TOKEN_BUDGET = 300000。workflow の定数で、args による上書きは無い。出力トークンのみ が対象で、実 run の総トークン(2026 年 9 月の実測で 37〜63 万)とは単位が違う。だから 300k は見積もりであり、summary と manifest に載る output-tokens の実測で校正する前提だ。budget API が無い runtime では検査せず、その旨を log に明示する。

3. 停止理由コード

summary と handoff manifest に stop-reason が載る。語彙は pass / already-resolved / skip / layer-1-args / layer-2-preflight / gate-3a / finalize-3a / gate-3b / finalize-3b / budget の 10 語で、status と failed-gate から決定論的に導く。

workflow-finding-handoff.sh には --stop-reason(必須、語彙外は exit 2)と --output-tokens(任意)を新設した。値は workflow がコマンド行に機械で埋める。agent の判断ではない。 そして PC-ROUNDS はこの manifest を「前 run の結果」として fingerprint に取り込む。ここで停止理由が次の起動判定へ戻り、ループが閉じる。

設計を 1 点変えた

壁打ちの見積もりでは、停止理由を版の申し送り TSV と doctor の D-n 検査に置くと言っていた。実装で変えた。run の停止理由は run の成果物である handoff manifest に置くのが正しい。 申し送り TSV は版の単位、manifest は run の単位で、寿命が違う。doctor は無変更で済んだ。

後方互換と、意図した非互換 1 点

3 つとも既定は「発火しない側」である。正常 run は 3 起動以内、予算 300k 以内、stop-reason=pass で、workflow の全 suite が改修前のまま緑だった。

意図した非互換は 1 点。同一状態の再起動は初回から deny する(resume を含む)。承認コマンド 1 本で通る。利用側には申し送り 2 件(ALL-1: deny の有効化通知と「FAIL 後は manifest の stop-reason を読んでから再 run」、ALL-2: output-tokens を tasklist に 1 行残す)を配布した。

テスト改修前 → 後
precheck75 → 113
hook24 → 45
handoff60 → 71
workflow-3b136 → 151
resolve-review / mark-review-pending47 → 49 / 53 → 55

ミューテーション 3 種で赤になることを確認してから復元し、root 27 本と dist 59 本が全緑、doctor 0、EC / POS の実ツリーで精査した。

🧑‍✈️ 暴走モードで読み直す — 何が「人が気づく」から「機械が止める」へ移ったか

「LLM はまだ暴走する」への答えは、暴走モードごとに書くのが誠実だ。

暴走モードv0.31.1 までv0.32.0
テストを書き換えて緑にするchecksum で exit 3不変
自分の成果を自分で採点するverifier を別コンテキスト・別家族へ分離不変
未実行を PASS と偽るfail-closed と証跡突合不変
直らないのに延々と周回する人が気づいて止める上限 3 と進捗なし検出で機械が止める
トークンを食い尽くす観測値があるだけstage 境界の予算検査で機械が止める
止まった理由が読めず人が再走させる生ログを読むstop-reason を読んでから再 run。読まずに再 run すれば fingerprint 一致で deny

上 3 行は応用編第I部で塞いだもので、下 3 行が本稿の追加だ。どの行も AI への信頼を増やしていない。減らしている。人が疲れていても機械が止める層、というのが v0.32.0 の正確な説明である。

📏 Anthropic の基準で採点する — 満たしたもの、満たしていないもの

「到達」と言うなら、自分の物差しではなく Anthropic の物差しで測るべきだ。原典の「Getting started with loops」から基準を抜き出し、v0.32.0 のハーネスを正直に採点する。判定は 3 段階に分ける。✅ は機械で成立している。🔌 は部品と配線が揃っていて、ループを回していないだけ。🧭 は回す前に設計判断が要る。「未着手」と「未起動」を混ぜないためである。

#Anthropic の基準当社ハーネス v0.32.0判定
1ループとは、停止条件が満たされるまで作業サイクルを繰り返すことDW は stage 境界と verdict で回り、周回上限・予算で止まる。ただし FAIL 後に DW を自動で再起動する経路は無く、どの型なら無人で再試行してよいかも未決定🧭
2成功条件と停止条件を明確に定義する。テスト数やスコア閾値のような決定論的基準が最も効くverdict は helper の JSON、完了は AT / DoD、周回上限 3、出力トークン予算 300k、停止理由は 10 語の語彙。止める場面がまだ来ていない✅(未発火)
3明示的な基準なしに Claude に「完了」を判断させないagent は verdict を書き換えない。散文は読まない。stop-reason は workflow が機械で埋める
4決定論的な作業にはスクリプトを使うprecheck は 0 トークン、checksum、doctor、CI が先に走る
5仕事に合ったプリミティブとモデルを選ぶ。モデルと effort がコストの最大のレバーモデル台帳と roster の機械突合、役割ごとのティア割当、effort の二層ピン
6大規模実行の前にパイロットするpilot アームと A/B、効かない指標を ADR-019〜021 で判定から外した
7自分の仕事を検証する手段を与える。コードレビューには第二のエージェントを使うtest-writer / implementer / verifier を別家族・別コンテキストへ分離。証跡は SubagentStop hook が捕捉
8部分的にしか検証していない成果を返さないfail-closed。SKIPPED と PASS を区別。review-pending marker は解消がゲート
9個別の修正で止めず、学びを次の周回へ組み込むfinding 台帳、D-* 規範、欠陥 family 台帳、周回台帳の deny / approve 行
10使用量をレビューするoutput-tokens の機械記録は配線済み。校正は run が溜まれば済む。総トークンの集計だけ未配線🔌
11定期作業は time-based / proactive ループ(/loop/schedule)で回し、必要以上の頻度で回さない/loop/schedule は Claude Code の標準機能。エイリアスプローブ、四半期の剪定、台帳集計のスクリプトは既にある。無いのは起動と、各ルーチンの間隔と着地先の決定🔌
12ループを回し、結果を観測し、設計を改善する周回台帳は稼働中。データが溜まるのを待つだけ🔌

✅ が 8、🔌 が 3、🧭 が 1。回せば埋まるものが 3 つ、決めなければ埋まらないものが 1 つ である。Anthropic の 4 型のうち time-based と proactive は「作っていない」のではなく「回していない」が正確で、本当に設計判断が残るのは 1 番の「修正 → 再試行」だけだ。✅ の多くは応用編第I部と終章で積んだ資産で、v0.32.0 が足したのは 2 番と 3 番の後半、9 番の周回台帳、10 番の記録開始である。

/goal と何が違うか — 同じ goal-based でも停止条件の持ち主が違う

Anthropic の goal-based ループの実装は /goal で、公式ドキュメントによれば実体はセッション限定の prompt-based Stop hook である。ターンが終わるたびに小型モデルの評価器が条件を読み、Met / Not yet met / Impossible のいずれかを返す。当社の停止条件層と並べると、思想の差がはっきりする。

観点/goal(Anthropic)cts-harness v0.32.0
停止の判定者小型モデルの評価器。会話に現れた内容だけを読むhelper の JSON と precheck。決定論のみ
周回上限条件文に「stop after N turns」と書く定数 3 起動。env や args で上書き不可
進捗なし検出ツール使用のないターンが数回続くと停止fingerprint 一致で次の起動を deny。run 間のみ
予算status に token spend を表示。上限機能は無い出力トークン 300k で stage 境界停止。未校正
再開resume で goal を復元し、周回数をリセット同一状態の再起動は deny。理由つき承認で 1 起動
決定論にできない条件評価器が Impossible を返して止める停止条件層は扱わない。人の裁定へ上げる

Anthropic も「決定論的基準が最も効く」と書き、Stop hook はスクリプトによる決定論の検査も選べるとしている。当社はその決定論側に全振りした。代わりに、「設計がきれいか」のように決定論にできない条件は停止条件層の外にあり、人の裁定に残る。これは弱点ではなく線引きだが、線引きであることは書いておく。

今後の課題 — 🔌 と 🧭 を埋める順番

  1. 停止条件の初回発火を観測する。 上限 3、fingerprint 一致、予算 300k のどれかが実 run で止めた日に、2 番の「未発火」が消える。LOGI/AD で観測する
  2. 予算 300k を校正する。 manifest の output-tokens を tasklist に残す申し送りは配布済み。数 run 溜まった時点で、総トークンとの比率と上限値を決め直す
  3. run 内の進捗なし検出を足す。 現在の fingerprint は run 間の再起動しか見ない。/goal が持つ「ツール使用のないターンの連続」に相当する検出を、workflow の stage 境界に置けるか検討する
  4. 「修正 → 再試行」を機械にする。 裁定済みの型に限り、上限 3 の内側で DW を再起動する continue 側を作る。唯一の 🧭 で、どの型を無人にするかと起動主体をどこに置くかを先に決める。無人区間の線引き(MR まで、裁定済みの型のみ)は動かさない
  5. time-based / proactive を起動する。 既にあるエイリアスプローブ、台帳集計、剪定候補の抽出を /loop/schedule に載せる。新しい部品は要らない。決めるのは「必要以上に回さない」ための間隔とイベント起動の選択、そして結果の着地先だけ
  6. 使用量レビューを機械にする。 手作業の観測をやめ、run 単位の総トークンを周回台帳か finding 台帳に集計する

1 と 2 は待つだけで進む。5 と 6 は起動するだけで進む。設計が要るのは 3 と 4 で、特に 4 が次の実録の主題になる。

🔁 「完成」ではなく「到達」と書く理由

記事のタイトルで「ループエンジニアリングの完成」と書きたい誘惑はあった。上の採点表に 🔌 と 🧭 が残ることに加えて、書かない理由が 2 つある。

  1. 「修正 → 再試行」の周回は、まだ人が回している。 DW は FAIL を記帳して止まり、修正して再 run するのは Lead(人の指示で動くセッション)だ。「検出 → 修正 → 再試行 → 止める」のうち、v0.32.0 が機械にしたのは「止める」であって「回す」ではない。Anthropic の 4 型で言えば goal-based の停止側が揃った段階で、time-based と proactive はまだ回していない
  2. 停止条件が実際に発火した実績が、まだ無い。 上限で止まった run が 1 つも無い状態で「完成」と書くと、当社の教義「発火で測る」に自分で反する。LOGI/AD で初の機械停止を観測してから、初めて「完成」と書ける

だから本稿は「到達」で止める。「完成」の 1 語は、初回発火の実録のために取っておく。

🗺️ ハーネスエンジニアリングとの違い — ステアリングを捨てるのではなく包む

概要記事の業界用語対応表には、SDD、Context Engineering、Harness Engineering、Humans on the Loop の 4 行があり、Loop Engineering の行が無かった。「ステアリング駆動開発からループエンジニアリングへ」と書くと、ステアリングを捨てたように読める。実態は逆で、ステアリングが内側の中身、ループが外側の制御である。

当社での実体ループ設計での役割
ステアリング(Spec 層)壁打ち、規模判定、.steering/ 文書、ADR判断原則と外部記憶。ゴール条件の出所
ハーネス(強制・計測層)CLAUDE.md、hooks、agents、決定論ゲート、証跡、finding 台帳、CI合格判定、作る係と評価する係の分離
ループ(運転層)precheck hook、周回台帳、予算、stop-reason起動条件、周回上限、進捗なし検出、予算、停止理由、再開経路

人の関与にも 3 段階がある。毎ステップ承認する human-in-the-loop、例外だけ裁定する human-on-the-loop、放置する human-out-of-the-loop。バイブコーディングは 3 番目で、概要記事は最初から 2 番目を掲げていた。ループエンジニアリングは、2 番目を人の注意力ではなく機械の停止条件で成立させる技術 である。当社に足りなかったのはその停止条件の明文化であって、人を外すことではなかった。

無人区間の線引きも緩めない。対象は壁打ちの成果物が既に規範と台帳にある型に限り、終点は MR 作成までで、マージと本番反映は人が判断する。

🧾 まとめ

  • ループエンジニアリングとバイブコーディングの分かれ目は「停止条件を誰が握るか」である。外側を AI に任せるのではなく、人が書いた決定論のコードに任せる
  • 当社ハーネスは起動条件と合格判定を最初から機械側に持っていた。周回上限・予算・停止理由コードは 1 行も無く、周回数は手書きだった
  • v0.32.0 で PC-ROUNDS と周回台帳、run 出力トークン予算、stop-reason を既存パターンだけで足し、AI 自身に「止まってよいか」を判断させる箇所をゼロにした
  • 計装 4 指標のうち 3 つ(round 数、ゲート発火、裁定回数の下限)が同じ台帳に機械記録されるようになった
  • Anthropic の基準 12 項目で採点すると ✅ 8、🔌 3、🧭 1。回せば埋まるものが 3 つ、決めなければ埋まらないものが 1 つ
  • 「修正 → 再試行」の周回は人が回し、停止条件の発火実績は無い。だから「完成」ではなく「到達」

ステアリング駆動開発を、ループエンジニアリングで包む。 人の注意力で止める仕組みは、人が疲れた日に壊れる。機械の停止条件で止める仕組みは、壊れない代わりに、発火の実績で自分を証明しなければならない。次の実録は、その初回発火の日に書く。

📚 シリーズ記事(ステアリング駆動開発・応用編)

第I部: クロスファミリー検証(全 6 回)

  1. 総論 — マルチ LLM の 2 系統と見取り図
  2. 裏取り編 — +18.1pt 論文の検証
  3. 設計編 — finder/verifier 分業と逆順禁止
  4. TDD×ハーネス編 — テスト保護と三層ゲート
  5. 実装編 — Claude Code の中から Codex を動かす
  6. モデル戦略編 — ティア割当と「買うか組むか」

本編終章

  1. クロスファミリー検証の最終型 — 自分で正しさを測り直す

運用実録

  1. CI テスト 29 分 → 5.6 分 — 検証エンジンの平時運用
  2. GPT-5.6 sol 切替 — もう一つのデフォルト追従
  3. 遊休 90% の枠に仕事を振る — Codex 上流調査と verifier バッチ化
  4. ハーネスが単一プロジェクトを卒業する — プラグイン化と二層配布
  5. 69分で5リリース — Opus 5 当日対応が暴いた共通ハーネスの死角

現在地と事業展開

  1. 「最高品質ですか?」に Yes と答えないハーネス
  2. 二度の「1か月」を繰り返さない — 技術的負債から育てる AI 駆動開発ハーネス【サービス化への現在地】
  3. ステアリング駆動開発を、ループエンジニアリングで包む【v0.32.0】(本記事)

関連記事

関連用語

参考リンク(2026-09-04 時点で確認)