Skip to main content
Glama

BanditDB Python SDK

BanditDB — Rust で書かれた超高速・ロックフリーの Contextual Bandit データベース — の公式 Python クライアント兼 Model Context Protocol (MCP) サーバーです。

BanditDB は、強化学習 (LinUCB、Thompson Sampling) の複雑な線形代数を、極めてシンプルな API の背後に隠蔽します。リアルタイムのパーソナライザー、動的な A/B テストを構築し、LLM エージェントに数学的に厳密な永続メモリを提供します。

インストール

pip install banditdb-python

BanditDB Rust サーバーが実行中である必要があります (デフォルト: http://localhost:8080)。


Related MCP server: Copilot Memory Store

1. 標準 SDK の使用方法

このクライアントは、自動コネクションプーリング、指数バックオフリトライ、厳格なタイムアウトを備えています。

from banditdb import Client, BanditDBError

# Connect to the BanditDB server.
# Pass api_key if BANDITDB_API_KEY is set on the server.
db = Client(
    url="http://localhost:8080",
    timeout=2.0,
    api_key="your-secret-key",   # omit if server runs without auth
)

try:
    # 1. Create a campaign (run once at startup)
    # algorithm defaults to "linucb"; use "thompson_sampling" for Bayesian exploration
    db.create_campaign(
        campaign_id="checkout_upsell",
        arms=["offer_discount", "offer_free_shipping"],
        feature_dim=3,
    )
    # or: db.create_campaign(..., algorithm="thompson_sampling")

    # 2. A user arrives — ask the database what to show them
    # Context: [is_mobile, cart_value_normalized, is_returning_user]
    arm_id, interaction_id = db.predict("checkout_upsell", [1.0, 0.8, 0.0])
    print(f"Showing: {arm_id}")  # e.g., "offer_free_shipping"

    # 3. The user clicked — send the reward
    db.reward(interaction_id, reward=1.0)

except BanditDBError as e:
    print(f"Database error: {e}")

クライアントの全メソッド

ヘルス

メソッド

説明

health()

サーバーに到達可能で WAL ライターが正常な場合に True を返します。

health_detail()

キャンペーンごとの entropystatus ("ok" / "warning" / "critical") を含む完全なヘルス dict を返します。

キャンペーン

メソッド

説明

create_campaign(campaign_id, arms, feature_dim, alpha=1.0, algorithm="linucb", metadata=None)

新しいキャンペーンを登録します。algorithm には "linucb""thompson_sampling"NeuralLinUCBConfig、または ProgressiveConfig を指定できます。metadata は任意の JSON dict です (≤ 64 KB)。

list_campaigns()

すべてのキャンペーン (アクティブおよびアーカイブ済み) のリストを alphaarm_countalgorithm とともに返します。

campaign_info(campaign_id)

アームごとの完全な状態 (thetatheta_norm、予測カウンター、報酬カウンター) を返します。見つからない場合は APIError (404) を発生させます。

report(campaign_id)

ビジネスレベルの収束レポートです。converged=True は、いずれかのアームが 95% CI で統計的に有意なリードを持っていることを意味し、停止しても安全です。converged=False はリードしているが CI がまだ重なっていることを意味します。converged=None はまだデータが十分でないことを意味します (アームあたり 30 報酬未満)。

diagnostics(campaign_id)

運用者向け診断情報: アームごとの theta ノルム、A\_inv 不確実性境界、エントロピーヘルス (selection_entropyentropy_statusentropy_trendlikely_causesuggested_action)、トーナメントトラフィック、ニューラルバッファサイズ。

archive_campaign(campaign_id)

ソフト削除: 予測/報酬を一時停止しますが、学習済みの重みはすべて保持します。restore_campaign() で復元できます。

restore_campaign(campaign_id)

アーカイブ済みキャンペーンをすべての重みを保持したままアクティブ状態に復元します。

delete_campaign(campaign_id)

キャンペーンを完全に削除します。見つからない場合は False を返します。

予測と報酬

メソッド

説明

predict(campaign_id, context)

(arm_id, interaction_id) を返します。interaction_idreward() に渡してループを閉じます。

batch_predict(predictions)

1 回のラウンドトリップで最大 100 件のキャンペーン/コンテキストペアを予測します。各項目は {"campaign_id": str, "context": List[float]} です。項目ごとに {arm_id, interaction_id} または {error} のリストを返します。

reward(interaction_id, reward)

結果を記録します。reward[0.0, 1.0] の範囲内である必要があります。インタラクションがすでに報酬を受け取っているか、期限切れの場合 (デフォルト TTL: 24 時間) は APIError を発生させます。

データとエクスポート

メソッド

説明

checkpoint()

WAL をフラッシュし、モデルをスナップショットし、Parquet シャードを書き出し、ニューラル再トレーニング + トーナメント評価を実行し、WAL をローテーションします。サマリー文字列を返します。

export()

キャンペーンごとにグループ化された Parquet エクスポートシャードをリストします。{export_dir, shards} を返します。


2. AI「ハイブマインド」(Model Context Protocol)

標準的な LLM エージェントはステートレスです。タスクを誤ったモデルにルーティングして失敗した場合、翌日も同じ過ちを繰り返します。BanditDB 組み込みの MCP サーバーは、エージェントの群れ全体に共有の永続メモリを提供します。

MCP サーバーの起動

# Set environment variables before starting
export BANDITDB_URL=http://localhost:8080
export BANDITDB_API_KEY=your-secret-key   # omit if server runs without auth

banditdb-mcp

Claude Desktop への接続

Claude 設定ファイルに追加します:

  • Mac: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "banditdb": {
      "command": "banditdb-mcp",
      "args": [],
      "env": {
        "BANDITDB_URL": "http://localhost:8080",
        "BANDITDB_API_KEY": "your-secret-key"
      }
    }
  }
}

