9月19日、asyncdot.comが「Orchestrating Claude Code Agents: The Chief of Staff Pattern」と題した記事を公開した。Claude Codeエージェントを複数セッションで組み合わせて長時間作業させる実践が広まるにつれ、「なぜ途中で壊れるのか」という問いへの答えが求められている。記事はその原因を構造的に分析し、「参謀長(Chief of Staff)パターン」と呼ぶオーケストレーション手法で対処する方法を詳述している。
なぜ今このパターンが注目されるのか
Claude Codeのような自律型コーディングエージェントが実用段階に入り、数時間〜数日単位の作業を任せる試みが増えている。しかし長時間セッションにおける信頼性の低さは慢性的な課題だ。問題はエージェントのコーディング能力ではなく、セッションが長くなるほど「何が本当に起きているか」が把握できなくなるという構造的な問題にある。
記事はその原因を3つに整理する。
- コンテキストが有限で劣化する。 長いセッションは圧縮(コンパクション)される。3時間前に重要だった詳細がサマリーになり、具体情報が失われる。
- 自己報告が現実からずれる。 「テストが通った」と報告するエージェントは、最新の観測ではなく意図と記憶を報告している。セッションが長くなるほどそのギャップは広がる。
- 知見が蓄積されない。 セッション2時間目に苦労して得た教訓は、次のセッションが読める場所に書き残さない限り消える。
エージェントを増やしてもこれは解決しない。信頼性の低いレポーターが増えるだけで、誰も突き合わせをしない。
Chief of Staffパターンとは何か
「何が真実かを知ること」を専任とするセッションを1つ置く、という組織的な解決策だ。
具体的には、1つの長命セッションがオーケストレーターとして機能し、短命な別セッションに実装作業を委譲する。オーケストレーターはタスクの割り当て、クレームの検証、共有状態の維持を担う。実装はしない。オーケストレーターが実装を始めた瞬間、検証が止まり、パターンが崩壊する。
この構造はすでに複数の名前で知られている。
- Orchestrator-Worker(スーパーバイザー型、階層的オーケストレーション)
- Coordinator-Implementor-Verifier(CIV)
- Maker-Checker(金融・オペレーション由来)
- Integration Manager(Gitの分散ワークフローで文書化されている人間版)
記事が「Chief of Staff」という名前で呼んでいるのはメタファーに過ぎず、確立された術語ではない。なお、AnthropicのクックブックにもChief of Staffエージェントは存在するが、そちらはカレンダーや受信トレイを管理するアシスタント型の別物だ。
2つの構成要素
1. セッション基盤:cmux
ターミナルワークスペースを管理し、コマンドラインから操作できるツール。オーケストレーターは以下のように実行セッションを生成する。
cmux workspace create \
--name project-session-12 \
--cwd /path/to/repo \
--command 'claude "Read docs/briefs/current.md and do exactly what it says."'
2つの重要な注意点がある。
--commandはシェルにテキストを送るだけで、エージェントを起動するわけではない。 エージェントの明示的な呼び出しが必要。指示だけ渡してもシェルが受け取るだけで終わる。- プロンプトは短くし、ファイルを参照させる。 長いコマンド文字列は信頼性が落ちる。コミット済みのブリーフを参照させる方が再実行可能で、レビューも可能になる。
2. 永続状態ストア:Plan Desk
MCP(Model Context Protocol)経由でエージェントに公開されるプランニングボード。なお、Plan Deskは本記事の著者が開発・提供するツールであり、asyncdot.com自身の製品でもある点は留意されたい。オーケストレーターと各実行セッションが同じボードを読み書きする。
ボードはメモリだ。セッションは使い捨てだが、ボードはそうではない。
多エージェント構成が長時間動き続けられない原因の多くは、このコンポーネントをスキップすることにある。ボードに置くべき情報は以下のとおりだ。
- タスクをビルドコントラクトとして記述する。 問題定義、アクション、インターフェース、検証条件、非目標を含める。実行セッションが親ドキュメントを読まずに完了できる粒度まで詳細に。
- ステータスを作業と同期してアトミックに変更する。 開始時に
in_progress、検証完了時にdone。セッション終了時にまとめて更新するボードは意味をなさない。
動作ループ
オーケストレーターは以下の8ステップを繰り返す。
1. PULL ボードから次のブロックされていないタスクを取得
2. READ 着手前に紐づいた設計ドキュメントを読む
3. RED GATE 検証を先に実行:失敗することを確認する
4. DELEGATE 実行セッションにブリーフを渡す
5. PROVE 主張されたコマンドを再実行する。終了コードが判定する
6. OBSERVE 差分をハンクごとに読む
7. GATE 承認を解決し、理由を記録する
8. SHIP ステータスを変更し、そのアイテムだけをコミットする
なぜ「レッドゲート」が最初に来るのか
REDゲート(ステップ3)で開始前にチェックを実行するのは、開始前にチェックがすでにグリーンなら、作業は何も証明しないからだ。正しい実装と、チェックが一度も走っていない状態を区別できない。また、実際には「キューに積まれたタスクの相当数がすでに完了している」ことが多い。別のカードで実装済みだったり、後続の変更で不要になっていたりする。レッドゲートが一発でグリーンを返せば、数秒のコストで1時間の節約になる。
1タスク1コミットの理由
Gitの履歴がボードと1対1で対応する(ステップ8)。3日後に何かが壊れたとき、git log一発で原因の決定まで追跡できる。
検証ディシプリン:このパターンの核心
レポートは指示ではなく「証拠」として扱う
実行セッションが「49件グリーン、失敗ゼロ」と報告してきたとき、オーケストレーターの仕事はそれが真実かどうかを確かめることだ。エージェントが意図的に嘘をつくからではなく、「報告している対象」と「実際にチェックした対象」が異なることが多いからだ。
記事では具体的な失敗例を挙げている。あるセッションがコミットハッシュをログファイルに手書きし、git cat-fileで検証した。しかし実際には、シェル上の短縮ハッシュに対して検証しており、ファイルに書いた文字列は何も解決しなかった。チェックとレコードが別のオブジェクトを指しており、片方しかテストされなかった。
ルール:アーティファクトの値は、そのアーティファクト自体から読み返して検証する。
よくある失敗パターン
| パターン | 見た目 | 見逃す理由 |
|---|---|---|
| 空虚なアサーション | 機能の有無に関わらず通るテスト | 対象を削除してもグリーンのまま |
| サイレント不一致 | 何もマッチしないgrep・フィルタ | ゼロ件が「クリーン」に見える |
| エラーしたチェック | そもそも実行に失敗したコマンド | エラーが握りつぶされ、不在が証拠に見える |
| 間違った参照 | 「X以降」をキーにするフィルタ | その間に起きたことが漏れる |
| スコープ不一致 | 部分集合に対するグリーン | 分母が明示されない |
一般的な防御策: マッチしない可能性があるチェックは必ずそれを明示する。「ゼロ件」と「実行失敗」は区別できなければならない。「何もなかった」という不在アサーションには、同じ実行内にポジティブコントロールを含める。
永続チャンネルの優先
セッション間の直接メッセージングは便利だが、信頼性が十分ではない。キューに詰まったり、受信セッションの権限設定で保留されたり、未配達のまま期限切れになることがある。沈黙は合意ではない。
必ず届かなければならない情報は永続チャンネルに置く。
- コミット済みファイル(ブリーフ、引き継ぎドキュメント、制約)
- ボードのカードとコメント
- シェアリンク(プロンプトにコンテキストを貼り付けるのではなく、URLを参照させる)
メッセージはナッジ。ファイルはコントラクト。
タイムボックスの使い方
タイムボックスは「いつ報告するか」を決めるもので、「どこで作業を止めるか」ではない。タイマーが作業中に切れた場合は、そのアイテムを完了させ、検証し、コミットしてから報告する。作業途中で切ると、最も回復困難な状態(半適用・未検証)に陥る。
「続けてもよいですか?」と書きそうになったら削除する。見ている人間は割り込み、見ていない人間はその質問でランを殺す。
詳細はOrchestrating Claude Code Agents: The Chief of Staff Patternを参照していただきたい。