アーキテクチャ11 min read2026-03-15
マルチエージェントアーキテクチャ設計:3マシン構成の実践
Mac Studio(Claude Code)+ STG VM(9エージェント)+ DEV VM(Strapi)の3マシン構成を設計・運用してわかった、オーケストレーターとワーカーの責務分離パターン。
S
Shintaku
AI Architect
なぜ3マシン構成なのか
「AIエージェントチーム」を設計するとき、最初に直面するのが「どこで何を動かすか」という問題です。全部同じマシンで動かすのがシンプルですが、実際に運用してみると責務の分離が重要だとわかりました。
現在の構成は以下の通りです:
- Mac Studio(192.168.68.120): 制御端末。Claude Code がここで動作し、SSH で VM を遠隔操作
- STG VM(192.168.68.72): Ubuntu 24.04。9体のエージェントが常駐し、RAGパイプラインを担う
- DEV VM(192.168.68.210): Ubuntu 24.04。Strapi CMS・開発環境
オーケストレーター / ワーカーパターン
最も基本的なパターンは「指揮者(オーケストレーター)」と「実行者(ワーカー)」の分離です。
- Aira(オーケストレーター): タスクを受け取り、分解し、適切なワーカーに委譲する
- KIKI(モニター): システム全体の健全性を監視する
- Haru(Reranker): 検索結果の品質評価に特化する
// オーケストレーターの基本構造(概念コード)
const orchestrator = new Agent({
model: "claude-opus-4-6",
systemPrompt: "タスクを受け取り、専門エージェントに委譲せよ",
tools: [delegateToWorker, monitorProgress, collectResults],
});
// ワーカーへの委譲
async function delegateToWorker(workerName, task) {
const workerUrl = AGENT_URLS[workerName];
const res = await fetch(`${workerUrl}/api/task`, {
method: 'POST',
body: JSON.stringify({ taskId: uuid(), type: task.type, payload: task.payload })
});
return res.json();
}
エージェントの独立性設計
各エージェントは独立したLinuxユーザーアカウントと、独立した20GB VDIを持っています。これは「隣のエージェントのファイルを見ない」というルールを物理的に強制するためです。
/mnt/agent-aira/ ← 20GB ext4(Aira 専用)
/mnt/agent-kiki/ ← 20GB ext4(KIKI 専用)
/mnt/agent-riku/ ← 20GB ext4(Riku 専用)
# 各マウントポイントに code/ data/ logs/ workspace/ が存在
RAGパイプラインとしてのデータフロー
ユーザーのクエリは以下の順序で処理されます:
- Aira がクエリを受け取り、Sen に振り分け判断を依頼
- Sen がクエリの意図を解析し、「ベクトル検索が必要」と判断
- Sora がベクトルDBに対して類似検索を実行
- Haru が検索結果を再ランキングして品質を向上
- Tomo が回答候補の幻覚チェック(出典確認)を実行
- Niko が最終回答を生成(ストリーミング)
監視:KIKIのヘルスチェック
// kiki/health-check.js(抜粋)
const AGENTS = [
{ name: 'aira', port: 9101 },
{ name: 'riku', port: 9103 },
// ... 9体分
];
async function checkAllAgents() {
const results = await Promise.allSettled(
AGENTS.map(async (agent) => {
const res = await fetch(
`http://localhost:${agent.port}/api/health`,
{ signal: AbortSignal.timeout(3000) }
);
return { ...agent, status: 'running', health: await res.json() };
})
);
return results.map(r =>
r.status === 'fulfilled' ? r.value : { name: r.reason.agent, status: 'down' }
);
}
3週間の運用で学んだこと
- エージェントの専門化は段階的に進める。最初は全員がAiraのコピーでも構わない
- ログの肥大化は想定より深刻。AIエージェントはオペレーション数が多いため、ログローテーションは必須
- 障害の局所化:VDIを分離しておくと、1エージェントが止まっても他は動き続ける
- Dashboard(:8080) を作ることで、全体状態の把握コストが大幅に下がる
#マルチエージェント#アーキテクチャ#RAG#VirtualBox