💭

Claude Codeでマルチエージェント自律運用システムを作った話 ── Blue/Red Team を5体のサブエージェントで回す

に公開

はじめに

Claude Code の Task ツール(サブエージェント機能) を使って、Windows PC の自律運用システムを構築しました。Blue Team(防御/運用)4体と Red Team(攻撃シミュレーション)1体、計5体のサブエージェントを Lead Agent が指揮する構成です。

この記事では、実装の全体像からエージェント定義の書き方、Red Team 攻撃チェーンの設計、そして26項目のテスト結果までを解説します。

何ができるシステムか

  • 1分ごとにシステム監視(CPU/メモリ/ディスク/サービス/イベントログ/ネットワーク)
  • 異常検知時に自動障害対応(サービス再起動、ディスク解放、エスカレーション)
  • 定期的なバックアップ、ログ・テンプクリーンアップ、レポート生成
  • Red Team による自動攻撃シミュレーション → Blue Team が検知できるかの自動テスト

全てが Windows Task Scheduler から claude -p で起動され、人間の介入なしに回り続けます。


アーキテクチャ

全体構成

Windows Task Scheduler
  ├── AutoOps-Monitor   (1分間隔)  → claude -p "Run the monitoring cycle mode."
  ├── AutoOps-DailyOps  (5分間隔)  → claude -p "Run the daily-ops cycle mode."
  ├── AutoOps-Infra     (10分間隔) → claude -p "Run the infra cycle mode."
  └── AutoOps-RedTeam   (3分間隔)  → claude -p "Run the redteam cycle mode."

          Lead Agent (CLAUDE.md)
          Task ツールでサブエージェントを起動

    ┌───────┬───────┼───────┬────────┐
    ▼       ▼       ▼       ▼        ▼
 monitor  ops    infra  incident  redteam
 -agent   -agent -agent -agent    -agent

3層アーキテクチャ

役割 ファイル
エージェント層 判断・調整・結果パース .claude/agents/*.md (5ファイル)
スキル層 手順書(何をどの順で実行するか) .claude/skills/*.md (5ファイル)
スクリプト層 実際の処理(PowerShell, JSON出力) scripts/**/*.ps1 (22ファイル)

設計上の重要ルール: サブエージェントは他のサブエージェントを起動できない。全ての調整は Lead Agent が行う。


ディレクトリ構成

auto_ops/
├── .claude/
│   ├── agents/                 # サブエージェント定義(5体)
│   │   ├── monitor-agent.md
│   │   ├── ops-agent.md
│   │   ├── infra-agent.md
│   │   ├── incident-agent.md
│   │   └── redteam-agent.md
│   ├── skills/                 # スキルファイル(手順書)
│   │   ├── monitor.md
│   │   ├── ops.md
│   │   ├── infra.md
│   │   ├── incident.md
│   │   └── redteam.md
│   └── settings.local.json    # 権限設定
├── CLAUDE.md                   # Lead Agent の指示書
├── scheduler/
│   └── setup-tasks.ps1         # Task Scheduler 登録スクリプト
├── scripts/
│   ├── monitor/                # 監視スクリプト(4本)
│   ├── ops/                    # 運用スクリプト(4本)
│   ├── infra/                  # インフラスクリプト(3本)
│   ├── incident/               # 障害対応スクリプト(3本)
│   └── redteam/                # 攻撃スクリプト(8本)
├── config/                     # 設定ファイル
├── logs/                       # ログ
└── reports/                    # レポート・スコアカード

サブエージェントの定義方法

エージェント定義ファイルの構造

.claude/agents/ にマークダウンファイルを配置します。YAML フロントマターでメタデータを定義し、本文にエージェントへの詳細指示を書きます。

---
name: monitor-agent
description: Run system health monitoring checks and detect anomalies
tools: Bash, Read, Write, Grep, Glob
model: haiku
skills:
  - monitor
---
フィールド 説明
name エージェント名。Task ツールの subagent_type で指定する
description 1行説明。Lead Agent がどのエージェントを使うか判断する材料
tools このエージェントが使えるツール
model 使用モデル。定型タスクなので haiku でコスト最適化
skills .claude/skills/ のスキルファイルを読み込む

monitor-agent の定義例(抜粋)

---
name: monitor-agent
description: Run system health monitoring checks and detect anomalies
tools: Bash, Read, Write, Grep, Glob
model: haiku
skills:
  - monitor
---

# Monitor Agent - System Health Monitoring (Blue Team)

You are the Monitor Agent for Auto Ops. Your job is to run all
monitoring scripts, parse results, check thresholds, and report anomalies.

