mcpField
S
simulation-orchestrator

simulation-orchestrator

github.com/heshamfsデータ・データベース83221 回インストール1 週間前に更新
リポジトリ

simulation-orchestrator について

simulation-orchestratorは、シミュレーション実行キャンペーンを管理するPythonスキルです。標準ライブラリを使い、パラメータスイープ用設定の生成、ジョブ状況の追跡、完了結果の集計を行います。

主な機能

  1. 01grid、linspace、LHSスイープの生成
  2. 02シミュレーションキャンペーンの初期化と管理
  3. 03ジョブ状況と進捗の追跡
  4. 04指標と実行結果の集計
  5. 05指標の方向に応じた最良実行の特定

活用シーン

  1. 01パラメータ調査用の設定作成
  2. 02シミュレーションキャンペーンのジョブ監視
  3. 03完了した実行を結果指標で比較
  4. 04指標の最小値または最大値を選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/heshamfs/materials-simulation-skills --skill simulation-orchestrator

インストール後、Claude Code で/simulation-orchestratorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CHANGELOG.md
evals/
evals.json
evals/files/
config.json
simulation.json
evals/files/case3_init/
config_0000.json
config_0001.json
config_0002.json
config_0003.json
manifest.json
evals/files/case3_status/
campaign.json
evals/files/case4_campaign/
campaign.json
config_0000.json
config_0001.json
config_0002.json
result_job_0000.json
result_job_0001.json
result_job_0002.json
references/
aggregation_methods.md
campaign_patterns.md
sweep_strategies.md
scripts/
campaign_manager.py
job_tracker.py
result_aggregator.py
sweep_generator.py

詳細

シミュレーションオーケストレーター

目標

複数のシミュレーションキャンペーンを管理するツールを提供します。パラメーターのスイープを生成し、ジョブの実行状況を追跡し、完了した実行の結果を集約します。

要件

  • Python 3.10+
  • 外部依存関係なし(Python 標準ライブラリのみを使用)
  • Linux、macOS、Windows で動作します

収集する入力

オーケストレーションスクリプトを実行する前に、ユーザーから以下を収集してください。

入力説明例
基本設定シミュレーション設定のテンプレートbase_config.json
パラメーター範囲範囲を指定してスイープするパラメーターdt:[1e-4,1e-2],kappa:[0.1,1.0]
スイープ方法パラメーター空間のサンプリング方法grid、lhs、linspace
出力ディレクトリキャンペーンファイルの保存先./campaign_001
シミュレーションコマンド各シミュレーションを実行するコマンドpython sim.py --config {config}

判断の指針

スイープ方法の選択
Need every combination (full factorial)?
├── YES → Use grid (warning: exponential growth with parameters)
└── NO → Is space-filling coverage needed?
    ├── YES → Use lhs (Latin Hypercube Sampling)
    └── NO → Use linspace for uniform sampling per parameter
方法最適な用途サンプル数
grid低次元(1~3)、正確な端点が必要n^d(指数関数的)
linspace1D スイープ、均等な間隔パラメーターごとに n
lhs高次元、空間充填型ユーザー指定の予算
キャンペーン規模の目安
パラメーター数各グリッドの点数実行総数推奨
11010グリッドで問題ありません
210100グリッドで対応できます
3101,000LHS を検討してください
4+1010,000+LHS または DOE を使用してください

スクリプトの出力(JSON フィールド)

スクリプト出力フィールド
scripts/sweep_generator.pyconfigs、parameter_space、sweep_method、total_runs
scripts/campaign_manager.py --action initcampaign_id、total_jobs、config_dir、command_template
scripts/campaign_manager.py --action statuscampaign_id、status、jobs、progress、total_jobs、created_at
scripts/campaign_manager.py --action listjobs(ジョブレコードの配列)
scripts/job_tracker.pyjob_id、status、start_time、end_time、exit_code
scripts/result_aggregator.pysummary(minimize を含む)、statistics、best_run、failed_runs

スイープするパラメーター名に関する注意:sweep_generator.py は、スイープする各値をキーのパスに従って基本設定に書き込みます。単独の名前(例:kappa)はトップレベルのキーを上書きし、ドット表記の名前(例:parameters.kappa)はネストされたキーを対象にします。スイープするキーのパスは、ソルバーが値を読み取る場所と一致している必要があります。parameters.kappa がネストされた設定に対して kappa をスイープすると、使用されないトップレベルのキーが追加され、基本設定の値がそのまま使われます。references/sweep_strategies.md を参照してください。

ワークフロー

ステップ 1:パラメータースイープの生成

すべてのパラメーターの組み合わせに対する設定を作成します。

