openclaw-test-performance について
openclaw-test-performanceは、OpenClawのテストスイートやplugin-inspectorの速度とメモリ使用量を改善するスキルです。カバレッジを維持しながら、計測したベースラインと根本原因の修正、変更前後の検証を行います。
主な機能
- 01実行時間とメモリのベースライン計測
- 02テストとインポートのボトルネック分析
- 03プラグインスイートの性能改善手順
- 04カバレッジを保つ根本原因の修正
- 05変更前後のベンチマーク
活用シーン
- 01遅いテストファイルの調査
- 02plugin-inspectorのインポート負荷削減
- 03拡張機能テストのメモリ使用量計測
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ openclaw/ openclaw --skill openclaw-test-performanceインストール後、Claude Code で/openclaw-test-performanceを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
OpenClaw テストのパフォーマンス
まず証拠を確認します。目標は、推測でランナーを調整することではなく、カバレッジを維持したまま、実際の pnpm test、プラグインスイート、プラグインインスペクターの速度と RSS を改善することです。
ワークフロー
- 編集前に、関連するローカルの
AGENTS.mdファイルを読みます。- エージェントやインポートのホットスポットについては
src/agents/AGENTS.md。 - プラグインやチャネルの遅延読み込みについては
src/channels/AGENTS.mdとsrc/plugins/AGENTS.md。 - サーバーのライフサイクルテストについては
src/gateway/AGENTS.md。 - 共通のコントラクトヘルパーについては
test/helpers/AGENTS.mdとsrc/channels/plugins/contracts/test-helpers/AGENTS.md。 - 送信/メディア/アクションのテストについては
src/infra/outbound/AGENTS.md。
- エージェントやインポートのホットスポットについては
- コードを変更する前にベースラインを確立します。
- スイート全体のランキングには、
pnpm test:perf:groups --full-suite --allow-failures --output <file>を優先します。 - プラグインを幅広く含むテストでは、拡張機能全体を一気に実行する前に、関連する最小範囲の
pnpm test:extensions:batch <plugin[,plugin...]>またはプラグインインスペクターのコマンドを実行します。 - 対象を絞ったホットスポットには、次を使用します。
/usr/bin/time -l pnpm test <file-or-files> --maxWorkers=1 --reporter=verbose - インポートが重いと考えられる場合は、次を追加します。
OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1。
- スイート全体のランキングには、
- 実時間やランナーのノイズと、実際のファイルのコストを切り分けます。
- Vitest の所要時間、テスト本体の実行時間、インポートの内訳、実時間、最大 RSS を比較します。
- グループ実行やスイート全体の数値が古い、またはノイズを含むように見える場合は、単一ファイルを再実行します。
- スイート全体のグループ実行でレーンの失敗が報告されたものの、JSON ではテストが成功している場合は、ハーネスの問題/ノイズとして記録し、該当するファイルを直接検証します。
- 効果とリスクに基づいて、次に取り組む対象を選びます。
- 効果が高いもの:1 つのファイル/テストが実行時間や RSS の大部分を占めており、原因が明確なもの。
- 波及効果が高いもの:1 つのプラグインまたは SDK のバレルにより、すべてのプラグインインスペクター実行や拡張機能バッチ実行で広範なランタイムが読み込まれるもの。
- リスクが低いもの:静的記述子、ターゲット解析、ルーティング、認証バイパス、セットアップのヒント、レジストリのフィクスチャ、テストサーバーのライフサイクル。
- リスクが高いもの:実際のメモリ/ランタイム動作、ライブプロバイダー、プロトコルコントラクト、広範な本番コードのリファクタリング。
- 症状ではなく根本原因を修正します。
- 静的メタデータや解析処理を、フルランタイムと高速処理の両方で再利用できる、対象を絞ったヘルパーまたは軽量アーティファクトに移します。
- 広範なモックより、依存性注入、読み込み済みプラグインのみを対象とする検索、明示的なフィクスチャ、純粋なヘルパーを優先します。
- 新しいハンドシェイクに意味がない場合は、スイートレベルのサーバー/クライアントを再利用します。
- テストでスケジューリングを検証しない限り、スケジューラーやバックグラウンドループは無効にします。
- プラグイン関連の処理では、静的メタデータをマニフェスト/軽量アーティファクトに移し、ランタイムプラグインの読み込みを明示的な実行境界の内側に保ちます。
- カバレッジの形を維持します。
- 遅い統合テストの証明は、まったく同じ本番コードの構成を名前付きヘルパーとして切り出してテストしない限り、削除しません。
- コンポーネント間の接続が重要な場合は、軽量な統合スモークテストを 1 つ残します。
- 偶発的なカバレッジを削除した場合は、その内容を明記します。
- 変更後に同じコマンドで再ベンチマークし、秒数と改善率を算出します。
- 依頼された場合、またはこのスレッドで進捗レポートを管理している場合は、進行中のレポートを更新します。変更前後のコマンド、アーティファクト、カバレッジに関する注記、検証結果、次に取り組む順序を含めます。
- 意図したパスだけをステージし、標準の Git 手順でコミットして、ユーザーからコミット/プッシュを依頼された場合はプッシュします。この対応で変更したファイルだけをステージします。
プラグインスイートのワークフロー
パフォーマンス作業がバンドルされたプラグイン、plugin-inspector、SDK のバレル、パッケージ境界テスト、または拡張機能スイートに関わる場合は、このセクションを使用します。
- まずスイートの構成を把握します。
- ソーステスト:
pnpm test extensions/<id>またはpnpm test:extensions:batch <id> - パッケージ境界:
pnpm run test:extensions:package-boundary:canaryおよびpnpm run test:extensions:package-boundary:compile - バンドルされたすべてのソーステスト:
pnpm test:extensions - プラグインのインポートメモリ:
pnpm test:extensions:memory -- --json .artifacts/test-perf/extensions-memory.json - plugin-inspector/レポートの作業:レポートのプリミティブは
plugin-inspectorに保持します。 ラッパーは薄く保ち、コマンドが対応している場合はピーク RSS を収集します。
- ソーステスト:
- 対象を絞ってから範囲を広げます。
- 変更したプラグインが 1 つの場合:そのプラグインのテストと plugin-inspector の対象部分を実行します。
- SDK/公開バレルを変更した場合:代表的なプロバイダー、チャネル、メモリ、 および機能プラグインを追加します。
- ローダー/ランタイムのミラーを変更した場合:必要に応じてパッケージ境界チェックとビルド/パッケージの検証を追加します。
- 共有プラグインの動作が不明な場合:
pnpm test:extensionsの前にtest:extensions:batchグループを実行します。
- plugin-inspector の失敗は、製品に関するシグナルとして扱います。
- JSON を解析できる必要があります。
- 警告/エラーは隠さず、分類する必要があります。
- ランタイムのキャプチャは静かに行い、設定の違いを許容する必要があります。
- コマンド出力には、取得可能な場合、実時間、終了コード、ピーク RSS を含める必要があります。
- ホストの選択には
$openclaw-testingを使用します。信頼できるソースベンチマークは、マシンと負荷の条件を比較可能にしてローカルで実行できます。クリーンなパッケージング、Linux/プラットフォームの動作、分離、または明示的なリモート実行の依頼が検証に含まれる場合は$crabboxを使用し、自分が所有するリースのみ再利用してクリーンアップします。 - プラグインのパフォーマンスがパッケージアーティファクトの影響を受ける場合は、ソースのみの計測を信用せず、
release-openclaw-plugin-testingと Package Acceptance に切り替えます。
メトリクスの収集
前後で少なくとも 1 つの安定したメトリクスを収集します。同じマシンと同じコマンドを使用することを優先します。Testbox の比較では、可能であれば同じ tbx_... ID を使用します。
| メトリクス | 用途 | 推奨ソース |
|---|---|---|
| 実時間 | ユーザーに見えるスイートのコスト | /usr/bin/time -l、テストラッパーの実行時間、Testbox の実行時間 |
| Vitest の実行時間 | テスト本体/インポートのコスト | ファイル/シャードごとの Vitest 出力 |
| インポート時間 | 広範なバレル/ランタイムの読み込み | OPENCLAW_VITEST_IMPORT_DURATIONS=1 |
| 最大 RSS | メモリ負荷と OOM のリスク | /usr/bin/time -l、pnpm test:extensions:memory、ラッパーのメモリサマリー |
| CPU/user/sys | CPU 負荷と待機負荷の区別 | ローカルでは /usr/bin/time -l、ローカルの CPU が不安定な場合は Testbox のジョブ計測 |
| ヒープの証拠 | 実際のリークと保持されたモジュールグラフの区別 | openclaw-test-heap-leaks ワークフロー |
CPU/RSS を含む、対象を絞ったローカルコマンド:
timeout 240 /usr/bin/time -l pnpm test <file> --maxWorkers=1 --reporter=verbose
プラグインのインポートメモリプロファイル:
pnpm build
pnpm test:extensions:memory -- --top 20 --json .artifacts/test-perf/extensions-memory.json
対象を絞ったプラグインのインポートメモリ:
pnpm test:extensions:memory -- --extension discord --extension telegram --skip-combined
ヒープ/RSS のエスカレーション:
pnpm test:perf:groups \
--config test/vitest/vitest.unit-fast.config.ts \
--allow-failures \
--output .artifacts/test-perf/unit-fast-memory.json
pnpm test:perf:profile:runner -- \
--output-dir .artifacts/test-perf/vitest-runner-profile -- <file>
RSS が間隔を空けて増加し続ける場合、ワーカーが OOM になる場合、または疑わしいコマンドでアプリオブジェクトが保持されている場合は、openclaw-test-heap-leaks を使用します。スナップショットまたはリテイナーによる裏付けが得られるまでは、RSS の増加をリークと断定しないでください。
よくある根本原因
- 静的データに対して、チャネル/プラグインのランタイム全体がバンドルされた状態で読み込まれている。
- すでに読み込まれたフィクスチャや純粋なパーサーで十分なのに、
getChannelPlugin()のフォールバックが使われている。 api.ts、runtime-api.ts、test-api.ts、または plugin-sdk のバレルが、負荷の高いテストに取り込まれている。- SDK のルートエイリアスやパッケージバレルが、特化したサブパスを広範なプラグイングラフに取り込んでいる。
- plugin-inspector が、メタデータ、レポート、CI ポリシーのスコアを表示するだけなのに、ランタイムコードを読み込んでいる。
- バンドルされたプラグインのキャプチャで、合成された、秘匿化済みの分離された状態ではなく、実際の config/home 状態が再利用されている。
- 部分的な実物モックで、広範なモジュールを囲むように
importActual()が使われている。 - テストごとのループで、
vi.resetModules()と新しいインポートが併用されている。 - テストプラグインレジストリが
beforeAllでシードされる一方、ランタイム状態はafterEachでリセットされている。 - 状態のリセットで十分なのに、テストごとにゲートウェイ/サーバー/クライアントを起動している。
- アイドル状態のスナップショットやフィクスチャで、ランタイム/デフォルトのモデル/認証の選択処理が実行されている。
- 引数にプラグイン所有のフィールドが含まれるか確認する前に、プラグイン所有のメディア/アクションの検出が実行されている。
- 並列の Vitest 実行で、異なる
OPENCLAW_VITEST_FS_MODULE_CACHE_PATHの値を設定せずにnode_modules/.experimental-vitest-cacheを共有している。
ベンチマークコマンド
対象ファイル:
timeout 240 /usr/bin/time -l pnpm test <file> --maxWorkers=1 --reporter=verbose
インポート内訳付きの対象ファイル:
timeout 240 /usr/bin/time -l env \
OPENCLAW_VITEST_IMPORT_DURATIONS=1 \
OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 \
pnpm test <file> --maxWorkers=1 --reporter=verbose
グループ化したスイート:
pnpm test:perf:groups --full-suite --allow-failures \
--output .artifacts/test-perf/<name>.json
拡張機能バッチ:
pnpm test:extensions:batch <plugin[,plugin...]> -- --reporter=verbose
すべての拡張機能テスト:
pnpm test:extensions
パッケージ境界のプラグインチェック:
pnpm run test:extensions:package-boundary:canary
pnpm run test:extensions:package-boundary:compile
既存の Vitest JSON レポートを再利用:
pnpm test:perf:groups --report <vitest-json> \
--output .artifacts/test-perf/<name>.json
検証
- 変更を証明できる対象テストを必ず実行してください。
- ソースの変更:プッシュ前に、対象を絞ったローカルテストと、対象を絞った型チェック/lint/フォーマットを実行してください。
pnpm check:changedは任意です。PR CI が広範な検証になります。Testbox は CI/ローカルで確認できない部分がある場合にのみ使用し、即座に付与してください。選択した場合は、ウォームアップ済みの Testbox を再利用してください。 - テストのみの変更では、
pnpm test:changedまたは編集したテストを正確に指定して実行してください。 - 遅延読み込み、バンドル成果物、パッケージ境界、動的インポート、ビルド出力、またはパブリックサーフェスに触れる場合は、
pnpm buildを実行してください。 - プラグイン SDK/バレル/ランタイムの変更では、パブリック API サーフェスに差異が生じる可能性がある場合、
pnpm plugin-sdk:api:diff -- --base <base-sha> --head <head-sha>で正確なコミットを比較してください。PR 内での検証では、<base-sha>にブランチのマージベースを、<head-sha>にテストした正確なヘッドコミットを指定してください。 - プラグインスイートのパフォーマンス修正では、代表的なプラグインバッチを少なくとも 1 つと、変更したゲートを検証してください。バグがパッケージ化された成果物でのみ発生する場合は、Package Acceptance を使用してください。
- 依存関係が欠落している、または古い場合は、
pnpm installを実行して、失敗したコマンドを 1 回だけ再試行してください。 - 次のレポート形式を使用してください:
| Metric | Before | After | Gain |
| -------------- | -----: | -----: | ------------: |
| File wall time | `Xs` | `Ys` | `-Zs` (`P%`) |
| Max RSS | `XMB` | `YMB` | `-ZMB` (`P%`) |
| CPU user/sys | `X/Ys` | `A/Bs` | explain |
引き継ぎ
最終報告は簡潔にしてください:
- 根本原因。
- スイート/プラグインの対象範囲。
- 変更したファイル。
- 可能な場合は、実行時間、Vitest/インポート、CPU、RSS の変更前/変更後の数値。
- メモリが関係する場合は、リークの分類:実際のリーク、保持されたモジュールグラフ、または判断不能。
- 維持したカバレッジ。
- 検証コマンド。
- リモートで検証した場合は、Testbox ID またはワークフロー URL。
- コミットハッシュとプッシュ状況。