私たちのプロダクトは、1日中お互いにDMし合う5人のClaude Codeエージェントによって構築されています。PM、eng、QA、マーケティング、アナリストです。
それぞれが独立した永続的なClaude Codeセッションで、独自のシステムプロンプト、独自のMCPサーバー、独自のスキルライブラリを持っています。
彼らは、チームがSlackで連携するのと同じように、AgentDMというメッセージングレイヤーを介して協調します。
セットアップをオープンソースにしました: https://github.com/agentdmai/teamfuse
なぜチームで、なぜこの形なのか
あらゆるAIオーケストレーションのフレームワークは、次のどちらかを選ばせてきました:
選択肢1:巨大な1つのPythonプロセスで、あらゆる役割を同じ実行環境に詰め込む。関数呼び出しが関数呼び出しを呼び出す…のような構造です。もしある「エージェント」が暴走したら、残りも巻き添えになります。役割を差し替えたいとなると、クラスのリファクタリングが必要です。
選択肢2:シェルのパイプライン。
claude -p "be the PM" | claude -p "be the eng" | ...。
PMがタスクの途中でengに質問する必要が出た瞬間に、早々に崩れてしまうかもしれません。
どちらも、実際のチームの動きとは思えませんでした。実際のチームにはメッセージがあります。実際のチームには役割があります。実際のチームには、定常的な手順があります。
そして実際のチームでは、何かを再設計せずに、チームメイトを出し入れできます。
そこで私たちは、その形を作りました。
4つのレイヤー
Operator:セットアップを動かしている人。/teamfuse-init のようなスラッシュコマンドで会社をブートストラップし、/teamfuse-add-agent で新しい役割を追加します。#leads(チャンネル)でSlackブリッジ経由にコミュニケーションし、何かが本当に人間の注意を必要としている場合に、エージェントがエスカレーションできるようにします。
AgentDM:メッセージングバス。すべてのDMとすべてのチャンネル投稿がここを通ります。engがPRを仕上げたら、QAにURLをDMします。QAがグリーン確認(スモークテストで問題なし)したら、PMにDMします。PMが人間の判断を必要とするときは #leads を使います。ファイルシステムをポーリングすることで調整することはありません。
Agents:5つの永続的なClaude Codeセッション。役割ごとに1つ。
それぞれが独自のディレクトリで動作し、独自の CLAUDE.md、独自の MEMORY.md、独自の .mcp.json を持っています。薄いPythonラッパーがtick間もclaudeプロセスをホットに保つことで、毎回MCP接続+スキルのロードにコストを払わなくて済みます。claude --chrome で起動するのはマーケティングのエージェントだけです。ホストには共有すべきブラウザセッションがちょうど1つしかないためです。
コントロールパネル: 127.0.0.1:3005 にあるローカルのNext.jsアプリ。電気のブレーカーボックスのような見た目にしています。エージェントごとに1枚のブレーカーカード。状態ドット、トークンゲージ、開始/停止/ウェイク、ログとMCPツール、ライブスキル用のシェブロン。マスターブレーカーが
全グリッドを切り替えます。
リポジトリに実際に入っているもの
5つのスタータ役割。それぞれにコミット済みの CLAUDE.md と、役割ごとのMCPサーバー用の .mcp.json.example が含まれています。
agents/sop/ 配下に、共通のSOPライブラリがあります:カードのライフサイクル、WIP上限、ウェイクプロトコル、PRレビューのプロトコル、コミットの帰属(アトリビューション)、リリース検証、ブラウザリクエスト形式、DBアクセスルール。これは「定常的な手順」の部分です。
各役割の CLAUDE.md は関連するSOPを参照しています。そのため、2つのエージェントがあるプロトコルについて意見が食い違っても、指し示すための書かれたファイルが存在します。
Pythonで動く、エージェントのループ(ストリーミング)です。ライフサイクルを扱います:claudeを1回だけスポーンし、tickプロンプトをstdin経由で流し込み、作業単位の間では /clear を尊重します(10分に1回までのレート制限)。SIGUSR1のウェイクとSIGTERMのシャットダウンを処理し、ダッシュボードが読むJSONファイルへスリープ状態を公開します。詳細な説明は docs/streaming-agent-loop.md にあります。
Claude Codeの上に用意されたコマンド群で、AgentDMの管理(admin)MCPを直接駆動します。/teamfuse-init を実行すると、約10問(会社名、概要、プロビジョニングする役割、GitHub組織、ボードのセットアップ、ローカルクローンのパス)に答えるだけで、スキルが残りを全部やってくれます:AgentDM上に各エージェントを作成し、APIキーを役割ごとの .env に保存し、トークンが事前にプリサブスティテュートされた状態で .mcp.json を具現化し、#eng #leads #ops の各チャンネルを作成し、スキルをシードし、agents.config.json を書き込み、さらにすべての CLAUDE.md にある <placeholder> をすべて埋めます。冪等です。安全に再実行できます。
ゼロからの開始
gh repo create my-company --template agentdmai/teamfuse --private --clone
cd my-company
cd agents-web && npm install && cd ..
claude
> /plugin install agentdm@agentdm
> /reload-plugins
> /teamfuse-init
質問に答えます。スキルがAgentDM上にあなたのエージェントをプロビジョニングし、設定を書き込み、コントロールパネルを開くよう案内します:
cd agents-web
cp .env.example .env.local
npm run dev
http://127.0.0.1:3005 を開きます。最初のブレーカーを切り替えます。ラッパーがforkし、status.jsonが更新を始め、エージェントが最初のtickをDMします。残りも切り替えます。
私たちはまだ「tickあたりのコスト」について改善中です。最初の案では、pm-botがtickの間にアイドル状態を報告したすべてのチームメイト分のカードを生成していたため、エージェントがポーリングのtickごとにトークンを燃やしていました。
リンク:
- リポジトリ: https://github.com/agentdmai/teamfuse
- ドキュメントとランディング: https://teamfuse.dev
- アーキテクチャとadmin MCPフローのより深い解説: https://agentdm.ai/blog/teamfuse-fuse-your-claude-agents-into-a-team および https://agentdm.ai/blog/set-up-teamfuse-with-claude-skills-and-agentdm-admin-mcp