python3 scripts/sweep_generator.py \
    --base-config base_config.json \
    --params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \
    --method linspace \
    --output-dir ./campaign_001 \
    --json
ステップ 2:キャンペーンの初期化

キャンペーン追跡構造を作成します。

python3 scripts/campaign_manager.py \
    --action init \
    --config-dir ./campaign_001 \
    --command "python sim.py --config {config}" \
    --json
ステップ 3:ジョブ状況の追跡

実行中のジョブを監視します。

python3 scripts/job_tracker.py \
    --campaign-dir ./campaign_001 \
    --update \
    --json
ステップ 4:結果の集約

完了した実行の結果をまとめます。

python3 scripts/result_aggregator.py \
    --campaign-dir ./campaign_001 \
    --metric final_energy \
    --json

result_aggregator.py はデフォルトで最小化します。best_run はメトリック値が最も低い実行です(summary.minimize は true です)。より高い値が望ましい場合(例:収率、精度、スループット)は、--maximize を渡すと、best_run は値が最も高い実行になります。

# Higher is better -> select the maximum
python3 scripts/result_aggregator.py \
    --campaign-dir ./campaign_001 \
    --metric yield \
    --maximize \
    --json

判断の指針:より高い値が望ましい場合(収率、精度、スループット)は --maximize を渡してください。それ以外の場合、報告される best_run は最小値になります。

CLI の例

# Generate 5x3=15 runs varying dt (5 values) and kappa (3 values)
python3 scripts/sweep_generator.py \
    --base-config sim.json \
    --params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \
    --method linspace \
    --output-dir ./sweep_001 \
    --json

# Generate LHS samples for 4 parameters with budget of 20 runs
python3 scripts/sweep_generator.py \
    --base-config sim.json \
    --params "dt:1e-4:1e-2,kappa:0.1:1.0,M:1e-6:1e-4,W:0.5:2.0" \
    --method lhs \
    --samples 20 \
    --output-dir ./lhs_001 \
    --json

# Check campaign status
python3 scripts/campaign_manager.py \
    --action status \
    --config-dir ./sweep_001 \
    --json

# List jobs (read-only), optionally filtered by status
python3 scripts/campaign_manager.py \
    --action list \
    --config-dir ./sweep_001 \
    --status-filter failed \
    --json

# Get summary statistics from completed runs (minimize: best = lowest)
python3 scripts/result_aggregator.py \
    --campaign-dir ./sweep_001 \
    --metric final_energy \
    --json

# Maximization metric: best = highest value (yield, accuracy, throughput)
python3 scripts/result_aggregator.py \
    --campaign-dir ./sweep_001 \
    --metric yield \
    --maximize \
    --json

会話形式のワークフロー例

ユーザー:フェーズフィールドシミュレーションで、dt と kappa のパラメータースイープを実行したいです。dt は 1e-4 から 1e-2 の間で 5 個、kappa は 0.1 から 1.0 の間で 4 個の値を試したいです。

エージェントのワークフロー:

  1. 実行総数を計算:5 x 4 = 20 回
  2. スイープ設定を生成:
    python3 scripts/sweep_generator.py \
        --base-config simulation.json \
        --params "dt:1e-4:1e-2:5,kappa:0.1:1.0:4" \
        --method linspace \
        --output-dir ./dt_kappa_sweep \
        --json
    
  3. キャンペーンを初期化:
    python3 scripts/campaign_manager.py \
        --action init \
        --config-dir ./dt_kappa_sweep \
        --command "python phase_field.py --config {config}" \
        --json
    
  4. ユーザーによるシミュレーション実行後、結果を集約:
    python3 scripts/result_aggregator.py \
        --campaign-dir ./dt_kappa_sweep \
        --metric interface_width \
        --json
    

エラー処理

エラー原因解決方法
Base config not foundファイルパスが無効ですベース設定ファイルが存在することを確認してください
Invalid parameter formatパラメーター文字列の形式が正しくありません形式 name:min:max:count または name:min:max を使用してください
Output directory exists上書きが発生します--force を使用するか、新しいディレクトリを選択してください
No completed jobs集計する結果がありませんジョブが完了するまで待つか、失敗がないか確認してください
Metric not found結果ファイルにフィールドがありません結果 JSON のメトリック名を確認してください

他のスキルとの統合

simulation-orchestrator は、他の simulation-workflow スキルと連携します。

parameter-optimization          simulation-orchestrator
        │                              │
        │ DOE samples ────────────────>│ Generate configs
        │                              │
        │                              │ Run simulations
        │                              │
        │<──────────────────────────── │ Aggregate results
        │                              │
        │ Sensitivity analysis         │
        │ Optimizer selection          │
