MCP Zero Shot Agentic Forecaster
エグゼクティブ概要とビジネス価値
このリポジトリとは?
MCP Zero Shot Agentic Forecasterは、Model Context Protocol (MCP)を介して公開される、本番環境対応のマイクロサービス型時系列予測エンジンです。最先端の基盤モデル(Google TimesFM 2.5 XRegおよびAmazon Chronos-2)を搭載し、自律型AIエージェント(LangGraphステートマシン、CrewAIスウォーム、OPA/Regoで管理されるNeSyスタック、標準的なReActループ)が、オフラインでのモデルトレーニング、ハイパーパラメータチューニング、SKUごとのデータセット準備を必要とせずに、確率的な需要予測をオンデマンドで照会できるようにします。
ビジネス価値とROI
コールドスタートレイテンシの排除:新製品の投入、プロモーション、履歴の短いSKUに対して、トレーニングパイプラインなしで即時のゼロショット確率予測を提供します。
分位数制約付きリスク制御:較正された$p_{10}$、$p_{50}$、$p_{90}$の需要分位数を出力し、自律型購買エージェントが安全在庫バッファと資本保有コストのバランスを取れるようにします。
総保有コスト(TCO)の低減:複雑なファインチューニングパイプラインを統一された3層フォールバックエンジンに置き換え、GPU計算要件とインフラストラクチャのドリフトを大幅に削減します。
エージェンティックな回復力:入力が無効な場合、修正のヒントを含む構造化された
AgentFriendlyErrorペイロードを返し、呼び出し元エージェントがサイレントに失敗したり未処理の例外を発生させたりすることなく、実行ループ内で自己修正できるようにします。
動作の仕組み
エージェント呼び出し:呼び出し元エージェントは、MCPツールインターフェースを介してstdio/HTTP上で
forecast_demandまたはforecast_batchを呼び出します。契約の強制:Pydantic v2スキーマが、厳密な有限数値および時間的境界チェック(
[Type-Safe Input Contract])を実行します。ノンブロッキング推論:FastMCPは
asyncio.to_threadを介して重いテンソル演算をスレッドプールにオフロードし、ゲートウェイの応答性を維持します。統一3層パイプライン:常にTimesFM 2.5(Tier 1)を経由し、Chronos-2(Tier 2、共変量が存在する場合は保持)およびARIMA111(Tier 3、共変量を破棄)にフォールバックします。CUDA OOMまたは障害が発生した場合、エンジンは次の層に移行する前にメモリ回復(
gc.collect()+torch.cuda.empty_cache())をトリガーします。数学的サニタイゼーション:等張回帰ソートを適用して出力分位数の単調性($p_{10} \le p_{50} \le p_{90}$)を保証し、認識論的信頼スコアを正規化してから、構造化されたJSONペイロードを返します。
Related MCP server: forecast-mcp
システムアーキテクチャ
このマイクロサービスは関心の厳密な分離に準拠しています。MCPツール層はノンブロッキング転送、メモリ安全性、モデルレベルの出力サニタイゼーションを管理し、ドメイン固有のビジネスポリシーは下流のエージェントオーケストレーターに委ねます。
graph TD
subgraph External Agent Orchestrator
Agent[LLM Agent / Swarm / State Machine<br/>LangGraph / OPA Sidecar / ReAct Loop]
end
subgraph MCP Microservice Boundary
Gateway[FastMCP Async Gateway Server<br/>mcp_server.py]
Sanitizer[Pydantic v2 Input Contract<br/>TimeSeriesInputPayload]
ErrorFormatter[AgentFriendlyError Formatter]
subgraph Engine Memory & Concurrency Boundary
ExecThread[Thread Executor<br/>asyncio.to_thread]
Engine[ZeroShotForecastingEngine<br/>src/models/forecaster.py<br/>Lazy-Load Lock Protected]
subgraph 3-Tier Fallback Model Chain
T1[Tier 1: TimesFM 2.5<br/>XReg / Univariate]
T2[Tier 2: Chronos-2<br/>Multivariate / Univariate]
T3[Tier 3: ARIMA111<br/>CPU Baseline Fallback]
end
IsoSanitizer[Isotonic Quantile Sanitizer<br/>Enforces p10 ≤ p50 ≤ p90]
end
end
Agent -->|FastMCP Tool Call<br/>forecast_demand / forecast_batch| Gateway
Gateway -->|1. Validate Schema| Sanitizer
Sanitizer -->|Validation Error| ErrorFormatter
ErrorFormatter -.->|Structured Error + Remediation| Agent
Sanitizer -->|2. Valid Payload| ExecThread
ExecThread -->|3. Route Request| Engine
Engine --> T1
T1 -.->|CUDA OOM / Fail| T2
T2 -.->|Fail| T3
T1 -->|Raw Quantiles| IsoSanitizer
T2 -->|Raw Quantiles| IsoSanitizer
T3 -->|Raw Quantiles| IsoSanitizer
IsoSanitizer -->|4. Validated ForecastResponse| Gateway
Gateway -->|5. Return JSON Payload| Agentコンポーネントアーキテクチャの内訳
FastMCPゲートウェイ(mcp_server.py):非同期JSON-RPCトランスポートを提供し、バッチ同時実行制限(asyncio.Semaphore(4))を適用します。
型安全な契約境界(src/schemas/payloads.py):時間的整合性、有限数値の保証、コンテキスト/ホライズン制限を強制します。
スレッドセーフなフォーキャスターコア(src/models/forecaster.py):遅延モデルロードにダブルチェックロッキング(threading.Lock())を採用し、CUDA OOMの自動回復(gc.collect() + torch.cuda.empty_cache())を処理します。
等張回帰出力サニタイザー:生の基盤モデル分位数を単調ソートで後処理し、予測をエージェントに返す前に統計的異常($p_{10} > p_{50}$)を排除します。
システム実行フロー(シーケンス図)
sequenceDiagram
autonumber
actor Agent as LLM Agent / Orchestrator
participant Gateway as FastMCP Gateway (Async)
participant Sanitizer as Pydantic Input Contract
participant Executor as Thread Executor (asyncio.to_thread)
participant Pipeline as 3-Tier Fallback Pipeline
participant Std as Isotonic Quantile Sanitizer
Agent->>Gateway: forecast_demand / forecast_batch (JSON)
Gateway->>Sanitizer: Validate TimeSeriesInputPayload
alt Validation Failure
Sanitizer-->>Gateway: AgentFriendlyError {error_code, expected, received, remediation}
Gateway-->>Agent: Structured Error Response
else Validation Success
Sanitizer->>Executor: Offload sync inference
Executor->>Pipeline: Execute prediction
Note right of Pipeline: Tier 1: TimesFM 2.5 → Tier 2: Chronos-2 → Tier 3: ARIMA111
alt CUDA OOM / Transient Failure
Pipeline->>Pipeline: gc.collect() + torch.cuda.empty_cache()
Pipeline->>Pipeline: Degrade to next tier (retain covariates where possible)
end
Pipeline->>Std: Apply _enforce_quantile_monotonicity()
Std-->>Executor: ForecastResponse {model_used, exogenous_dropped, warnings}
Executor-->>Gateway: Return validated response
Gateway-->>Agent: 200 OK with ForecastResponse
end中核となるアーキテクチャ原則
ノンブロッキング非同期トランスポート
すべてのテンソルフォワードパスはasyncio.to_threadを介してスレッドプールで実行され、負荷がかかった状態でもFastMCPイベントループが同時のヘルスチェックとツール呼び出しに応答し続けるようにします。
# mcp_server.py
result = await asyncio.to_thread(engine.predict, validated_payload)VRAM遅延ロード
モデルウェイトはアクセサメソッドを介して最初の使用時のみ実体化され、起動時にVRAMを消費しません。スレッドセーフなダブルチェックロッキングにより、同時コールドスタート時の重複インスタンス化を防ぎます。
# src/models/forecaster.py
def _get_timesfm(self):
if self._timesfm is None:
with self._timesfm_lock:
if self._timesfm is None:
import timesfm
logger.info(f"Lazily loading TimesFM-2.5 ({self.timesfm_repo_id}) onto {self._device}")
self._timesfm = timesfm.TimesFM_2p5_200M_torch.from_pretrained(self.timesfm_repo_id)
return self._timesfm
def _get_chronos(self):
if self._chronos is None:
with self._chronos_lock:
if self._chronos is None:
from chronos import BaseChronosPipeline
logger.info(f"Lazily loading Chronos-2 ({self.chronos_repo_id}) onto {self._device}")
self._chronos = BaseChronosPipeline.from_pretrained(
self.chronos_repo_id, device_map=self._device, dtype=torch.float32
)
return self._chronos3層フォールバックエンジン
エンジンは、ペイロードの内容に関係なく、単一の統一された決定論的デグラデーションチェーンを維持します。
Tier | バックエンド | モード |
|
|
1 | TimesFM 2.5 | XReg / Univariate |
|
|
2 | Chronos-2 | Multivariate / Univariate |
|
|
3 | ARIMA111 | Baseline |
|
|
TimesFMの障害時(torch.cuda.OutOfMemoryErrorを含む):
gc.collect()+torch.cuda.empty_cache()外生シグナルは
_build_chronos_covariates()(過去/将来の共変量)を介してChronos-2用に保持されますexogenous_dropped = trueは、フォールバックがTier 3(ARIMA111)にデグラデーションした場合のみ実行はChronos-2にルーティングされます
Chronosが失敗した場合→ARIMA111ベースライン
時間的規則性の強制
Pydantic v2バリデータは、境界で無効なテレメトリを拒否します:
Validator | Rule |
コンテキスト境界 |
|
ホライズン境界 |
|
有限値 |
|
外生変数の整合性 |
|
バイナリフラグ |
|
等張回帰分位数サニタイゼーション
すべてのバックエンド(TimesFM、Chronos-2、AutoARIMA)は、極端なOOD入力下で時折交差する($p_{10} > p_{50}$または$p_{50} > p_{90}$)生の分位数を出力します。エンジンは、タイムステップごとに等張回帰ソートを実行する軽量な後処理ステップ_enforce_quantile_monotonicity()を適用します。$(p_{10}, p_{50}, p_{90})$をスタックし、分位数軸に沿ってソートし、順序付けられたトリプレットを返します。これにより、分布形状を歪めることなく、すべての予測ホライズンステップで数学的に有効な$p_{10} \le p_{50} \le p_{90}$が保証されます。
制限付きバッチ同時実行
forecast_batch MCPツールは、asyncio.Semaphore(4)によって制限されたasyncio.gatherを使用して、マルチSKU推論を同時に実行します。これにより、無制限の同時テンソル割り当てからGPU/CPUメモリを保護しながら、並列スループットを提供します。各アイテムはセマフォを取得し、ペイロードを検証し、asyncio.to_threadを介してengine.predictをスレッドプールにオフロードし、アイテムごとのフォールバックメタデータを含む構造化されたForecastResponseを返します。サマリーブロックは、総アイテム数、エラー数、バックエンドごとの使用状況(model_usage)を報告します。
バックエンド別サーキットブレーカー
各基盤モデルバックエンドは、モデルハブに到達できない場合や一貫してエラーが発生する場合のカスケード障害を防ぐために、独立したサーキットブレーカー(CircuitBreakerState)を維持します。5回連続で失敗すると、ブレーカーが開き、テストコールを許可する前に60秒間トラフィックを直ちに次のフォールバック層にルーティングします。
バックエンド | 失敗しきい値 | クールダウン | オープン時の動作 |
TimesFM 2.5 | 5回の失敗 | 60s |
|
Chronos-2 | 5回の失敗 | 60s |
|
これにより、一時的なHuggingFace Hubの停止や破損したウェイトのダウンロードがエージェントを無期限にブロックしないことが保証されます。
正規化された信頼度メトリック
信頼度スコアは、広い分散を0.0に圧縮する線形フロアの代わりに、有界な相対不確実性比を使用します:
$$\text{Confidence} = \frac{1}{1 + \frac{p_{90} - p_{10}}{\vert p_{50}\vert + \epsilon}}$$
ここで$\epsilon = 10^{-5}$です。特性:
出力範囲$(0, 1]$ — 負になることはなく、0に圧縮されることもありません
スプレッド$(p_{90} - p_{10}) \to 0$のとき、信頼度は$\to 1$(タイトな境界)
スプレッドが$\to \infty$のとき、信頼度は漸近的に$\to 0$(極端な不確実性)
中央値の大きさ$|p_{50}|$による除算でスケール不変
エージェンティックアーキテクチャ非依存
ステートレスでスキーマにバインドされたMCPツールマイクロサービスとして、このエンジンは、OPA/Regoポリシーで管理されるニューロシンボリックスタック、LangGraphステートマシン、CrewAIスウォーム、標準的なReActループなど、あらゆるエージェントオーケストレーターとシームレスに統合します。
MCPツール仕様とAPI契約
forecast_demand
単一の時系列予測。
リクエスト(TimeSeriesInputPayload)
{
"target_series": [120.5, 115.0, 130.2, 125.8, 140.1],
"forecast_horizon": 30,
"price_index": [19.99, 19.99, 24.99, 24.99, 24.99, 24.99, ...],
"promo_flag": [0, 0, 1, 0, 1, 0, ...]
}レスポンス(ForecastResponse)
{
"model_used": "Chronos-2-Fallback",
"mean_prediction": [142.3, 145.1, 140.8, 148.2, 150.0],
"p10_quantile": [120.1, 122.4, 118.7, 125.3, 127.9],
"p50_quantile": [142.3, 145.1, 140.8, 148.2, 150.0],
"p90_quantile": [165.2, 168.5, 162.1, 170.4, 172.8],
"confidence_score": 0.87,
"horizon_length": 30,
"exogenous_dropped": false,
"warnings": ["CUDA unavailable; running on CPU. Expect degraded inference performance."]
}forecast_batch
アイテムごとのフォールバックサマリーを備えた、配列ベースのマルチSKU予測。
リクエスト
{
"payloads": [
{"target_series": [10.0]*20, "forecast_horizon": 5},
{"target_series": [11.0]*30, "forecast_horizon": 3, "price_index": [20.0]*33}
]
}レスポンス
{
"results": [
{"model_used": "Chronos-2-Fallback", "mean_prediction": [...], ...},
{"model_used": "TimesFM-2.5", "mean_prediction": [...], ...}
],
"summary": {
"total": 2,
"errors": 0,
"model_usage": {"Chronos-2-Fallback": 1, "TimesFM-2.5": 1}
}
}AgentFriendlyError
検証または実行の失敗時に返される自己修正エラースキーマ。
{
"error_code": "VALIDATION_ERROR",
"message": "Input validation failed at 'price_index': Price array misalignment. Expected 25 elements (Context: 20 + Horizon: 5), got 2.",
"expected": "Payload matching TimeSeriesInputPayload schema (context 16-16000 finite values, aligned exogenous signals).",
"received": "{\"location\": \"price_index\", \"message\": \"Price array misalignment. Expected 25 elements (Context: 20 + Horizon: 5), got 2.\", \"context\": {\"expected\": \"25\", \"got\": \"2\"}}",
"remediation_suggestion": "Correct field 'price_index' (Price array misalignment. Expected 25 elements (Context: 20 + Horizon: 5), got 2.) and resubmit. Ensure context length is between 16 and 16000, values are finite (no NaN/Inf), and exogenous arrays align to len(target_series) + forecast_horizon."
}エラーコード:VALIDATION_ERROR、MODEL_UNAVAILABLE、TRANSIENT_FAILURE、MODEL_FAILURE、INTERNAL_ERROR
クイックスタートとMCP設定
インストール
# Requires Python 3.11+
uv sync --extra gpu # or: pip install -r requirements.txt環境
# Optional: force CPU if GPU memory constrained
export MODEL_CONFIG_PATH=configs/model_config.yaml
export DATA_STORAGE_ROOT=data/エンジンはCUDAを自動検出します。利用できない場合はCPUにフォールバックし、warningsフィールドに警告を出力します。
MCPクライアント設定(Claude Desktop / OpenCode / LangGraph / CrewAI)
MCPクライアント設定(claude_desktop_config.json、opencode.json、または同等のもの)に追加します:
{
"mcpServers": {
"zero-shot-forecaster": {
"command": "python",
"args": ["mcp_server.py"],
"cwd": "/absolute/path/to/zero-shot-demand-foundation",
"env": {
"MODEL_CONFIG_PATH": "configs/model_config.yaml"
}
}
}
}MCPクライアントを再起動します。ツールforecast_demandとforecast_batchが完全なJSONスキーマとともに自動登録されます。
呼び出し例(Claude / LLMエージェント)
{
"tool": "forecast_demand",
"arguments": {
"target_series": [120, 115, 130, 125, 140, 135, 150, 145, 155, 160, 155, 165, 170, 168, 172, 175, 180, 178, 185, 190],
"forecast_horizon": 7,
"price_index": [19.99, 19.99, 19.99, 19.99, 19.99, 19.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99],
"promo_flag": [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
}
}検証とテスト
完全なテストスイートを実行(62テスト、AC-1からAC-5)
uv run pytest tests/ -q
# or
python -m pytest tests/ -q期待される出力:
.............................................................. [100%]
62 passed in ~3sテストカバレッジマトリックス
AC | 基準 | テスト関数 |
AC-1 | ノンブロッキングイベントループ |
|
AC-2 | 遅延ロードとVRAM節約 |
|
AC-3 | グレースフルフォールバックとシグナル除去 |
|
AC-4 | CUDA OOMリカバリ |
|
AC-5 | エージェント自己修正ペイロード |
|
レガシーテスト(後方互換性)
元の48件のテストはすべて引き続き成功しています:
pytest tests/test_forecasting_engine.py tests/test_forecaster_router.py tests/test_mcp_server.py tests/test_schemas.py tests/test_metrics.py -qプロジェクト構造(リファクタリング後)
zero-shot-demand-foundation/
├── configs/
│ └── model_config.yaml # Model IDs, device_map, num_samples
├── data/ # Git-ignored (CSV, ZIP)
├── scripts/
│ ├── download_m5.py # M5 dataset fetcher
│ └── download_favorita.py # Favorita dataset fetcher
├── src/
│ ├── models/
│ │ └── forecaster.py # ZeroShotForecastingEngine (refactored)
│ ├── schemas/
│ │ └── payloads.py # TimeSeriesInputPayload, ForecastResponse, AgentFriendlyError
│ └── utils/
│ ├── data_loader.py # DemandDataEngine, FavoritaDataLoader
│ └── metrics.py # WAPE, RMSSE, Pinball Loss, CRPS
├── tests/
│ ├── test_forecasting_engine.py # Updated for lazy loading
│ ├── test_forecaster_router.py # Updated fixtures
│ ├── test_mcp_server.py # Async + AgentFriendlyError
│ ├── test_metrics.py # Unchanged
│ ├── test_schemas.py # Unchanged
│ └── test_refactored_forecaster.py # NEW: AC-1..5 coverage
├── main.py # CLI evaluation entry point
├── mcp_server.py # FastMCP server (async, batch, errors)
├── requirements.txt
├── .gitignore # Ignores *.md, data/, __pycache__/
└── README.md # This fileライセンス
MITライセンス。詳細はLICENSEを参照してください。
参考文献
Chronos-2: Ansari et al., Chronos: Learning the Language of Time Series, arXiv:2403.07815
TimesFM: Das et al., TimesFM: A Decoder-Only Foundation Model for Time-Series Forecasting, arXiv:2402.02592
M5 Competition: Makridakis et al., M5 Accuracy Competition, IJF 2022
Corporación Favorita: Kaggle Favorita Grocery Sales Forecasting
Model Context Protocol: Anthropic MCP Specification
This server cannot be deployed
Maintenance
Related MCP Connectors
Probabilistic time-series forecasts from zero-shot foundation models: routed, single or ensembled.
Forecast product demand using historical sales and market signals.
Market forecasts with their own track record, inside Claude, ChatGPT and other MCP apps.
PredictOracle - 12 forecasting tools: time-series, scenario analysis, risk projections.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server powered by Meta's Prophet that enables LLMs to perform time-series forecasting, trend analysis, and predictive modeling on historical data. It provides LLM-friendly statistical summaries, automated business-rule validation, and ready-to-render Chart.js visualizations.MIT
- AlicenseBqualityDmaintenanceEnable any AI agent to forecast time-series data (e.g., sales, traffic) using Google's TimesFM or a zero-dependency statistical baseline.3Apache 2.0
- AlicenseNot gradedqualityDmaintenancePredictive supply-chain MCP server that forecasts material confirmation risks and enables AI clients to interact with the system via natural language.MIT
- FlicenseAqualityCmaintenanceEnables demand forecasting and replenishment recommendations using statistical models (Syntetos-Boylan classification, AutoETS, TSB) and provides tools for forecasting, evaluation, and order quantity calculation.6-