mcpField
S
simulation-orchestrator

simulation-orchestrator

github.com/heshamfs数据与数据库83221 次安装1 周前更新
代码仓库

关于 simulation-orchestrator

simulation-orchestrator 是一项用于管理模拟运行批次的 Python 技能,可生成参数扫描配置、跟踪作业状态,并使用标准库汇总已完成运行的结果。

主要功能

  1. 01生成网格、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(指数级)
linspace一维扫描、均匀间隔每个参数 n 个
lhs高维、空间填充用户指定的预算
批次规模指南
参数数量每个参数的网格点数总运行次数建议
11010使用网格即可
210100网格可接受
3101,000考虑使用 LHS
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 进行参数扫描。我想尝试 5 个介于 1e-4 和 1e-2 之间的 dt 值,以及 4 个介于 0.1 和 1.0 之间的 kappa 值。

Agent 工作流:

  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 或汇总统计数据之前,请为以下每一项记录具体证据:

  • 确认扫描的键路径确实改变了求解器读取的值:打开至少一个生成的 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 是随机的,所以没必要记录任何东西。”只有固定 --seed,LHS 才能复现。如果不记录种子(以及 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 会验证命令模板,拒绝 shell 链接运算符(;、|、&、反引号、$)
  • --params 格式字符串会经过解析和验证(格式为 name:min:max:count,数值边界必须有限——拒绝 NaN/Inf——且 min < max,计数必须为正整数且不超过 100,000);每次扫描最多允许 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)
  • 结果文件中的所有字符串值在显示前都会经过清理(截断并移除控制字符)
  • 插入 shell 命令的配置路径会根据安全字符允许列表进行验证,并使用 shlex.quote() 转义
工具限制
  • Read:用于检查脚本源代码、参考资料、基础配置和活动状态文件
  • Write:用于保存生成的扫描配置、活动清单和汇总结果;写入范围仅限于用户的工作目录
  • Grep/Glob:用于定位活动文件、结果文件和搜索参考资料
  • 该技能的 allowed-tools 不包含 Bash,以防 Agent 在处理不可信的模拟输出时执行任意命令
安全措施
  • 不使用 eval()、exec() 或动态代码生成
  • 所有子进程调用均使用显式参数列表(不使用 shell=True)
  • 缩减工具范围(不包含 Bash),将 Agent 限制为仅执行读写操作
  • 命令模板会经过验证,但技能本身绝不会执行;执行由用户负责

限制

  • 不是作业调度器:不会向 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):首次发布,包含扫描、活动、跟踪和汇总功能

评论

支持 Markdown