一般的な組み合わせワークフロー
  1. parameter-optimization/doe_generator.py を使用してサンプル点を取得します
  2. simulation-orchestrator/sweep_generator.py を使用して設定ファイルを作成します
  3. シミュレーションを実行します(ユーザーの責任です)
  4. simulation-orchestrator/result_aggregator.py を使用して結果を収集します
  5. parameter-optimization/sensitivity_summary.py を使用して分析します

検証チェックリスト

キャンペーンの best_run や要約統計量を信頼する前に、各項目について具体的な証拠を記録してください。

  • スイープ対象のキーのパスによって、ソルバーが読み取る値が実際に変更されたことを確認しました。少なくとも1つの生成された config_NNNN.json を開き、スイープ対象パラメーター(例:parameters.kappa)が、重複した未使用のトップレベルキーではなく、想定された階層で想定どおりの値になっていることを確認しました(sweep_generator.py はキーのパスを使用して書き込みます)。
  • result_aggregator.py --json のジョブ集計を照合し、summary.total_jobs、summary.completed、summary.failed を記録して、completed + failed == total_jobs であることを確認しました。件数が一致しない場合、実行が(結果ファイルの欠落、または extract_metric が None を返したために)通知なしにスキップされています。無視せず、原因を調査してください。
  • completed > 0 であることを確認し、記録された summary.metric がソルバーによって実際に書き込まれるフィールドと一致することを確認しました。メトリックの誤記や欠落があると、extract_metric は None を返し、エラーなしで完了実行数がゼロになります。
  • summary.minimize を記録し、best_run を示す前に、意図した方向と一致することを確認しました(デフォルトは最小化です。収率/精度/スループットの場合は --maximize を使用します)。
  • job_tracker.py の「completed」を物理的な成功として扱っていません。結果ファイルの存在だけでジョブを完了と判定し、exit_code を 0 として記録するため、実際の終了ステータス/ソルバーログを別途確認し、ゼロ以外のコードや NaN/Inf 出力がないことを確認しました。
  • メトリック値に外れ値/妥当性チェック(例:references/aggregation_methods.md の Tukey 1.5x IQR)を適用し、best_run.value が、異常終了した実行による不自然な極値ではなく、物理的に妥当であることを確認しました。
  • LHS スイープの場合、使用した --seed を記録し、サンプルセットを再現できるように manifest.json(パラメーターの範囲、total_runs、parameter_space)を保存しました。

よくある落とし穴と誤った正当化

つい選びがちな近道それが誤りである理由/すべきこと
「ジョブトラッカーに完了と表示されているので、実行は成功しました。」job_tracker.py は結果ファイルが存在すると「完了」と判定し、exit_code を 0 に固定します。実際の終了コードは読み取りません。部分的な結果ファイルを書き出したクラッシュ実行も、正常に終了した実行と同じように見えます。ソルバーの実際の終了ステータスと出力の妥当性を確認してください。
「completed の数が多いので、結果はすべてそろっています。」結果ファイルがないジョブや、extract_metric で読み取れないメトリックを持つジョブは、completed にも failed にも数えられず、黙ってスキップされます。completed + failed と total_jobs を照合してください。差があれば、実行が失われています。
「集計で best_run が返されたので、それが最適値です。」デフォルトでは、アグリゲーターは最小化します。値が大きいほど良い場合は --maximize を渡さなければならず、そうしないと best_run は最悪の値になります。必ず summary.minimize を記録し、最適化の方向を確認してください。
「kappa をスイープしたので、実行ごとに値が変わります。」sweep_generator.py はキーのパスを使って値を書き込みます。ベース設定で値が parameters.kappa の下にネストされているのに、単独の名前 kappa をスイープすると、すべての設定で元のネストされた値が維持され、未使用のトップレベルキーが追加されます。このスイープには科学的な意味がありません。ソルバーが読み取る正確なドット区切りパスを指定してください。
「メトリック名はだいたい合っていれば十分です。」メトリック名に誤りがあるか、メトリックが存在しない場合、extract_metric はすべての実行で None を返すため、completed は 0 になり、統計情報も空になります。エラーも発生しません。メトリックがソルバーの出力フィールドと完全に一致することを確認してください。
「グリッドですべてを網羅できるので、すべてのパラメーターに使いましょう。」グリッドは n^d となり、指数関数的に増大します(パラメーター 4 個 × 10 で 10,000 回の実行)。4 次元以上では、予算を慎重に設定して lhs を使い、グリッドはパラメーター 1~3 個の場合に限って使用してください。
「LHS はランダムなので、何も記録する必要はありません。」LHS で再現性を得るには、--seed を固定する必要があります。シードと manifest.json を記録しないと、サンプルセットを再生成したり、その妥当性を示したりできません。

