simengine について
simengineは、JSON設定で不確実性をモデル化し、戦略を比較するモンテカルロ意思決定システムです。リスク制約、最適化、ベイズ更新、診断機能とローカルWeb UIを備えています。
主な機能
- 01JSONによるシミュレーション定義
- 02モンテカルロリスク分析
- 03安全制約とCVaR
- 04遺伝的アルゴリズムによる戦略最適化
- 05ベイズ推定によるパラメーター更新
- 06収束・感度分析
活用シーン
- 01不確実な入力に基づく結果の推定
- 02リスク上限を守る戦略の比較
- 03観測データによる仮定の更新
MCP 対応
MCP サーバーを介して、MCP クライアントからSimEngineのシミュレーションを利用できます。HTTP APIはインライン設定も受け付け、AIエージェント向けに構造化結果を返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
9掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| seed | integer | いいえ | 再現性を確保するための乱数シード(デフォルト:42) |
| config | object | いいえ | インラインのドメイン設定 JSON(ドメインファイル名の代わり) |
| domain | string | いいえ | ドメイン設定ファイル名(例:'saas_startup.json') |
| overrides | object | いいえ | 設定に適用するドットパス形式の上書き。例:{'parameters.close_rate.params.mode': 0.35} |
| n_simulations | integer | いいえ | 実行するシミュレーションの回数(デフォルト:設定から取得) |
詳細
SimEngine
特定のドメインに依存しないモンテカルロシミュレーションと意思決定インテリジェンスシステムです。
依存関係ゼロ。Python 標準ライブラリのみ。ローカルのウェブ UI。Python が動作する環境ならどこでも実行できます。
SimEngine は不確実性を、行動に移せる数値へと変換します。変数、ロジック、リスク許容度を JSON 設定で定義します。エンジンは何千もの未来をシミュレーションしてスコアを付け、求められれば、安全制約を守りながら最善の戦略へと進化させます。
不確実性を計算する電卓のようなものだと考えてください。
クイックスタート
# 1. Clone the repository
git clone <repo-url> ~/projects/simengine
cd ~/projects/simengine
# 2. Start the web UI
cd v3 && python3 server.py
# 3. Open your browser
# http://localhost:8420
これだけです。pip install も、Docker も、Node も、ビルド手順も不要です。必要なのは Python 3.8 以降だけです。
MCP サーバーとしてインストールする
uvx simengine-mcp
公式 MCP レジストリに掲載されています。 ホスト型のインストール不要エンドポイント:ウェイトリストに登録。
オプションのネイティブ高速化
デフォルトのエンジンは引き続き純粋な Python で動作します。メトリクスのリデューサー、軌跡の帯、リスク評価、ヒストグラム、単純な数値変数分布のネイティブ事前サンプリングをオプションで高速化するための Rust ワークスペースが、リポジトリのルートに追加されました。
これはオプトイン方式で、上記の基本的なワークフローは変わりません。
ワークスペースの構成
Cargo.toml
crates/
├── simengine-core/ # pure Rust numeric kernels
└── simengine-py/ # PyO3 extension module: simengine_native
v3/native.py # optional loader + Python fallback glue
ネイティブ拡張をビルドする
cd crates/simengine-py
python3 -m venv ../../.venv
source ../../.venv/bin/activate
pip install maturin
maturin develop --release
これを実行すると、simengine_native をインポートできる場合、既存の Python エンジンはネイティブのリデューサーとネイティブのバッチサンプラーを自動的に使用します。モジュールが見つからない場合、または読み込みに失敗した場合、SimEngine は既存の Python 実装にフォールバックします。
バッチサンプラーは保守的に動作します。
- 単純な数値変数のパラメーターにのみ適用されます
- 相関のある設定では無効のままです
SIMENGINE_DISABLE_NATIVE_SAMPLING=1で明示的に無効化できます
これにより、式エンジン、アキュムレーター、メトリクスは Python のままにしつつ、モンテカルロループのより大きな部分を Rust に移せます。
確率式向けの、より限定的なネイティブ高速化パスもあります。
- 拡張機能がインストールされている場合、
binomial(n, p)を Rust に委譲できます SIMENGINE_DISABLE_NATIVE_EXPR_SAMPLING=1で明示的に無効化できます
これにより、step_logic で binomial(...) を多用するドメインで役立ちながら、一般的な式の評価は引き続き Python で行えます。
Python 側では、繰り返し使われる式は一度だけコンパイルされ、モンテカルロ実行間で再利用されます。このキャッシュは、ベンチマークやトラブルシューティングのために SIMENGINE_DISABLE_EXPR_CACHE=1 で明示的に無効化できます。
診断モジュールでは、AST のみを使う同じ考え方の安全な評価器を適用しています。解析済みのツリーは呼び出し間で再利用され、このキャッシュは SIMENGINE_DISABLE_SAFE_EXPR_CACHE=1 で無効化できます。
できること
- モンテカルロシミュレーション -- JSON で記述できるあらゆる領域について、5,000 件以上の並列の将来シナリオを実行します。
- 安全性制約 -- チャンス制約(「破産する確率は最大 15%」)と CVaR 制約(「最悪ケースの平均損失は $X 以下」)に対応します。
- 遺伝的最適化 -- 安全性の境界を守りながら、最良の結果に向けて制御パラメーターを進化させます。交叉、突然変異、エリート保存、トーナメント選択に対応します。
- ベイズ更新 -- 観測データをモデルにフィードバックします。共役事前分布(Beta-Binomial、Gamma-Poisson、Normal-Normal)により、証拠が得られるたびに分布が絞り込まれます。
- 診断 -- 収束分析(サンプルサイズが十分であることを検証)、感度分析(出力を左右する入力を順位付け)、決定論的ベースラインとの比較(表計算による計算に対するシミュレーションの価値を定量化)を行います。
- Web UI -- ヒストグラム、軌跡ファン、リスクゲージ、制御変数のスイープや入力差分を用いたシナリオ比較、領域ウィザード、ベイズ更新モーダル、スタンドアロン HTML レポートへのエクスポートに対応します。
- AI エージェントとの統合 -- 設定をインラインで
/api/simulateに POST すると、構造化された結果が返されます。ファイルは不要です。LLM は SimEngine をツールとして利用できます(リポジトリのルートにあるllms.txtとGET /llms.txtを参照してください)。 - 検証済みのキャリブレーション -- sqlite の予測台帳で適切なスコアリングルール(Brier/log-loss/CRPS)を用いて予測を評価します。また、公開 FRED データを数十年分使用し、約 2,800 件のウォークフォワード月次予測でパイプラインをバックテストしています。実行するには、
cd v3 && python3 backtest.pyを実行してください(コミット済みスナップショットを使用するため、オフラインで実行できます)。結果:docs/backtests/。
アーキテクチャ
本番コードはすべて v3/ にあります。
v3/
├── kernel.py Monte Carlo engine, distributions, safety evaluation,
│ fitness scoring, genetic optimizer, experiment manifests
├── server.py HTTP server (port 8420), all API endpoints, report generation
├── bayesian.py Conjugate prior updates for calibrating parameters from data
├── diagnostics.py Convergence, sensitivity (OAT), baseline comparison, AST evaluator
├── static/
│ └── index.html Single-page web UI (vanilla HTML/JS/CSS, no framework)
└── domains/
├── _template.json Annotated starter config
├── business_pipeline_v3.json B2B sales pipeline
├── investment_portfolio.json Portfolio allocation
├── investment_portfolio_v2.json Fat-tailed returns (Student's t)
├── job_search.json Job search decision model
├── project_timeline.json Software project estimation
├── real_estate_rental.json Rental property analysis
└── saas_startup.json SaaS MRR growth and runway
領域設定スキーマ
領域設定は、シミュレーションを完全に記述する単一の JSON ファイルです。v3 スキーマでは変数を意味上の 3 つのカテゴリに分けており、ベイズ更新と最適化に影響します。
公開済みの仕様: 機械可読な JSON Schema(Draft 2020-12)は GET /api/schema で常時提供されます。これを AI に渡すだけで、有効な設定を一度に作成できます。平易な表現によるフィールドリファレンスは docs/schema-reference.md にあります。スキーマはテストスイート内の、同梱されているすべての領域を対象に検証されています。
トップレベルのフィールド
| フィールド | 型 | 説明 |
|---|---|---|
name | string | 人が読める領域名 |
description | string | このシミュレーションでモデル化する内容 |
n_simulations | int | モンテカルロ実行回数(デフォルト:5000) |
n_steps | int | シミュレーションごとの時間ステップ数(例:12 か月) |
step_label | string | 時間軸のラベル:「month」、「week」、「sprint」 |
seed | int or null | 再現性を確保するための乱数シード |
parameters | object | 不確実な変数。証拠に基づいて更新可能 |
controls | object | オペレーターの意思決定(価格設定、予算、労力) |
exogenous | object | 自分では制御できない外部要因 |
initial_state | object | 累積値の初期値 |
step_logic | array | 各時間ステップで実行する計算 |
accumulators | object | 各ステップで更新される累積値 |
metrics | object | 最終的な出力測定値 |
safety | object | チャンス制約と CVaR 制約 |
fitness | object | オプティマイザー用の重み付きスコア構成要素 |
tunable | array | オプティマイザーによる調整を許可するパラメーター |
context | object | 任意のメタデータ:意思決定に関する質問、主要なレバー |
calibration | object | 変数ごとのデータソースと更新方法 |
変数の定義
3 つすべての変数カテゴリ(parameters、controls、exogenous)で、同じ構造を使用します。
{
"monthly_churn_rate": {
"distribution": "triangular",
"params": {"low": 0.02, "mode": 0.05, "high": 0.12},
"calibration": {
"source": "Baremetrics Open Benchmarks: median monthly churn 5-8%",
"updatable": true,
"update_method": "Beta-Binomial conjugate from observed monthly cancellations"
}
}
}
利用可能な分布
| 分布 | パラメーター | 用途 |
|---|---|---|
fixed | value | 既知の定数 |
uniform | low, high | 範囲内で確率が均等 |
triangular | low, mode, high | 専門家による推定(悲観的/可能性が高い/楽観的) |
normal | mean, std, min?, max? | ベルカーブ。必要に応じて範囲を制限 |
lognormal | median, spread, min?, max? | 常に正の値で、右に裾が長い分布(価格、期間) |
bernoulli | p | 2 値の「はい/いいえ」イベント |
poisson | lambda | まれなイベントの回数 |
student_t | mean, scale, df, min?, max? | 裾の厚いリターン(株式では df=5 を使用) |
correlated_normal | mean, std | 相関に対応した正規分布(step_logic 経由) |
ステップロジック
各時間ステップで実行される計算の順序付きリストです。各エントリには target 名と、expr(式の文字列)または sample(インライン分布)のいずれかを指定します。
"step_logic": [
{"target": "new_leads", "expr": "binomial(round(demand), conversion_rate)"},
{"target": "revenue", "expr": "new_leads * price_per_unit"},
{"target": "costs", "expr": "fixed_cost + variable_cost * new_leads"},
{"target": "net_income", "expr": "revenue - costs"},
{"target": "shock_event", "sample": {"distribution": "bernoulli", "params": {"p": 0.02}}}
]
使用可能な式関数: min、max、abs、round、sum、len、int、float、sqrt、log、exp、ceil、floor、pow、random()、gauss(mu, sigma)、binomial(n, p)、clamp(val, lo, hi)、range()。三項式も使用できます:100 if x > 0 else 0。
累積値
時間ステップをまたいで保持される実行中の状態です。
"accumulators": {
"cumulative_revenue": "cumulative_revenue + revenue",
"cash": "cash + net_income",
"peak_subscribers": "max(peak_subscribers, subscribers)"
}
指標
すべてのステップの完了後に計算される最終的な測定値です。
"metrics": {
"total_revenue": {"expr": "cumulative_revenue", "format": "dollar"},
"roi": {"expr": "cumulative_revenue / cumulative_costs", "format": "percent"},
"final_subs": {"expr": "subscribers", "format": "number"}
}
安全制約
"safety": {
"chance_constraints": [
{
"metric": "ending_cash",
"condition": "below",
"threshold": 0,
"max_prob": 0.15,
"rationale": "No more than 15% chance of running out of cash"
}
],
"cvar_constraints": [
{
"metric": "ending_cash",
"alpha": 0.10,
"min_cvar": -15000,
"rationale": "Average of the worst 10% of outcomes must not exceed $15k loss"
}
]
}
適合度と調整可能なパラメーター
オプティマイザーは、安全制約を守りながら適合度要素の加重合計を最大化します。各要素は、指標の統計値(例:total_revenue_median、ending_cash_p10)に対して評価される式です。
"fitness": {
"components": [
{"expr": "min(100, final_mrr_median / 100)", "weight": 0.30, "name": "mrr_growth"},
{"expr": "max(0, 100 - months_negative_median * 5)", "weight": 0.25, "name": "time_to_profit"}
]
},
"tunable": [
{"path": "controls.price_per_seat.params.value", "range": [9, 99]},
{"path": "parameters.monthly_churn_rate.params.mode", "range": [0.01, 0.10]}
]
適合度の式では、{metric_name}_{stat} の形式ですべての指標統計値を参照できます。stat は mean、median、std、p10、p25、p75、p90 のいずれかです。
制約違反 1 件につき、安全制約違反のペナルティとして 30% が適用されます。オプティマイザーは違反を避けるよう学習します。
API リファレンス
サーバーは http://localhost:8420 で実行されます。すべての POST エンドポイントは JSON を受け取り、JSON を返します。すべてのレスポンスに CORS ヘッダーが含まれます。
GET /api/domains
利用可能なすべてのドメイン設定を一覧表示します。
レスポンス:
[
{
"file": "saas_startup.json",
"name": "Indie SaaS -- MRR Growth & Runway",
"description": "Models a bootstrapped SaaS product over 24 months...",
"n_simulations": 5000,
"n_steps": 24,
"step_label": "month"
}
]
GET /api/domain/{filename}
ファイル名を指定して、特定のドメイン設定を読み込みます。
レスポンス: ドメイン設定の完全な JSON オブジェクト。
POST /api/simulate
モンテカルロシミュレーションを実行します。
リクエスト(ファイルベース):
{
"domain": "saas_startup.json",
"n_simulations": 5000,
"seed": 42,
"overrides": {
"controls.price_per_seat.params.value": 49
}
}
リクエスト(インライン設定 -- AI エージェント向け):
{
"config": { ... full domain config object ... },
"n_simulations": 5000,
"seed": 42
}
レスポンス:
{
"domain": "Indie SaaS -- MRR Growth & Runway",
"n_simulations": 5000,
"elapsed": 1.23,
"stats": {
"final_mrr": {
"mean": 4250.00,
"median": 3915.00,
"std": 2100.50,
"p10": 1740.00,
"p25": 2610.00,
"p75": 5220.00,
"p90": 7105.00,
"format": "dollar"
}
},
"trajectories": {
"cash": {
"p10": [24500, 23800, ...],
"p50": [25100, 25300, ...],
"p90": [25800, 26900, ...]
}
},
"histograms": {
"final_mrr": {
"bins": [0.0, 250.0, ...],
"counts": [12, 45, ...],
"bin_width": 250.0,
"lo": 0.0,
"hi": 10000.0
}
},
"safety": {
"chance": [
{"metric": "ending_cash", "condition": "below", "threshold": 0,
"max_prob": 0.15, "actual_prob": 0.082, "passed": true}
],
"cvar": [
{"metric": "ending_cash", "alpha": 0.10, "min_cvar": -15000,
"actual_cvar": -8500.00, "passed": true}
],
"all_passed": true
},
"fitness": 72.5,
"narrative": "**Final Mrr** is most likely $3,915 (range: $1,740 to $7,105 in 80% of scenarios)...",
"context": {"decision": "Should I go full-time on this SaaS?"}
}
POST /api/evolve
遺伝的オプティマイザーを実行し、最適な制御設定を見つけます。
リクエスト:
{
"domain": "saas_startup.json",
"generations": 15,
"population": 20
}
レスポンス:
{
"domain": "Indie SaaS -- MRR Growth & Runway",
"best_fitness": 85.3,
"best_stats": { ... same format as simulate stats ... },
"best_safety": { "all_passed": true, "chance": [...], "cvar": [...] },
"history": [
{"gen": 0, "best_fit": 62.1, "avg_fit": 45.3, "safe_pct": 60.0, "elapsed": 2.1},
{"gen": 1, "best_fit": 68.5, "avg_fit": 52.1, "safe_pct": 75.0, "elapsed": 2.0}
],
"elapsed": 31.5
}
POST /api/validate
完全なシミュレーションを実行せずに、ドメイン設定を検証します。式のエラーを検出するため、10 回の反復テストを実行します。
リクエスト:
{
"config": { ... domain config object ... }
}
レスポンス:
{
"valid": true,
"errors": []
}
または、失敗した場合:
{
"valid": false,
"errors": [
"Variable 'close_rate': unknown distribution 'beta'",
"step_logic[2]: missing 'target'"
]
}
POST /api/save-domain
ドメイン設定を検証し、domains/ ディレクトリに保存します。
リクエスト:
{
"config": { ... domain config object ... },
"filename": "my_new_domain"
}
レスポンス:
{
"saved": true,
"file": "my_new_domain.json"
}
POST /api/update
ベイズ更新:観測データをドメイン設定に入力し、更新されたパラメーター分布とプレビューシミュレーションを取得します。
リクエスト:
{
"domain": "saas_startup.json",
"observations": {
"monthly_churn_rate": [0.04, 0.06, 0.03, 0.05],
"organic_signup_rate": [18, 22, 15, 25, 20]
}
}
レスポンス:
{
"updated_config": { ... full config with tightened distributions ... },
"update_report": {
"monthly_churn_rate": {
"method": "beta_binomial",
"prior_mean": 0.05,
"posterior_mean": 0.045,
"posterior_std": 0.012,
"observations_used": 4,
"credible_interval_90": [0.025, 0.065]
}
},
"preview_stats": { ... simulation results with updated params ... },
"preview_safety": { ... }
}
POST /api/report
シミュレーション結果から、単独で利用できる HTML レポートを生成します。
リクエスト:
{
"results": { ... simulate response object ... },
"config": { ... domain config ... }
}
レスポンス: HTML ドキュメント(Content-Type: text/html)。自己完結型で、外部依存関係はありません。保存、メール送信、印刷ができます。
CLI の使用方法
kernel.py
cd ~/projects/simengine/v3
# Run a Monte Carlo simulation
python3 kernel.py domains/saas_startup.json
# Set a random seed for reproducibility
python3 kernel.py domains/saas_startup.json --seed 42
# Save results to a specific file
python3 kernel.py domains/saas_startup.json --output results.json
# Run evolutionary optimization
python3 kernel.py domains/saas_startup.json --evolve
# Customize optimizer parameters
python3 kernel.py domains/saas_startup.json --evolve \
--generations 25 \
--population 30 \
--workers 8 \
--output best_strategy.json
短縮フラグ:-g(世代数)、-p(個体数)、-w(ワーカー数)、-o(出力)。
diagnostics.py
cd ~/projects/simengine/v3
# Convergence analysis -- proves sample size is sufficient
# Runs at N=100, 250, 500, ..., 20000 and measures estimator stability.
python3 diagnostics.py domains/saas_startup.json --convergence
# Sensitivity analysis -- ranks which inputs drive the output
# One-at-a-time perturbation with normalized impact scores.
python3 diagnostics.py domains/saas_startup.json --sensitivity
# Baseline comparison -- Monte Carlo vs deterministic spreadsheet
# Shows the risk that point-estimate forecasting hides.
python3 diagnostics.py domains/saas_startup.json --baseline
# Target a specific metric (default: first metric defined)
python3 diagnostics.py domains/saas_startup.json --convergence --metric ending_cash
# Save results to JSON
python3 diagnostics.py domains/saas_startup.json --convergence --output conv.json
フラグは組み合わせて使用できます:--convergence --sensitivity --baseline を実行すると、3 つすべてを実行します。
新しいドメインの作成
ドメイン設定を作成する方法は 3 つあります。
1. Web UI ウィザード
http://localhost:8420 を開き、ドメインウィザードをクリックしてフォームに入力します。ウィザードが有効な設定を生成して検証し、domains/ ディレクトリに保存します。
2. テンプレートをコピーする
cp ~/projects/simengine/v3/domains/_template.json ~/projects/simengine/v3/domains/my_problem.json
my_problem.json を編集します。テンプレートには、_guide フィールド内のインラインドキュメントと、動作するサンプル構造が含まれています。プレースホルダー変数、ロジック、メトリクスを独自のものに置き換えてください。
3. LLM で生成する
問題を LLM に説明し、SimEngine v3 のドメイン設定を作成するよう依頼します。使用前に検証してください。
# Validate from the command line via the API
curl -X POST http://localhost:8420/api/validate \
-H 'Content-Type: application/json' \
-d '{"config": <paste your JSON>}'
または、設定を {"config": {...}} として /api/simulate に直接 POST します。シミュレーションが実行されるか、エラーが返されます。
最小構成
実行可能な最小の設定です。
{
"name": "Coin Flip",
"n_simulations": 1000,
"n_steps": 10,
"parameters": {
"heads": {
"distribution": "bernoulli",
"params": {"p": 0.5}
}
},
"step_logic": [
{"target": "payout", "expr": "1 if heads > 0.5 else -1"}
],
"accumulators": {
"bankroll": "bankroll + payout"
},
"metrics": {
"final_bankroll": {"expr": "bankroll", "format": "number"}
},
"initial_state": {"bankroll": 0}
}
ベイズ更新
SimEngine は、実世界のデータが届くにつれてパラメーター分布を絞り込む、共役ベイズ更新をサポートしています。
仕組み
- 事前分布を設定します。これは、設定で指定した分布です(例:解約率に対する
triangular(0.02, 0.05, 0.12))。 - 実データを観測します(例:実際の月次解約率:
[0.04, 0.06, 0.03, 0.05])。 - エンジンは、適切な共役更新を使用して事後分布を計算します。
- 事前の信念と証拠の両方を反映する、より絞り込まれた分布で設定が書き換えられます。
サポートされる手法
| 手法 | 共役ペア | 用途 |
|---|---|---|
beta_binomial | ベータ二項分布 | 成約率、解約率、コンバージョン率などの率や確率 |
gamma_poisson | ガンマ・ポアソン分布 | 月間リード数、スプリントごとのバグ数、週間登録数などのカウント |
normal_normal | 正規・正規分布 | プロジェクト価値、給与、取引額などの連続的な平均値 |
手法の選択
手法は次の順序で選択されます。
- 変数定義に明示的に指定された
calibration.update_method。 - 分布の種類とパラメーター範囲から自動推定します([0,1] の値にはベータ二項分布、整数値のポアソン分布にはガンマ・ポアソン分布、それ以外には正規・正規分布が使用されます)。
API 経由
curl -X POST http://localhost:8420/api/update \
-H 'Content-Type: application/json' \
-d '{
"domain": "saas_startup.json",
"observations": {
"monthly_churn_rate": [0.04, 0.06, 0.03, 0.05]
}
}'
レスポンスには、更新済みの設定、事前分布と事後分布を示す診断レポート、更新済みパラメーターを使ったプレビューシミュレーションが含まれます。
Python 経由
from bayesian import update_parameter
updated_params, diagnostics = update_parameter(
variable_def={
"distribution": "triangular",
"params": {"low": 0.02, "mode": 0.05, "high": 0.12}
},
observations=[0.04, 0.06, 0.03, 0.05],
method="beta_binomial"
)
print(diagnostics["posterior_mean"]) # 0.0459
print(diagnostics["credible_interval_90"]) # [0.0312, 0.0606]
AI エージェントとの統合
SimEngine は、LLM や AI エージェントがツールとして使用できるよう設計されています。主な機能はインライン設定のサポートです。ファイルを保存せずに、完全なドメイン設定を /api/simulate に直接 POST できます。
パターン
- エージェントが問題を SimEngine のドメイン設定(JSON)として記述します。
- エージェントが
{"config": {...}, "n_simulations": 5000, "seed": 42}を/api/simulateに POST します。 - エージェントが構造化レスポンス(統計、安全性評価、適合度スコア、ナラティブ)を読み取ります。
- エージェントが結果を推論し、報告するか、設定を調整して再実行します。
例:エージェントのツール呼び出し
import json, urllib.request
config = {
"name": "Should I take this contract?",
"n_simulations": 3000,
"n_steps": 6,
"step_label": "month",
"parameters": {
"hours_per_week": {
"distribution": "triangular",
"params": {"low": 15, "mode": 25, "high": 45}
},
"scope_creep": {
"distribution": "bernoulli",
"params": {"p": 0.3}
}
},
"controls": {
"hourly_rate": {
"distribution": "fixed",
"params": {"value": 150}
}
},
"exogenous": {},
"initial_state": {"total_hours": 0, "total_revenue": 0},
"step_logic": [
{"target": "weekly_hours", "expr": "hours_per_week * (1.4 if scope_creep > 0.5 else 1.0)"},
{"target": "monthly_hours", "expr": "weekly_hours * 4.33"},
{"target": "monthly_rev", "expr": "min(monthly_hours, 160) * hourly_rate"}
],
"accumulators": {
"total_hours": "total_hours + monthly_hours",
"total_revenue": "total_revenue + monthly_rev"
},
"metrics": {
"total_revenue": {"expr": "total_revenue", "format": "dollar"},
"effective_rate": {"expr": "total_revenue / total_hours if total_hours > 0 else 0", "format": "dollar"},
"total_hours": {"expr": "total_hours", "format": "number"}
}
}
req = urllib.request.Request(
"http://localhost:8420/api/simulate",
data=json.dumps({"config": config, "seed": 42}).encode(),
headers={"Content-Type": "application/json"},
method="POST"
)
resp = json.loads(urllib.request.urlopen(req).read())
print(f"Revenue (median): ${resp['stats']['total_revenue']['median']:,.0f}")
print(f"Revenue (P10-P90): ${resp['stats']['total_revenue']['p10']:,.0f} - ${resp['stats']['total_revenue']['p90']:,.0f}")
print(f"Effective rate (median): ${resp['stats']['effective_rate']['median']:,.0f}/hr")
エージェントが受け取る情報
/api/simulate のレスポンスには、エージェントが結果を推論するために必要な情報がすべて含まれています。
stats-- すべてのメトリクスについての分布統計(平均、中央値、標準偏差、p10/p25/p75/p90)。safety-- 各制約の合否と実際の確率。fitness-- シナリオを比較するための単一のスカラー値のスコア。narrative-- 人が読める形式の要約テキスト。trajectories-- 傾向分析用の時系列パーセンタイル帯。histograms-- 分布形状の分析用にビン分けされたデータ。
シナリオの比較
代替案を比較するには、エージェントが複数の設定(コントロールを変更したもの)を POST し、レスポンス間で適合度スコア、安全性評価、または特定のメトリクスのパーセンタイルを比較します。
判断ゲート:decide_under_uncertainty(MCP)
複数ステップのエージェントでは、過度に自信のある単一の回答が積み重なります。decide_under_uncertainty MCP ツールは、シミュレーションを続行/エスカレーションの判定に変換します。モンテカルロシミュレーションを実行し、結果の分布のうち、許容する範囲に入る割合を測定して、判定フラグと分布全体、わかりやすい理由を返します。
このツールがモデル化するのは、不確実な入力を前提とした結果のばらつきである結果リスクであり、言語モデル自身のトークンに対する信頼度ではありません。この2つは相補的なものであり、混同しないでください。
引数: metric(必須)、acceptable({"min": ..., "max": ...}、少なくとも一方の境界値が必要)、min_confidence(続行に必要な範囲内の確率質量。デフォルトは 0.8)、さらに domain またはインラインの config、および任意の seed/n_simulations。
{
"metric": "annual_gross_income",
"decision": "proceed",
"proceed": true,
"probability_within_bounds": 0.92,
"min_confidence": 0.8,
"acceptable": {"min": 40000, "max": null},
"distribution": {"median": 68000, "p10": 44000, "p90": 95000, "format": "dollar"},
"n_simulations": 5000,
"reason": "92% of 5,000 simulated outcomes for 'annual_gross_income' fall within the acceptable range (>= 40,000) -- at or above the 80% confidence required to proceed."
}
エージェントのパターン全体については、docs/decision-gate.md を参照してください。
キャリブレーションと実績
モンテカルロエンジンは、常に自信がありそうな分布を出力します。*「もっともらしい数字を出す計算機」と「実証済みの的中率を持つ予測ツール」*を分けるのは、現実と照らして採点された実績だけです。v3/calibration.py はその基盤です。標準ライブラリのみを使い、依存関係はありません。
適切なスコアリングルール: brier_score、log_loss、crps_sample。
予測台帳: 予測を記録し、後で実際の結果と照合して、時間の経過とともにキャリブレーションがどれほど適切だったかを採点します。
from calibration import CalibrationLedger
ledger = CalibrationLedger("forecasts.db")
fid = ledger.record("Annual gross >= $40k?", 0.82, metric="annual_gross_income")
# ... the year resolves ...
ledger.resolve(fid, 1)
print(ledger.score()) # {"n": 1, "brier": 0.0324, "log_loss": 0.198}
Brier スコアは 0.0 が完全で、0.25 は常に 50/50 で推測する場合のスコア、1.0 は最悪です。Log-loss は、自信を持って誤った予測をした場合に、より大きなペナルティを課します。どちらも低いほど良好です。実績は時間の積み重ねが重要です。記録を今すぐ始めなければ、実績は蓄積されません。
リアルタイムデータ(オプトイン)
コアエンジンはオフラインで動作し、標準ライブラリのみを使用します。v3/feeds/ パッケージは、ライブデータへのオプションのブリッジです。ネットワークに接続する SimEngine の唯一の部分であり、新たな依存関係は追加せず、urllib のみを使用します。また、コアからインポートされることはありません。
最初のアダプターである feeds/polymarket.py は、Polymarket のリアルタイム予測市場価格をキャリブレーション済み事前分布に変換します。市場が示唆する確率を、ドメイン設定に組み込める SimEngine の変数にし、独自の証拠が得られるたびに Beta-Binomial アップデーターでさらに調整できます。価格を入力 → 事前分布 → 事後分布であり、価格を入力 → 価格を出力するものではありません。
from feeds import polymarket
markets = polymarket.fetch_markets(query="fed rate", limit=5)
prior = polymarket.market_prior(markets[0], strength=20) # -> a triangular variable_def
docs/feeds.md を参照してください。市場価格は内部シミュレーションの入力として扱われ、再配信フィードや取引シグナルとして使われることはありません。
SimEngine に自然言語で何でも質問する
設定ファイルを記述したくない場合は、意思決定の内容を平易な言葉で説明すれば、LLM がモデルを作成します。SimEngine は設定ファイルの下書きを作成し、エンジンで検証して、エラーを修正したうえでシミュレーションを実行し、結果を説明します。モデルが生成した内容をエンジンが検証するため、小規模なローカルモデルでも信頼性を保てます。
これはオプトインで、標準ライブラリのみを使用します。デフォルトでは Ollama 経由のローカルモデルを使用します。無料で、プライベートに利用でき、API キーも不要です。ホスト型モデルを使うには、環境変数を設定してください。
CLI
# With Ollama running (e.g. `ollama pull qwen2.5`):
python3 v3/sim_ask.py "Should I take an $8k/mo, 6-month contract if there's a 30% chance it overruns?"
フラグ:--n(シミュレーション回数)、--seed、--save NAME(設定を domains/ に保存)、--show-config、--json、--model NAME、--backend。
Web
http://localhost:8420 を開き、Ask anything をクリックして質問を入力し、実行します。平易な言葉による回答、主要な数値、安全性の判定、生成されたモデルが得られます。生成されたモデルは、再利用可能なドメインとして保存できます。
API
{"question": "...", "n_simulations": 3000, "seed": 42} を指定して POST /api/ask を呼び出すと、{config, results, explanation, attempts, valid} が返されます。
バックエンド(環境変数)
| 変数 | デフォルト | 用途 |
|---|---|---|
SIMENGINE_LLM_BACKEND | ollama | ollama | openai | anthropic |
SIMENGINE_LLM_MODEL | qwen2.5 | モデル名 |
SIMENGINE_LLM_TIMEOUT | 120 | リクエストごとの秒数(ローカルモデルの処理が遅い場合は増やしてください) |
OPENAI_API_KEY / OPENAI_BASE_URL | — | OpenAI 互換(llama.cpp / LM Studio / vLLM も対象) |
ANTHROPIC_API_KEY | — | Anthropic |
意思決定の支援とシナリオ分析のみを目的としています。金融アドバイスや取引シグナルではありません。
数値の意味
シミュレーションを実行すると、各指標は次の内容を示します。
- 平均値 -- シミュレーションしたすべての将来の平均です。
- 中央値 -- 50 パーセンタイルです。将来の半数がこの値を上回り、半数が下回ります。
- P10 -- 悲観的な値です。将来のうち、これより悪い結果となるのは 10% のみです。
- P90 -- 楽観的な値です。将来のうち、これより良い結果となるのは 10% のみです。
- 標準偏差 -- 標準偏差です。分布の幅を示します。
- CVaR(alpha) -- 最悪の alpha% の将来における平均的な結果です。リスクを考慮する意思決定者が最も重視する数値です。
安全制約は、意思決定に関する表現にそのまま置き換えられます。
- 確率制約:「[metric] が [threshold] を [下回る/上回る] 確率は、[X]% を超えてはなりません。」
- CVaR 制約:「最悪の [alpha]% のシナリオにおいて、[metric] の平均は少なくとも [min_cvar] でなければなりません。」
ドキュメント
SimEngine を初めてお使いですか? まずは平易な言葉によるガイドをご覧ください。 SimEngine とは何か、結果の読み方、対象ユーザー、他の人への説明方法、自分自身の意思決定のモデル化方法を、予備知識がなくても理解できるよう解説しています。
査読レポートとシステム設計論文は、ご要望に応じて提供しています。アクセス方法についてはメンテナーにお問い合わせください。
ライセンス
SimEngine はオープンコアモデルを採用しています。
- エンジン、サーバー、カーネル、診断機能、Rust による高速化、ドメインライブラリ — Apache License 2.0。同ライセンスの条件に従い、無料で使用、変更、セルフホスト、自社製品への組み込み、再配布ができます。
- ホスト型 SimEngine MCP サービス(OtrovertLabs が運営)— 商用ライセンス。マネージドホスティング、OAuth、永続状態、SLA、エンタープライズ機能を提供するサブスクリプションプランがあります。
オープンソースエンジンのセルフホストは、現在も今後も無料です。商用ライセンスが適用されるのは、ホスト型サービスと、オープンソース配布物に含まれないマネージド機能のみです。
SimEngine は OtrovertLabs の製品であり、Venture Horizon LLC が公開しています。
商用ライセンス、エンタープライズ関連のお問い合わせ、パートナーシップについて:https://otrovertlabs.com/contact
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。