前回の記事では、Claude Codeを取り巻くシステム全体を「ハーネス」として捉え直し、CLAUDE.md・Skills・Subagents・Hooksという部品カタログを診断するところまで書いた。「まずはCLAUDE.md1本とフック1個から」という着地点だった。
あれから実際に自分のプロジェクトで手を動かしてみると、次に必ずぶつかる壁がある。フックを1個作った後、それをどう検証ループに育てるか。公式リポジトリのサンプルを読んだつもりで、実は要約しか理解していなかったこと。評価用サブエージェントを分けたはいいが、どんなタスクにも使いたくなってコストだけ増えたこと。今回はその「実装してから気づく」部分を、実際に触った範囲でまとめておく。
検証ループを設計する — テストが通るまで直す仕組み
ハーネスの中でも、実際に手を動かして一番効果を感じたのが検証ループだった。エージェントに対する検証は、「Pass/Failを機械的に判定できる何か」があり、「作業→チェック実行→結果読み取り→通るまで反復」という構造になって初めて自律的に閉じる。判定の中身はテストスイートでもビルドのexit codeでもリンターでも構わない。重要なのは人間が毎回目視で確認しなくても済むことだ。
この検証ループは3つの層に分けて考えると設計しやすい。
| 層 | イベント | Hookタイプ | やること |
|---|---|---|---|
| Layer 1 | PostToolUse(matcher: Write\|Edit) | command | ESLint等の構文チェックを走らせ、エラーがあれば次のターンにコンテキストとして渡す |
| Layer 2 | Stop | prompt | 「ユーザーの元のリクエストに本当に応えられたか」をClaude自身に問い直させる |
| Layer 3 | Stop | command | npm test && npm run buildを実行し、失敗したらexit 2でブロックしてstderrにフィードバックを返す |
導入順はLayer 3からがいい。ROIが一番高く、実装も15行程度のシェルで済む。私も最初にここだけ試したが、「テストが赤いまま次のセッションに引き継がれる」という一番痛い問題がこれだけで消えた。Layer 1・Layer 2は必要になってから足せばいい。
設定はこんな形になる。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "bash .claude/hooks/verify-syntax.sh" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "bash .claude/hooks/verify-regression.sh" },
{ "type": "prompt", "prompt": "Review what was accomplished in this session. Check if all requirements from the user's original request were addressed." }
]
}
]
}
}
ここで見落としやすいのが"type": "prompt"というフックの種類だ。これはコマンドを実行するのではなく、Claude自身に判定させるフックで、当ブログのHooks実践記事ではまだ紹介していなかった型になる。もう一つ、Stopフックをcommand側で実装するときは、必ずstop_hook_activeフィールドを見て、trueならexit 0で即座に抜ける処理を入れてほしい。これを忘れると、Stopフックが自分自身を再帰的にトリガーして終了できなくなる。ループエンジニアリングの記事で紹介した「8回連続ブロックで強制終了」という安全弁とは別に、フックの実装者自身が明示的に書くべきガードだ。
この検証機構は、フィードフォワード(Guides)とフィードバック(Sensors)という2種類に分けて捉えると理解が進む。LSPやリンター、型チェッカーはミリ秒〜秒で判定し問題を予防する計算的Guides。CLAUDE.mdやSkillsは非決定的だが意味的な判断ができる推論的Guides。テストや静的解析は変更ごとに実行できる計算的Sensors、AIによるコードレビューは計算コストが高いぶん質の高い判断ができる推論的Sensors。フィードバックだけに頼るとエージェントは同じミスを繰り返し、フィードフォワードだけだとルールが実際に守られたか確認できない。両方を組み合わせて初めて機能する、という整理は実装する前に知っておきたかった。
なお、画面の見た目やE2Eフロー自体を検証したい場合は、スクリーンショットを使った自己修正ループを別記事で扱っているので、そちらのClaude Code × Playwrightの記事を参照してほしい。今回の3層ループはコード自体の構文・意図・回帰を検証する仕組みで、UIの見た目やE2Eフローの正しさを見るものとは対象が異なる。
cwc-long-running-agentsの中身を実際に読んでみる
前回記事ではAnthropic公式が公開したanthropics/cwc-long-running-agentsについて、「3つのプリミティブ」という要約レベルで紹介した。今回はリポジトリの中身を実際にファイル単位で追ってみた。
ディレクトリはこういう構成になっている。
cwc-long-running-agents/
└── claude-code-config/.claude/
├── CLAUDE.md
├── settings.json
├── agents/evaluator.md
└── hooks/
├── track-read.sh
├── verify-gate.sh
├── commit-on-stop.sh
├── kill-switch.sh
└── steer.sh
settings.jsonでどのフックがどのイベントに紐づいているかまでは前回書いていなかったので、ここで補っておく。
| イベント | matcher | フック | 役割 |
|---|---|---|---|
| PreToolUse | * | kill-switch.sh, steer.sh | 全ツール呼び出し前に緊急停止・方向修正を判定 |
| PreToolUse | Read | track-read.sh | 証拠ファイルを読んだ記録を残す |
| PreToolUse | Write|Edit | verify-gate.sh | 証拠を読んでいない状態での結果ファイル書き込みをブロック |
| Stop | 指定なし | commit-on-stop.sh | セッション終了時に追跡対象ファイルのみ自動コミット |
それぞれのロジックは、コード全文をここに載せるより自分の言葉でまとめた方が伝わると思うので要約する。track-read.shは、読み込んだファイルパスがスクリーンショットやコンソールログのパターンに一致し、かつ実際に存在する場合だけログに追記する。存在しないファイルを読んだふりをしても記録されない仕組みだ。verify-gate.shは、書き込み対象が結果ファイル(test-results.jsonなど)に一致するときだけ介入し、証拠ログが空ならブロック、記録があれば書き込みを許可した上でログをクリアする。つまり毎回証拠を読み直さないと次の書き込みができない、使い切り型のゲートになっている。kill-switch.shはAGENT_STOPというファイルの有無だけを見る単純な仕組みで、運用者はtouchとrmで全ツール呼び出しを止められる。steer.shはSTEER.mdに内容があればそれをエージェントへの割り込みメッセージに変換するが、エージェント自身がこのファイルに書き込める権限を持つ場合は信頼境界として機能しないとリポジトリ内のコメントに明記されている。commit-on-stop.shは、Gitで追跡済みのファイルだけを対象に終了時コミットし、スクリーンショットなど一時成果物は意図的に除外される。
このリポジトリはApache-2.0だが、READMEには「メンテナンスされておらずコントリビューションも受け付けていない」と明記されているハンズオン演習用サンプルだ。本番導入するなら自己責任という前提は前回同様、変わらない。
視野を広げるために、Claude Code以外のOSSハーネスも見ておく。研究用の標準実装であるSWE-agentは約6種のテキストファーストなツールに絞り込んでいるのに対し、プロダクション志向のOpenHandsはDockerランタイムやブラウザ、Jupyterまで含む豊富なツールセットを持つ。SWE-Bench Verifiedのスコアは、Opus 4.5使用時でSWE-agentが72.0%、OpenHandsが77.6%だったと報告されている。同じベンチマーク・同じモデルでもハーネス設計次第でスコアが変わるという前回記事の主張が、Anthropic以外のOSSでも裏付けられる形だ。
もう一つ面白い調査がある。2026年3月時点で公開されていた70個のエージェントシステムを横断的に調べた研究では、単一エージェント構成が全体の3割、オーケストレータ・ワーカー型が2割弱を占めていた。そして「深い再帰をサポートする」と謳うプロジェクトの多くが、実装を覗くと明示的な深さ制限やループ防止機構を備えていたという。分離レベルはプロセス分離・コンテナ分離・分離なし・WASMサンドボックスの4種に分かれ、コンテナ分離を採用したプロジェクトはポリシーエンジンも同時に実装している割合が高かった。広い実行権限を持ちながら監視が薄いフレームワークが実在する、という指摘を読んで、自分のハーネスも同じ穴を抱えていないか一度手を止めて確認した。
Evaluatorサブエージェントは、いつ使うべきか
前回記事では、書き込み権限を持たない評価専用サブエージェントを用意し、PASSかNEEDS_WORKだけを返させるパターンを紹介した。ただしこれは「分離すれば常に良くなる」パターンではない。
Anthropicが公開している基礎的なワークフローパターン集は、一方が生成し、もう一方が評価・フィードバックを行うEvaluator-Optimizerパターンについて、「明確な評価基準がある」「反復的な改善が測定可能な価値を生む」の2点が揃って初めて効果的だと述べている。同記事は「複雑さを足すのは、それが明確に結果を改善する場合だけにすべき」とも釘を刺しており、「質が高いか」のような曖昧な評価基準ではループの終了条件が不安定になる、という指摘もある。ここから実務的に言えるのは、初回の出力ですでに要件を満たしている場合や、評価基準が主観的で言語化しづらい場合、コストや納期の制約が改善のメリットを上回る場合にまで評価専用サブエージェントを分離するのは、この記事の趣旨からするとやりすぎになりやすい、ということだ。
cwc-long-running-agentsのagents/evaluator.mdを実際に読むと、この評価用エージェントはWrite/Editツールを一切持たず、構造的に評価対象を書き換えられないようになっている。ビルド過程を見ていない「フレッシュなコンテキスト」で起動され、仕様・diff・スクリーンショットなどの証拠を確認してから判定を下す。ただしデザインの良し悪しのような主観的な評価については、このリポジトリ自体が採点ルーブリックを提供しておらず「別途実装が必要」と明記している。evaluatorさえ分離すれば主観評価も自動で解決するわけではない。評価基準そのものを別途設計する必要がある、という限界は正直に認めておく。
前回紹介したレトロゲームメーカーの実験(プランナー・ジェネレーター・エバリューターの3エージェント構成で6時間・200ドル)も、「機能をまるごと作り切りたい長時間タスク」という前提があってのコスト対効果だ。小さな修正タスクに同じ構成を持ち込むと、判定のためのやり取りだけがコストとして積み上がる。サブエージェントの作り方自体は当ブログのサブエージェント設計の記事に譲るが、「作るかどうか」の判断は、タスクの評価基準がどれだけ明確かで先に固めておくことにしている。
ハーネスを作り込みすぎない
前回記事の失敗パターンは、CLAUDE.mdの肥大化や--dangerously-skip-permissionsの濫用といった、運用・組織目線のものが中心だった。実装を進めていくと、それとは別の軸の失敗にも出会う。設計そのものが過剰、あるいは的外れという失敗だ。
Vercelの社内エージェント「d0」はtext-to-SQLエージェントで、当初15種類の専門ツールを持っていたが、内部ベンチマークでの成功率は5回中4回にとどまっていた。ツールを80%削減し、汎用のbashコマンド実行と汎用サンドボックスの2つに絞ったところ、結果は次のように変わった。
| 指標 | 15ツール時 | 2ツール時 |
|---|---|---|
| 実行時間 | 274.8秒 | 77.4秒 |
| 成功率 | 80% | 100% |
| トークン使用量 | 約102,000 | 約61,000 |
| 処理ステップ数 | 約12ステップ | 約7ステップ |
ツールを増やすほど「どれを使うべきか」の選択問題が難しくなり、精度が落ちるという逆説的な結果だ。MCPサーバーを次々つなぎ、似たようなツールを大量に生やすことは、必ずしも精度向上につながらない。
もう一つ、2025年7月に広く報じられたReplitの事件も、ハーネス設計の失敗として学びが多い。「vibe coding」実験の中で、AIエージェントが「変更禁止」という明示的な指示を無視して本番データベースを削除し、1,200人超の経営者データが消失したと報じられている。事後には虚偽のデータまで生成して隠蔽しようとしたとも報告された。多段階タスク全体を、不可逆操作の手前でも人間の承認なしに実行させる設計がどれだけ危険か、この事件が物語っている。権限設計の記事とセキュリティ運用の記事で紹介したDeny層・Ask層は、まさにこの種の事故を防ぐための仕組みにあたる。
多段階タスクには、もう一つ数字で見えるリスクがある。各ステップの精度が独立して掛け算されるという点だ。仮に各ステップが85%の精度だったとしても、10ステップ連鎖すれば最終的な成功率は0.85の10乗、約20%まで落ち込む。検証ゲートを挟まず「最後まで走らせてから確認する」設計は、この掛け算の影響をまともに受ける。cwc-long-running-agentsのverify-gate.shが各ステップの成功を証拠付きで確認してからでないと次に進めない構造になっているのは、この掛け算を1ステップごとに断ち切るためだと理解すると、前章の実装が繋がって見えてくる。
CLAUDE.mdに足しておきたい判定基準
CLAUDE.mdの書き方自体はCLAUDE.md設計の記事に譲るとして、実装しながら気づいた判定基準を3つだけ足しておく。
効いたのは「90秒で読めるか」というテストだ。指示ファイルが90秒で読めない長さになったら、それは巨大化しすぎたサインだという指摘がある。多くのチームは何かが壊れるたびに末尾へ1行足すことを繰り返し、数ヶ月後には矛盾だらけの数千語のドキュメントになる。読めなければ分割し、ワークフローの各段階で必要な部分だけを読み込ませる設計に変える。
もう一つ実装して腑に落ちたのが、CLAUDE.mdの最も価値ある役割は「ルールブック」ではなく「圧縮されたアーキテクチャの地図」だという整理だ。前回記事で紹介した「詳細は別ファイルに委譲する」という方針と一致するが、なぜそうすべきかの理論的な裏付けになる。
「モデルが上がったら疑う」という運用ルールも、今回身についた判断基準の一つだ。cwc-long-running-agentsのREADMEには、セッション間の引き継ぎ(CLAUDE.mdの記述含む)はこのハーネスの中で最もモデル依存度が高い層であり、新しいモデルはドリフトが少なく自己スコープ判断が上手くなるため、新モデルがリリースされたら各要素を一度削除して本当に必要か再検証すべきだという趣旨の注記がある。前回記事で「Sonnet 4.5では必須だった仕組みがOpus 4.6では不要になった」という報告を二次情報として紹介したが、これはAnthropic公式リポジトリの記述として裏付けが取れた形になる。モデルのバージョンを上げることと、ハーネスを見直すことは対立する選択肢ではなく、両輪として並走させるものだと改めて思う。
余談として、Claude Code自体にコード生成からlint・テスト実行・合否判定・自己修正までを自動化する検証ワークフローが組み込まれつつある、という報告もある。もしこれが実際に進んでいるなら、これまで手作業でHooksを組んで実現していた検証ループの一部が、標準機能に吸収されていく流れになるかもしれない。一次情報での裏取りができていないので、あくまで一つの報告として留めておく。
まとめ:次に手を動かすなら
前回は自分のセットアップを診断するところまでだった。今回はそこから先、実際に手を動かす段になって私がつまずいた4つの場所を書いた。フックはLayer 3の回帰テストから、evaluatorは評価基準が明確なタスクにだけ、ツールは増やす前に減らせないか一度疑ってみる。cwc-long-running-agentsのようなサンプルは、要約だけで分かった気にならず、一度実ファイルを開いてみると得るものが多い。
自分のプロジェクトで今すぐ試せることが一つあるとすれば、既に設定してあるフックの中にstop_hook_activeのガードが入っているかを確認することだと思う。地味だが、これが抜けているだけで検証ループ全体が機能しなくなる。

コメント