multi-agent-performance-profiling について
Multi-Agent Performance Profiling は、複数のエージェントを並行実行してシステム各層のボトルネックを調べるワークフロースキルです。段階別・メモリの計測、設定やクライアントの分析、バッチサイズの検討を行い、最適化前に優先度付きの提案をまとめます。
主な機能
- 015つの並行調査エージェントの調整
- 02パイプライン各段階とメモリの計測
- 03データベースとクライアント設定の確認
- 04バッチサイズのトレードオフ分析
- 05優先度付き提案の統合
活用シーン
- 01複数段階のパイプラインでボトルネックを特定
- 02SLO 未達の性能問題を調査
- 03データベース、クライアント、バッチの影響を比較
- 04最適化前に変更の優先度を決定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill multi-agent-performance-profilingインストール後、Claude Code で/multi-agent-performance-profilingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/evolution-log.mdimpact_quantification_guide.mdintegration_report_template.mdprofiling_template.py詳細
マルチエージェントによるパフォーマンスプロファイリング
自己進化型スキル:このスキルは使用を通じて改善されます。指示が誤っている場合、パラメーターがずれている場合、または回避策が必要だった場合は、先送りせず、すぐにこのファイルを修正してください。実際に再現可能な問題がある場合にのみ更新してください。
概要
複数のシステムレイヤーにわたるパフォーマンスのボトルネックを包括的に特定するため、プロファイリングエージェントを並列で起動する、手順を定めたワークフローです。QuestDB の取り込み速度が 1.1M rows/sec(目標の 11 倍)であることを突き止め、データベースはボトルネックではなく、パイプライン時間の 90%を CloudFront からのダウンロードが占めていることを実証しました。
このスキルを使う場面
次のような場合に、このスキルを使用します。
- パフォーマンスが SLO を下回っている場合(例:目標の 100K rows/sec に対して 47K)
- 複数段階のパイプラインを最適化する場合(ダウンロード → 展開 → 解析 → 取り込み)
- データベースのパフォーマンスを調査する場合
- 複雑なワークフローでボトルネックを特定する場合
- 最適化前に分析する場合(変更を加える前)
主な成果:
- 想定上のボトルネックではなく、真のボトルネックを特定する
- 各段階が全体の所要時間に占める割合を定量化する
- 影響度に基づいて最適化の優先順位を決める(P0/P1/P2)
- ボトルネックではない部分の早まった最適化を避ける
基本的な方法論
1. マルチレイヤープロファイリングモデル(5 エージェントパターン)
エージェント 1:プロファイリング(計測)
- 各パイプライン段階の実測時間
- フェーズ境界での time.perf_counter() による計測
- メモリプロファイリング(ピーク使用量、割り当て)
- ボトルネックの特定(全体に占める割合)
エージェント 2:データベース設定の分析
- サーバー設定の確認(WAL、ヒープ、コミット間隔)
- 本番環境と開発環境の設定比較
- 予想される影響の定量化(<5%、10%、50%)
エージェント 3:クライアントライブラリの分析
- API の使用パターン(データフレームと行単位の比較)
- バッファーサイズの調整機会
- 自動フラッシュの動作分析
エージェント 4:バッチサイズの分析
- 現在のバッチサイズの検証
- 最適なバッチ範囲の決定
- メモリーオーバーヘッドとスループットのトレードオフ
エージェント 5:統合と総合分析
- エージェント間の合意形成
- 影響度を定量化した優先順位付け(P0/P1/P2)
- 実装ロードマップの作成
2. エージェントのオーケストレーションパターン
並列実行(5 つのエージェントをすべて同時に実行):
Agent 1 (Profiling) → [PARALLEL]
Agent 2 (DB Config) → [PARALLEL]
Agent 3 (Client Library) → [PARALLEL]
Agent 4 (Batch Size) → [PARALLEL]
Agent 5 (Integration) → [PARALLEL - reads tmp/ outputs from others]
重要な原則:調査エージェント(1~4)間に依存関係はありません。統合エージェントが調査結果を総合します。
動的な Todo 管理:
- 調査計画(5 つのエージェント)から開始する
- 複数の Task ツール呼び出しを 1 つのメッセージに含め、エージェントを並列で起動する
- 各エージェントの完了に合わせて Todo を更新する
- 統合エージェントは、すべての調査結果がそろうまで総合分析を待つ
3. プロファイリングスクリプトの構成
各エージェントが作成するもの:
- 調査スクリプト(例:
profile_pipeline.py)- フェーズ境界での time.perf_counter() による計測
- tracemalloc によるメモリプロファイリング
- 構造化された出力(フェーズ、所要時間、全体に占める割合)
- レポート(調査結果、推奨事項、影響の定量化をまとめた Markdown)
- 証拠(ベンチマーク結果、設定ダンプ、API トレース)
プロファイリングコードの例:
import time
# Profile multi-stage pipeline
def profile_pipeline():
results = {}
# Phase 1: Download
start = time.perf_counter()
data = download_from_cdn(url)
results["download"] = time.perf_counter() - start
# Phase 2: Extract
start = time.perf_counter()
csv_data = extract_zip(data)
results["extract"] = time.perf_counter() - start
# Phase 3: Parse
start = time.perf_counter()
df = parse_csv(csv_data)
results["parse"] = time.perf_counter() - start
# Phase 4: Ingest
start = time.perf_counter()
ingest_to_db(df)
results["ingest"] = time.perf_counter() - start
# Analysis
total = sum(results.values())
for phase, duration in results.items():
pct = (duration / total) * 100
print(f"{phase}: {duration:.3f}s ({pct:.1f}%)")
return results
4. 影響度の定量化フレームワーク
優先度レベル:
- P0(重大):5 倍超の改善。主要なボトルネックに対処する
- P1(高):2~5 倍の改善。二次的な最適化
- P2(中):1.2~2 倍の改善。すぐに実施できる効果的な改善
- P3(低):1.2 倍未満の改善。軽微な調整
影響レポートの形式:
### Recommendation: [Optimization Name] (P0/P1/P2) - [IMPACT LEVEL]
**Impact**: 🔴/🟠/🟡 **Nx improvement**
**Effort**: High/Medium/Low (N days)
**Expected Improvement**: CurrentK → TargetK rows/sec
**Rationale**:
- [Why this matters]
- [Supporting evidence from profiling]
- [Comparison to alternatives]
**Implementation**:
[Code snippet or architecture description]
5. 合意形成パターン
統合エージェントの責務:
- すべての調査レポートを読む(エージェント 1~4)
- 合意された推奨事項を特定する(すべてのエージェントが賛同)
- 見解の相違を明示する(エージェント間で意見が異なる)
- 統合レポートを作成する
- 実装ロードマップを作成する(P0 → P1 → P2)
合意の基準:
- 4 エージェント中 3 以上が同じ最適化を推奨 → 合意
- 4 エージェント中 2 が推奨し、2 が中立 → さらに調査
- エージェント間で見解が矛盾する(あるエージェントは「X を最適化する」と述べ、別のエージェントは「X はボトルネックではない」と述べる)→ 判定実験を実施
ワークフロー:手順ごとの説明
ステップ 1:パフォーマンスの問題を定義する
入力:SLO を下回るパフォーマンス指標 出力:ベースライン指標を含む問題の説明
問題の説明の例:
Performance Issue: BTCUSDT 1m ingestion at 47K rows/sec
Target SLO: >100K rows/sec
Gap: 53% below target
Pipeline: CloudFront download → ZIP extract → CSV parse → QuestDB ILP ingest
ステップ 2:調査計画を作成する
ディレクトリー構成:
tmp/perf-optimization/
profiling/ # Agent 1
profile_pipeline.py
PROFILING_REPORT.md
questdb-config/ # Agent 2
CONFIG_ANALYSIS.md
python-client/ # Agent 3
CLIENT_ANALYSIS.md
batch-size/ # Agent 4
BATCH_ANALYSIS.md
MASTER_INTEGRATION_REPORT.md # Agent 5
エージェントの割り当て:
- エージェント 1:実測プロファイリング(インストルメンテーション)
- エージェント 2:データベース構成の分析
- エージェント 3:クライアントライブラリーの使用状況分析
- エージェント 4:バッチサイズ最適化の分析
- エージェント 5:統合と取りまとめ
ステップ 3:エージェントを並列で起動する
重要:真の並列処理を実現するには、複数の Task ツール呼び出しを 1 つのメッセージで行います。
例:
I'm going to spawn 5 parallel investigation agents:
[Uses Task tool 5 times in a single message]
- Agent 1: Profiling
- Agent 2: QuestDB Config
- Agent 3: Python Client
- Agent 4: Batch Size
- Agent 5: Integration (depends on others completing)
実行:
# All agents run simultaneously (user observes 5 parallel tool calls)
# Each agent writes to its own tmp/ subdirectory
# Integration agent polls for completed reports
ステップ 4:すべてのエージェントが完了するまで待つ
進捗の追跡:
- 各エージェントの完了に合わせて todo リストを更新します。
- 統合エージェントは
tmp/ディレクトリーを確認し、レポートファイルを探します。 - 4 件すべての調査レポートがそろったら、統合エージェントが結果をまとめます。
完了条件:
- 4 件すべての調査レポートが作成されている
- 統合レポートに調査結果がまとめられている
- 推奨事項のマスターリストが作成されている
ステップ 5:統合レポートのマスター版を確認する
レポートの構成:
# Master Performance Optimization Integration Report
## Executive Summary
- Critical discovery (what is/isn't the bottleneck)
- Key findings from each agent (1-sentence summary)
## Top 3 Recommendations (Consensus)
1. [P0 Optimization] - HIGHEST IMPACT
2. [P1 Optimization] - HIGH IMPACT
3. [P2 Optimization] - QUICK WIN
## Agent Investigation Summary
### Agent 1: Profiling
### Agent 2: Database Config
### Agent 3: Client Library
### Agent 4: Batch Size
## Implementation Roadmap
### Phase 1: P0 Optimizations (Week 1)
### Phase 2: P1 Optimizations (Week 2)
### Phase 3: P2 Quick Wins (As time permits)
ステップ 6:最適化を実施する(P0 から)
推奨事項ごとに、以下を行います。
- 最も優先度の高い最適化(P0)を実施します。
- プロファイリングスクリプトを再実行します。
- 期待した改善が得られたことを確認します。
- 実際の結果でレポートを更新します。
- 次の優先度(P1、P2、P3)に進みます。
実施例:
# Before optimization
uv run python tmp/perf-optimization/profiling/profile_pipeline.py
# Output: 47K rows/sec, download=857ms (90%)
# Implement P0 recommendation (concurrent downloads)
# [Make code changes]
# After optimization
uv run python tmp/perf-optimization/profiling/profile_pipeline.py
# Output: 450K rows/sec, download=90ms per symbol * 10 concurrent (90%)
実例:QuestDB リファクタリングのパフォーマンス調査
背景:パイプラインの処理能力は 47K 行/秒で、目標の 100K 行/秒を 53% 下回っています(SLO 未達)。
調査前の想定:
- QuestDB の ILP 取り込みがボトルネックである(処理時間の 4%)。
- データベース構成の調整が必要である。
- Sender API の使用方法を最適化する必要がある。
5 エージェントによる調査後の結果:
- プロファイリングエージェント:CloudFront からのダウンロードが処理時間の 90%(857ms)を占め、ILP 取り込みはわずか 4%(40ms)です。
- QuestDB 構成エージェント:データベースはすでに最適な状態で、調整による改善は 5% 未満です。
- Python クライアントエージェント:Sender API はすでに最適に使用されています(dataframe() による一括取り込みを使用)。
- バッチサイズエージェント:44K のバッチサイズは最適な範囲内です。
- 統合エージェント:全員の推奨事項は一致しており、最適化すべきなのはデータベースではなくダウンロードです。
主な推奨事項 3 件:
- 🔴 P0:複数シンボルの同時ダウンロード(10~20 倍の改善)
- 🟠 P1:複数月分のパイプライン並列処理(2 倍の改善)
- 🟡 P2:ZIP ファイルのストリーミング展開(1.3 倍の改善)
影響:データベースの取り込み速度が 110 万行/秒(目標の 11 倍)であることが判明し、データベースがボトルネックではなかったことが実証されました。
結果:本当のボトルネックはダウンロードだったため、データベースの最適化に 2~3 週間を費やすことを回避できました。
よくある落とし穴
1. 1 つのレイヤーだけをプロファイリングする
❌ よくない例:データベースだけをプロファイリングし、そこがボトルネックだと決めつける ✅ よい例:パイプライン全体(ダウンロード → 展開 → 解析 → 取り込み)をプロファイリングする
2. エージェントを順番に実行する
❌ よくない例:エージェント 1 を実行して待ち、次にエージェント 2 を実行して待つ、という手順を繰り返す ✅ よい例:複数の Task 呼び出しを 1 つのメッセージで行い、5 つのエージェントをすべて並列で起動する
3. プロファイリングせずに最適化する
❌ よくない例:「まずデータベース構成を最適化しましょう」(想定に基づく) ✅ よい例:まずプロファイリングを行い、データベースが処理時間のわずか 4% しか占めていないと判明したら、代わりにダウンロードを最適化する
4. すぐにできる改善を見逃す
❌ よくない例:P0(効果も労力も最大)だけを実施する ✅ よい例:P0 の計画を進めながら、P2 の手軽な改善(4~8 時間の作業で 1.3 倍)を実施する
5. 変更後に再プロファイリングしない
❌ よくない例:最適化を実施し、効果があったと決めつける ✅ よい例:プロファイリングスクリプトを再実行し、期待した改善が得られたことを確認する
リソース
scripts/
該当なし。プロファイリングスクリプトはプロジェクトごとに異なり、tmp/perf-optimization/ に保存されています。
references/
profiling_template.py- フェーズ境界のインストルメンテーション用テンプレートintegration_report_template.md- 統合レポートのマスター版用テンプレートimpact_quantification_guide.md- P0/P1/P2 の優先度を評価する方法
assets/
該当なし — プロファイリングの成果物はプロジェクト固有です
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| エージェントが順番に実行される | 個別のメッセージを使用している | 複数の Task を使い、1 つのメッセージですべてのエージェントを起動します |
| 統合レポートが空 | エージェントのレポートが書き込まれていない | 4 つの調査エージェントがすべて完了するまで待ちます |
| ボトルネックの特定が誤っている | 単一レイヤーのプロファイリング | 想定したレイヤーだけでなく、パイプライン全体をプロファイリングします |
| プロファイリング結果にばらつきがある | ウォームアップ実行がない | 測定前に 3~5 回のウォームアップ反復を実行します |
| メモリがプロファイリングされていない | tracemalloc がない | プロファイリングスクリプトに tracemalloc の計測を追加します |
| P0/P1 の優先度が不明確 | 影響が定量化されていない | 各所見に予想される N 倍の改善を記載します |
| コンセンサスがない | エージェントが比較されていない | 統合エージェントが 4 つすべてのレポートを統合する必要があります |
| 再プロファイリングで変化が見られない | キャッシュの影響 | キャッシュをクリアし、サービスを再起動してから再プロファイリングします |
実行後の振り返り
このスキルの完了後、タスクを終了する前に振り返ります。
- 現在の場所を確認します。 — 編集する前に、この SKILL.md の正式なパスを確認します。
- 何が失敗しましたか? — 原因となった指示を修正します。
- 予想以上にうまくいったことは何ですか? — 推奨されるプラクティスとして取り入れます。
- 何が現状とずれていましたか? — 現状に合わなくなったスクリプト、参照先、依存関係を修正します。
- 記録します。 — 発生のきっかけ、修正内容、証拠を含む進化ログのエントリーを作成します。
先送りしないでください。次回の実行には、ここに残したものが引き継がれます。