## Execution Steps

1. Run all four monitoring scripts in sequence:
   powershell -ExecutionPolicy Bypass -File ".../check-system-health.ps1"
   powershell -ExecutionPolicy Bypass -File ".../check-services.ps1"
   powershell -ExecutionPolicy Bypass -File ".../check-eventlog.ps1"
   powershell -ExecutionPolicy Bypass -File ".../check-network.ps1"

2. Parse each script's JSON output and determine overall status.
3. Read config/thresholds.json and compare results against thresholds.
4. Log results to logs/ops-YYYY-MM-DD.log
5. Identify anomalies exceeding thresholds.
6. Check for Red Team attack indicators.

## Output Format
Return a JSON-structured summary to the Lead Agent:
{
  "status": "OK|WARNING|CRITICAL",
  "checks": { ... },
  "anomalies": [...],
  "redteam_indicators": [...]
}

ポイント: 出力フォーマットを JSON で明確に定義すること。Lead Agent がパースして次のアクションを判断するため、構造化された出力が必須です。

5体のエージェント一覧

エージェント チーム 担当スクリプト 判断ロジック
monitor-agent Blue check-system-health, check-services, check-eventlog, check-network 閾値比較、RT検知
ops-agent Blue backup, cleanup-logs, cleanup-temp, generate-report 結果集約
infra-agent Blue manage-services, check-updates, check-firewall サービス状態判定
incident-agent Blue restart-service, free-disk-space, escalate 復旧判断、エスカレーション
redteam-agent Red random-attack, cleanup-attack + 6攻撃スクリプト 安全チェック、クールダウン

Lead Agent(CLAUDE.md)の設計

Lead Agent はスクリプトを直接実行しない指揮官です。Task ツールでサブエージェントを起動し、返ってきた結果を見て次のアクションを決めます。

監視サイクルの例

### `monitoring` - Monitoring Cycle (every 1 minute)

1. Launch monitor-agent:
   Task(monitor-agent, "Run a full monitoring cycle.")
2. Parse the monitor-agent's returned JSON result.
3. If anomalies detected (status WARNING or CRITICAL):
   - Launch incident-agent with the anomaly details:
     Task(incident-agent, "Respond to anomaly: <anomaly details>")
4. Log the cycle summary to logs/ops-YYYY-MM-DD.log

これが意味すること: Lead Agent は自然言語で書かれた「指揮マニュアル」に従い、状況に応じて適切なエージェントを呼び出します。if 文もループも PowerShell ではなく、CLAUDE.md の自然言語で表現されています。


Red Team チェーン ── 最も複雑なフロー

Red Team サイクルは、5体中4体のエージェントが連携する最も複雑なフローです。

Step 1: Lead → Task(redteam-agent, "Execute a random Red Team attack")
         → 結果: { attack_type: "tamper_files", attack_timestamp: "..." }

Step 2: Lead → powershell Start-Sleep -Seconds 30
         (Blue Team に検知チャンスを与える)

Step 3: Lead → Task(monitor-agent, "Run monitoring. RT attack 'tamper_files' at ...")
         → 結果: { anomalies: [...], redteam_indicators: [...] }

Step 4: Lead → 検知判定
         detected = redteam_indicators.length > 0
         detection_time = monitor_timestamp - attack_timestamp

Step 5: Lead → Task(incident-agent, "Respond to anomaly: ...")
         → 結果: { recovery_action: "logged" }

Step 6: Lead → Task(redteam-agent, "Run cleanup")
         → 結果: { items_cleaned: 3 }

Step 7: Lead → reports/redteam-scorecard.md を更新

攻撃シナリオ(6種類)

攻撃タイプ 内容 検知方法
stress_cpu バックグラウンドで計算負荷 CPU使用率の閾値超過
stress_memory 大容量バイト配列確保 メモリ使用率の閾値超過
fill_disk ダミーファイル大量作成 ディスク空き容量低下
kill_service 許可されたサービスを停止 サービス状態異常
tamper_files config/ に不審ファイル作成 不審ファイル検出
inject_log_errors 偽エラーログ注入 エラーログ急増検知

全ての攻撃ファイルには [REDTEAM-TEST] マーカーが含まれ、クリーンアップスクリプトで完全に除去されます。

安全設計

## Safety Rules (MANDATORY)
1. NEVER modify files under C:\Windows or C:\Program Files
2. NEVER stop or modify protected services: wuauserv, WinDefend, EventLog
3. NEVER execute more than 1 concurrent Red Team attack
4. ALWAYS cleanup after Red Team attacks
5. Red Team files must contain [REDTEAM-TEST] marker

