本文へスキップ
Ship Logo
Tech Blog Logo

設計は完璧だったのに動いていなかった:マルチエージェント基盤の顛末

家長真大

/

CEO

設計は残っていたのに、数ヶ月後に「これは今動いているのか」が自分で分からなくなったシステムがあります。社内でマルチエージェント基盤として設計した Command Center の顛末と、そこから引き出した「作る順番」の話です。

何を作ろうとしたか

2026年4月、社内向けにマルチエージェントのオーケストレーション基盤を設計しました。社内では Command Center と呼んでいます。構成は次のとおりです。

  • cc-spawn — Claude Code のヘッドレスセッションをプログラムから起動する
  • tmux — セッションを永続化し、名前付きで並列管理する
  • Notion — タスクDB。何を誰にやらせるかのキュー
  • Hooks 一式 — セッションのライフサイクル全イベントを捕捉する
  • DynamoDB + Slack — PreToolUse で危険操作を止め、Slack ボタンで承認する

タスクを Notion に積むとエージェントが順に起動して処理し、危険な操作にぶつかったら Slack にボタンが飛んできて、押すと処理が再開する。並列で自律的に開発が進む基盤です。設計としては、いま読み返してもそれなりに筋が通っています。

【図1】Command Center の構成と、実際に動いた範囲(画像は追って差し替え)

何が起きたか

数ヶ月後、自分で「Command Center って今動いているんだっけ」が分からなくなりました。

改めて確認すると、実態は次のいずれかでした。

  1. 設計とスクリプトは完成していたが、実運用には載っていない
  2. 一部(worktree の並列運用、Slack 通知 Hook など)だけを切り出して使っていた
  3. どこかに置いたまま忘れていた

先に動き出したのは、営業自動化パイプラインの方でした。そちらは「提案を送らないと売上にならない」という痛みが明確だったので、設計から実装、運用まで一気に通りました。Command Center は痛みが曖昧なまま、設計だけが精緻になっていたのです。

失敗の構造を4つに分解する

一度に全部を作る設計だった

起動・タスク管理・承認・通知・コスト追跡を1つの体系として設計しました。結果として「一部だけ動かす」ができない構造になりました。動かすには全部を立ち上げる必要があり、そのハードルを越える日が来ませんでした。

動かす動機となる痛みが薄かった

「並列で自律開発が回ると効率が上がる」は正しいのですが、明日困ることではありません。一方で「送った提案が誤送信だったら事故になる」は明日困ります。痛みの緊急度が実装の優先度を決めます。 設計の美しさは決めてくれません。

稼働の可視化がなかった

これが一番効きました。動いているかどうかを自分が知る手段がなかったので、動いていないことにも気づけませんでした。ダッシュボードでも Slack 通知でもよいのですが、稼働の証拠が出てこない仕組みは、静かに止まります。

展開コストが高かった

worktree ごとに設定ファイルをコピーする方式で設計していました。worktree を切るたびに手作業が発生するので、忙しい日には設定なしで起動します。それが常態になれば、仕組みは実質存在しません。

全部捨てずに、効用の高い部分だけ移植した

作り直しではなく、部分抽出を選びました。

移植したのは、通知とコスト追跡の Hooks です。しかも worktree ごとではなく ~/.claude/settings.json(ユーザーレベル)に置いて、全セッションに効かせました。Claude Code の設定は hooks のような配列フィールドがレイヤー間でマージされるため、既存のプロジェクト設定を壊さずに敷けます。

承認ゲートは、スクリプトは入れておいて既定で無効にしました。誤検知で作業が止まると、仕組みごと外されるからです。

結果として、Command Center という体系のうち生き残ったのは1割程度です。ただしその1割は毎日動いています。動いていない9割よりも価値があります。

tmux は Warp の代わりではない

蛇足のようで、実は重要だった話です。ターミナルは Warp を使っているので「tmux は要らないのでは」と思っていました。しかし用途が違います。

  • プロセスの永続化 — ターミナルを閉じてもセッションが生き続ける
  • SSH で再アタッチ — 外出先から作業中のセッションに入り直せる
  • プログラムからのセッション生成 — cc-spawn のような自動起動はこれがないと成立しない
  • 名前付きの並列管理 — セッションに意味のある名前を付けて管理できる
  • pane capture — 外部から画面内容を取得して監視できる

対話的に使うなら Warp が快適です。tmux は「自動化されたセッションの器」として必要になります。両方使う、が正解でした。

【図2】エージェント基盤を作る正しい順番(画像は追って差し替え)

教訓: 作る順番を逆にする

同じものを作り直すなら、この順番にします。

  1. 観測 — セッションの開始・終了・ツール使用をログと通知に出す。Hooks だけで完結する
  2. 通知 — 完了と異常が手元に飛んでくる状態を作る
  3. 承認 — 危険操作を止める。まずは検知のみ、その次に停止
  4. 起動の自動化 — ここでようやく tmux とタスクDBを繋ぐ
  5. オーケストレーション — 複数エージェントの協調はここ

オーケストレーターから作ると、動いているかどうかも分からないまま複雑さだけが増えます。逆に1と2は数時間で入り、その日から効きます。

エージェント基盤の最初の機能は、自分が稼働を確認できることです。

SHARE ON ❤️