エージェントの群れは、現在 9 つのツールを利用できます:

ツール

機能

create_campaign

新しい意思決定キャンペーンを作成します。algorithm ("linucb" または "thompson_sampling") と alpha を受け付けます。チューニング不要の自然なベイズ探索には Thompson Sampling を使用してください。

list_campaigns

すべてのアクティブなキャンペーンをリストします (algorithmalpha を表示)。get_intuition を呼び出す前に何が存在するかを確認するのに便利です。

campaign_diagnostics

アームごとの学習状態 (theta_norm、予測回数、報酬率、エントロピーヘルス) を検査します。キャンペーンが学習していないように見える場合や、1 つのアームが支配的になっている場合に使用します。

campaign_report

ビジネスレベルの収束レポートです。キャンペーンが統計的に収束したかどうか、どのアームが信頼区間付きで勝っているかを示します。

get_intuition

指定されたコンテキストに対して BanditDB にどのアームを選ぶべきかを尋ねます。アームと保存用の interaction_id を返します。

batch_get_intuition

1 回のラウンドトリップで複数のキャンペーンの意思決定を取得します。{campaign_id, context} dict のリストを渡します。

record_outcome

選択したアクションが成功 (1.0) か失敗 (0.0) かを報告します。共有モデルを更新します。

archive_campaign

キャンペーンをソフト削除します。予測/報酬を一時停止しますが、学習済みの重みはすべて保持します。

restore_campaign

アーカイブ済みキャンペーンをすべての重みを保持したままアクティブ状態に復元します。

ネットワーク内の任意のエージェントによるすべての意思決定は、将来のすべてのエージェントのルーティングを改善します。


3. データサイエンスとオフライン評価

BanditDB はすべての予測と報酬を Write-Ahead Log (WAL) にイベントソーシングします。checkpoint() を呼び出すと、完了した予測→報酬ペアが、キャンペーンごとに 1 つの Snappy 圧縮 Parquet ファイルにコンパイルされ、Polars や Pandas によるオフライン分析に使用できます。

報酬が数時間後に到着した場合でも、すべての予測は Parquet ファイルに確実に含まれます。BanditDB は各チェックポイントで処理中のインタラクションを再出力するため、遅延した報酬は常に将来のサイクルで捕捉されます。

# Checkpoint: snapshot models, write Parquet, rotate the WAL.
# Call this on a schedule or after significant traffic.
summary = db.checkpoint()
print(summary)
# "Checkpoint written and WAL rotated: 2 campaigns, offset 4821 bytes,
#  150 interactions exported, 3 in-flight re-emitted"

# List which Parquet files are available
print(db.export())
# 'Parquet files in /data/exports: ["llm_routing.parquet"]'

# Load directly from the mounted volume into Polars.
# Flat schema: interaction_id | arm_id | reward | predicted_at | rewarded_at | propensity | feature_0 | ...
import polars as pl
df = pl.read_parquet("/data/exports/llm_routing.parquet")
print(df.head())
print(df.columns)

オフラインポリシー評価 (OPE)

SDK の banditdb.eval には 3 つの OPE 推定器が同梱されています。これらは次の問いに答えます: 「ライブ実験を実行せずに、別のポリシーの下での平均報酬はどうなっていただろうか?」

評価用の依存関係をインストールします:

pip install "banditdb-python[eval]"

推定器

関数

動作

使用場面

Replay

replay(df)

各インタラクションを確率 (1/K) / propensity で受け入れます (Li et al. 2010)。一様ランダムポリシーの不偏サンプルです。

ベースラインの健全性チェック。カバレッジが低いのは想定どおりで、インタラクションの ~1/K が使用されます。

IPS / SNIPS

ips(df, clip=10.0)

重要度重み (1/K) / propensity を使用してすべてのインタラクションを使用します。分散を減らすために自己正規化されます。重みクリッピング (デフォルト 10 倍) はバイアスと分散のトレードオフを制御します。

主要な推定器。十分なデータがあるが完全なカバレッジが必要な場合に使用します。

Doubly Robust

doubly_robust(df, clip=10.0)

線形報酬モデルを適合させ、残差に IPS 補正を適用します。報酬モデルまたは propensity のいずれかが正しければ、一致推定量です。

最良の統計的効率。複数のポリシーを比較する場合や alpha をスイープする場合に使用します。