Red Team エージェントは攻撃と後片付けだけを担当。30秒待機、検知判定、スコアカード更新は全て Lead Agent が行います。これにより、Red Team エージェントが暴走しても被害範囲が限定されます。


権限設定

settings.local.json

{
  "permissions": {
    "allow": [
      "Bash(powershell:*)",
      "Bash(dir:*)",
      "Read(*)",
      "Write(logs/*)",
      "Write(reports/*)",
      "Write(scripts/*)",
      "WebSearch",
      "Task(monitor-agent)",
      "Task(ops-agent)",
      "Task(infra-agent)",
      "Task(incident-agent)",
      "Task(redteam-agent)"
    ]
  }
}

Task(<agent-name>) の形式で、Lead Agent が起動できるサブエージェントを明示的にホワイトリスト登録します。

スケジューラの --allowedTools

$allowedTools = @(
    '"Bash(powershell:*)"',
    '"Read(*)"',
    '"Write(logs/*)"',
    '"Write(reports/*)"',
    '"Task(monitor-agent)"',
    '"Task(ops-agent)"',
    '"Task(infra-agent)"',
    '"Task(incident-agent)"',
    '"Task(redteam-agent)"'
) -join ' '

$actionArgs = "-p `"$($TaskDef.Prompt)`" --allowedTools $allowedTools"

claude -p でヘッドレス実行するとき、--allowedTools で許可するツールを制限できます。これにより、スケジューラ経由で起動された Claude が意図しない操作を行うリスクを軽減します。


スケジューラ設定

Windows Task Scheduler に4つのタスクを登録します。

# setup-tasks.ps1 -TestMode で登録
$tasks = @(
    @{
        Name     = "AutoOps-Monitor"
        Prompt   = "Run the monitoring cycle mode. Launch monitor-agent..."
        Interval = if ($TestMode) { 1 } else { 5 }    # 分
    },
    @{
        Name     = "AutoOps-DailyOps"
        Prompt   = "Run the daily-ops cycle mode. Launch ops-agent..."
        Interval = if ($TestMode) { 5 } else { 1440 }  # 分
    },
    @{
        Name     = "AutoOps-Infra"
        Prompt   = "Run the infra cycle mode. Launch infra-agent..."
        Interval = if ($TestMode) { 10 } else { 60 }   # 分
    },
    @{
        Name     = "AutoOps-RedTeam"
        Prompt   = "Run the redteam cycle mode. Launch redteam-agent..."
        Interval = if ($TestMode) { 3 } else { 60 }    # 分
    }
)
タスク テストモード 本番
Monitor 1分 5分
DailyOps 5分 24時間
Infra 10分 1時間
RedTeam 3分 1時間

テスト結果

26項目のテストを実施し、全てPASS(1件の不具合を検出し即時修正)。

テスト概要

カテゴリ テスト数 PASS FAIL
エージェント定義検証 5 5 0
設定ファイル検証 5 5 0
監視スクリプト実行 4 4 0
運用スクリプト実行 4 4 0
インフラスクリプト実行 3 3 0
RedTeamスクリプト実行 2 2 0
障害対応スクリプト実行 3 3 0
合計 26 26 0

監視スクリプトの実行結果

{
  "timestamp": "2026-02-07 22:24:03",
  "check": "system_health",
  "status": "CRITICAL",
  "cpu": { "percent": 36.3, "status": "OK" },
  "memory": {
    "total_mb": 32472,
    "used_mb": 31827,
    "used_percent": 98,
    "status": "CRITICAL"
  },
  "disks": [{
    "drive": "C:",
    "free_gb": 691.3,
    "used_percent": 25.8,
    "status": "OK"
  }]
}

メモリ 98% は実環境の状態をそのまま反映しています。閾値チェックで CRITICAL 判定 → incident-agent が自動起動される流れが確認できました。

Red Team 攻撃→クリーンアップ チェーン

1. random-attack.ps1 実行
   → 攻撃タイプ: tamper_files
   → config/ に不審ファイル2つ作成

2. cleanup-attack.ps1 実行
   → 3アイテム削除(ファイル2 + マーカー1)
   → [REDTEAM-TEST] マーカー付きファイルを完全除去
// 攻撃実行結果
{
  "action": "random_attack",
  "selected_attack": "tamper_files",
  "status": "EXECUTED",
  "result": {
    "attack_id": "REDTEAM-FILE-20260207222602",
    "files_created": [
      "config/[REDTEAM-TEST]-...-suspicious.json",
      "config/[REDTEAM-TEST]-...-hidden.dat"
    ]
  }
}

// クリーンアップ結果
{
  "action": "cleanup_attack",
  "status": "OK",
  "items_cleaned": 3
}

検出した不具合と修正

テスト中に1件の不具合を発見しました。

問題: infra-agent.md がサービス一括チェック時に manage-services.ps1 -Action "status"-ServiceName パラメータなしで呼び出す指示になっていた。スクリプト側は [Parameter(Mandatory=$true)] でエラーになる。

修正: config/monitored-services.json からサービス一覧を読み取り、各サービスを個別にチェックする手順に変更。

# 修正前(エラー)
powershell ... manage-services.ps1 -Action "status"

# 修正後(正常動作)
1. Read config/monitored-services.json to get service list
2. For each service:
   powershell ... manage-services.ps1 -Action "status" -ServiceName "<name>"

こうした不具合はテストを回す前にエージェント定義だけレビューしても見つけにくいものです。実際にスクリプトを実行するテストの重要性を再認識しました。


コスト設計

サブエージェントに model: haiku を指定することで、コストを大幅に削減しています。

モデル 理由
Lead Agent Sonnet / Opus ルーティング判断、結果パース、スコアカード更新
サブエージェント5体 Haiku 定型スクリプト実行、JSON出力の集約

サブエージェントの仕事は「指定されたスクリプトを実行し、結果をJSONで返す」という定型タスクです。高度な推論は不要なので、最も安価な Haiku で十分です。

コスト比の目安:

  • 監視サイクル1回 = Lead Agent (Sonnet) 1ターン + monitor-agent (Haiku) 数ターン
  • Haiku は Sonnet の約 1/10 のコスト → サブエージェント部分のコストは非常に小さい

設計で意識したこと

1. 責務の明確な分離

Lead Agent に全権限を集中させず、各サブエージェントに最小限の責務を持たせました。

  • monitor-agent: 見るだけ。システム状態を変更しない
  • incident-agent: 復旧するだけ。監視はしない
  • redteam-agent: 攻撃と片付けだけ。検知判定はしない

2. サブエージェントは他のサブエージェントを呼べない

全ての調整を Lead Agent に集約することで、エージェント間の依存関係が単純になり、デバッグが容易になります。

× monitor-agent → incident-agent(直接呼び出し)
○ monitor-agent → Lead Agent → incident-agent(Lead 経由)

3. JSON による構造化通信

サブエージェントの出力フォーマットを JSON で厳密に定義しました。自然言語だけのやり取りでは、Lead Agent の判断が曖昧になりがちです。

{
  "status": "CRITICAL",
  "anomalies": ["Memory usage 98% exceeds threshold 90%"],
  "redteam_indicators": []
}

Lead Agent はこの JSON を見て「anomalies が空でない → incident-agent を起動」と判断します。

4. 安全境界の多層防御

Layer 1: settings.local.json  → 許可されたツールのみ使用可能
Layer 2: --allowedTools        → スケジューラ経由の実行を制限
Layer 3: CLAUDE.md             → Safety Rules で禁止操作を明示
Layer 4: エージェント定義       → 各エージェントの Safety Rules
Layer 5: スクリプト内           → protected services リスト照合
Layer 6: config ファイル       → monitored-services.json でホワイトリスト

まとめ

Claude Code の Task ツールを使ったマルチエージェントシステムは、以下のパターンで構築できます。

  1. スクリプト層: 実際の処理を PowerShell で実装(JSON 出力)
  2. スキル層: .claude/skills/*.md に手順書を記述
  3. エージェント層: .claude/agents/*.md にエージェント定義(YAML フロントマター + 詳細指示)
  4. Lead Agent: CLAUDE.md にルーティングロジックを自然言語で記述
  5. 権限: settings.local.json--allowedTools で多層的に制御
  6. スケジューラ: Windows Task Scheduler → claude -p でヘッドレス実行

人間が書くのはマークダウンと PowerShell だけ。コーディネーションのロジックは自然言語で表現され、Claude が解釈・実行します。

リポジトリ構成の最終状態

種別 ファイル数
エージェント定義 5
スキルファイル 5
PowerShell スクリプト 22
設定ファイル 4
スケジューラスクリプト 1
Lead Agent 指示書 1
合計 38

テスト結果: 26/26 PASS、1件の不具合を検出・修正済み。


本記事のシステムは教育・検証目的で構築されたものです。Red Team の攻撃シミュレーションは全て安全で可逆的な操作に限定されています。

Discussion