セキュリティ

入力の検証
  • メトリック名(result_aggregator.py --metric)は、巧妙に細工されたキーによるパストラバーサルやインジェクションを防ぐため、[a-zA-Z_][a-zA-Z0-9_.]* に照らして検証されます
  • スイープするパラメーター名(sweep_generator.py --params)は、[a-zA-Z_][a-zA-Z0-9_]*(.[a-zA-Z_][a-zA-Z0-9_]*)* に照らして検証されます(ネストされたキーにはドット表記を使用)。無効な名前は拒否されます
  • campaign_manager.py は、シェル連結演算子(;、|、&、バッククォート、$)を拒否するよう、コマンドテンプレートを検証します
  • --params の書式文字列は解析・検証されます(name:min:max:count。有限の数値境界を使用し、NaN/Inf は拒否されます。min < max であり、正の整数の個数は最大 100,000 です)。1 回のスイープで指定できるパラメーターは最大 32 個です
  • --method は固定の許可リスト(grid、linspace、lhs)に照らして検証されます
  • --samples は、上限(最大 1,000,000)以下の正の整数であることを検証されます
  • --action は固定の許可リスト(init、status、list)に照らして検証されます。読み取り専用の list アクションでは、--status-filter が pending、running、completed、failed のいずれかであることを検証します
ファイルアクセス
  • sweep_generator.py は、--base-config で指定された単一のベース設定ファイル(JSON)を読み込み、生成された設定を --output-dir に書き込みます
  • result_aggregator.py は、結果ファイルごとに 10 MB のファイルサイズ上限と JSON の最大ネスト深度を適用し、数値型を厳密に検証します(bool、NaN、Inf を拒否します)
  • 結果ファイル内のすべての文字列値は、表示する前にサニタイズされます(長さを切り詰め、制御文字を除去します)
  • シェルコマンドに埋め込まれる設定パスは、安全な文字の許可リストに照らして検証され、shlex.quote() でエスケープされます
ツールの制限
  • Read:スクリプトのソース、参照資料、ベース設定、キャンペーンのステータスファイルの確認に使用します
  • Write:生成したスイープ設定、キャンペーンマニフェスト、集計結果の保存に使用します。書き込み先はユーザーの作業ディレクトリに限定されます
  • Grep/Glob:キャンペーンファイルや結果ファイルの検索、参照箇所の検索に使用します
  • スキルのallowed-toolsでは、信頼できないシミュレーション出力を処理する際にエージェントが任意のコマンドを実行できないよう、Bashを除外しています
安全対策
  • eval()、exec()、動的コード生成は使用しません
  • すべてのサブプロセス呼び出しで明示的な引数リストを使用します(shell=Trueは使用しません)
  • ツールの範囲を縮小し(Bashなし)、エージェントの操作を読み取り/書き込みのみに制限しています
  • コマンドテンプレートは検証しますが、スキル自体では実行しません。実行はユーザーの責任です

制限事項

  • ジョブスケジューラーではありません:SLURM/PBSへのジョブ投入は行わず、設定の生成とステータスの追跡を行います
  • 並列実行には対応していません:ユーザーはシミュレーションを外部で実行する必要があります(GNU parallel、SLURMなどを使用できます)
  • ファイルベースの追跡:ステータスはファイルで追跡されます。データベースやリアルタイム監視はありません
  • ローカルファイルシステム:すべてのファイルにローカルマシンからアクセスできることを前提としています

参考資料

  • references/campaign_patterns.md - 一般的なキャンペーン構成
  • references/sweep_strategies.md - パラメータスイープの設計ガイド
  • references/aggregation_methods.md - 結果集計の手法

バージョン履歴

正式な日付入りの履歴については、CHANGELOG.mdを参照してください。概要:

  • v1.1.3 (2026-06-24):スクリプトの実際の動作に基づく「検証チェックリスト」と「よくある落とし穴と正当化」を追加(結果ファイルのみでの「完了」判定、読み取れないメトリクスのサイレントスキップ、デフォルトでの最小化、キー単位のパスマージの意味)
  • v1.1.1 (2026-06-23):sweep_generator.pyにドット記法によるネストした上書きを追加し、入力検証を強化(--paramsの名前/有限値/件数の上限、--samplesの範囲)。--maximizeとlistアクションを文書化し、「スクリプトの出力」表と使用例の数値を修正
  • v1.1.0 (2026-03-26):メタデータ、評価スイート、セキュリティレビュー、CHANGELOGを標準化
  • v1.0.0 (2026-02-25):スイープ、キャンペーン、追跡、集計機能を備えた初回リリース

コメント