3 つの推定器はすべて:

  • BanditDB の Parquet エクスポートから読み込まれた Polars または pandas DataFrame を受け付ける

  • ターゲットとして一様ランダムポリシーを評価する(打ち負かすべき不偏ベースライン)

  • Thompson Sampling キャンペーンでは ValueError を発生させる(propensity 列が null の場合 — TS は propensity を記録しない)

  • estimatestd_errorn_usedn_totalmethod を含む OPEResult を返す

import polars as pl
from banditdb.eval import replay, ips, doubly_robust

df = pl.read_parquet("/data/exports/llm_routing.parquet")

# How much reward would a uniform random policy have earned?
print(replay(df))
# OPEResult(method='replay', estimate=0.4821, std_error=0.0312, coverage=22.1% [33/149])

print(ips(df))
# OPEResult(method='ips', estimate=0.5103, std_error=0.0187, coverage=100.0% [149/149])

print(doubly_robust(df))
# OPEResult(method='doubly_robust', estimate=0.5219, std_error=0.0141, coverage=100.0% [149/149])

# Compare against the observed reward of the logging policy:
print("Observed (logging policy):", df["reward"].mean())
# If observed >> estimate, the campaign has learned something real — it outperforms random.

実用的な使い方: デプロイ前にオフラインで alpha をスイープする。 実トラフィックでキャンペーンをトレーニングし、Parquet にチェックポイントを保存してから、doubly_robust() でさまざまな alpha 値をリプレイして最適な探索レベルを見つける — ライブ実験は不要。

注: OPE には propensity 列が必要です。この列は LinUCB キャンペーンでのみ書き込まれます。Thompson Sampling キャンペーンでは null の propensity が記録されます。TS のアーム選択は確率的であり、propensity スコアリングには決定論的なロギングポリシーが必要だからです。


アルゴリズムの選択

BanditDB はキャンペーン作成時に選択できる4つのアルゴリズムをサポートしています。

アルゴリズム

algorithm

探索スタイル

使用場面

LinUCB

"linucb"(デフォルト)

決定論的 UCB ボーナス: θ·x + α√(x·A⁻¹·x)

予測可能で調整可能。オフラインで alpha をスイープしてキャリブレーションする。

Linear Thompson Sampling

"thompson_sampling"

θ̃ ~ N(θ, α²·A⁻¹) をサンプリングし、θ̃·x でスコアリングする

ベイズ事後分布 — alpha スイープは不要。同時ユーザーは自動的に選択肢を多様化する。

NeuralLinUCB

NeuralLinUCBConfig(...)

深層 MLP エンベディング + エンベディング空間での LinUCB

非線形の報酬関数。N 報酬ごとに MLP を再トレーニングする。

Progressive

ProgressiveConfig(...)

自己調整トーナメント: ベースとチャレンジャーを並列実行し、トラフィックを勝者にシフトする

設定不要のモデル選択。最適なアルゴリズムを自動的に選択する。

from banditdb import Client, NeuralLinUCBConfig, ProgressiveConfig

db = Client("http://localhost:8080")

# LinUCB (default)
db.create_campaign("routing", ["fast", "cheap"], feature_dim=4, alpha=1.5)

# Thompson Sampling — natural Bayesian exploration, alpha=1.0 is ideal
db.create_campaign("routing_ts", ["fast", "cheap"], feature_dim=4,
                   algorithm="thompson_sampling")

# NeuralLinUCB — learns a deep embedding of the context, then applies LinUCB
cfg = NeuralLinUCBConfig(
    context_dim=4,     # must match feature_dim
    embed_dim=32,      # arm matrix dimension (default 32)
    hidden_dim=128,    # MLP hidden layer width (default 128)
    retrain_every=200, # retrain the MLP every N cumulative rewards
)
db.create_campaign("routing_neural", ["fast", "cheap"], feature_dim=4, algorithm=cfg)

# Progressive — runs LinUCB vs NeuralLinUCB, shifts traffic to whoever wins SNIPS checkpoints
cfg = ProgressiveConfig(
    base="linucb",
    challenger=NeuralLinUCBConfig(context_dim=4, embed_dim=32),
    min_obs=100,       # minimum buffer entries per arm before any traffic shift
    required_wins=3,   # consecutive checkpoint wins to earn one traffic step
    step_bps=1000,     # traffic delta per win run, in basis points (1000 = 10%)
)
db.create_campaign("routing_prog", ["fast", "cheap"], feature_dim=4, algorithm=cfg)

4つのアルゴリズムはすべて同じ predictreward ループを共有しています。


エラーハンドリング

例外

発生条件

BanditDBError

基本例外 — すべての SDK エラーを処理するにはこれをキャッチする。

ConnectionError

サーバーがオフラインまたは到達不能である。

TimeoutError

リクエストが設定されたタイムアウトを超えた。

APIError

サーバーがエラーを返した(例: キャンペーンが見つからない、未認可)。


ライセンス

Apache-2.0 — Copyright (C) 2026 Simeon Lukov and Dynamic Pricing Ltd. 詳細はメインリポジトリを参照してください。

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dynamicpricing-ai/banditdb-python'

If you have feedback or need assistance with the MCP directory API, please join our Discord server