Skip to main content
Glama

BanditDB Python SDK

BanditDB 的官方 Python 客户端和 Model Context Protocol(MCP)服务器——一个用 Rust 编写的超快、无锁的 Contextual Bandit 数据库。

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}")

所有客户端方法

健康检查

Method

描述

health()

如果服务器可访问且 WAL 写入器健康,则返回 True

health_detail()

返回完整的健康状态字典,包括每个 campaign 的 entropystatus"ok" / "warning" / "critical")。

Campaign 管理

Method

描述

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

注册一个新的 campaign。algorithm 接受 "linucb""thompson_sampling"NeuralLinUCBConfigProgressiveConfigmetadata 是任意的 JSON 字典(≤ 64 KB)。

list_campaigns()

返回所有 campaign(活跃和已归档)的列表,包含 alphaarm_countalgorithm

campaign_info(campaign_id)

返回每个 arm 的完整状态:thetatheta_norm、预测和奖励计数器。如果未找到,则引发 APIError(404)。

report(campaign_id)

业务层面的收敛报告。converged=True 表示某个 arm 在 95% 置信区间下具有统计显著的领先优势——可以安全停止。converged=False 表示有领先但置信区间仍然重叠。converged=None 表示数据量尚不足(每个 arm 少于 30 个奖励)。

diagnostics(campaign_id)

运营诊断:每个 arm 的 theta 范数、A_inv 不确定性界限、熵健康状态(selection_entropyentropy_statusentropy_trendlikely_causesuggested_action)、锦标赛流量和神经缓冲区大小。

archive_campaign(campaign_id)

软删除:暂停预测/奖励,但保留所有已学习的权重。可通过 restore_campaign() 恢复。

restore_campaign(campaign_id)

将已归档的 campaign 恢复到活跃状态,并保留所有权重不变。

delete_campaign(campaign_id)

永久删除 campaign。如果未找到,返回 False

预测与奖励

Method

描述

predict(campaign_id, context)

返回 (arm_id, interaction_id)。将 interaction_id 传给 reward() 以闭环。

batch_predict(predictions)

在单次往返中为最多 100 个 campaign/context 对进行预测。每个条目:{"campaign_id": str, "context": List[float]}。返回每个条目的 {arm_id, interaction_id}{error} 列表。

reward(interaction_id, reward)

记录结果。reward 必须在 [0.0, 1.0] 范围内。如果交互已被奖励或已过期(默认 TTL:24 小时),则引发 APIError

数据与导出

Method

描述

checkpoint()

刷新 WAL、对模型做快照、写入 Parquet 分片、运行神经重训练和锦标赛评估、轮转 WAL。返回摘要字符串。

export()

列出按 campaign 分组的 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"
      }
    }
  }
}

该智能体蜂群现在拥有九个工具:

Tool

功能

create_campaign

创建新的决策 campaign。接受 algorithm"linucb""thompson_sampling")和 alpha。使用 Thompson Sampling 可实现自然的贝叶斯探索,无需调优。

list_campaigns

列出所有活跃 campaign(显示 algorithmalpha)——在调用 get_intuition 之前检查已有内容时很有用。

campaign_diagnostics

检查每个 arm 的学习状态:theta_norm、预测次数、奖励率和熵健康状态。当某个 campaign 似乎没有在学习或某个 arm 占据主导时使用。

campaign_report

业务层面的收敛报告。告诉你 campaign 是否在统计上已收敛,以及哪个 arm 以置信区间获胜。

get_intuition

询问 BanditDB 在给定 context 下应选择哪个 arm。返回该 arm 以及一个用于保存的 interaction_id

batch_get_intuition

在单次往返中获取多个 campaign 的决策。传入 {campaign_id, context} 字典列表。

record_outcome

报告所选动作是成功(1.0)还是失败(0.0)。更新共享模型。

archive_campaign

软删除 campaign。暂停预测/奖励,但保留所有已学习的权重。

restore_campaign

将已归档的 campaign 恢复到活跃状态,并保留所有权重不变。

网络中任何智能体做出的每个决策都会改进所有未来智能体的路由。


3. 数据科学与离线评估

BanditDB 将每个预测和奖励以事件源的方式写入 Write-Ahead Log(WAL)。调用 checkpoint() 会把已完成的 prediction→reward 对编译为 Snappy 压缩的 Parquet 文件——每个 campaign 一个——供使用 Polars 或 Pandas 进行离线分析。

即使奖励在数小时后才到达,每个预测也保证出现在 Parquet 文件中:BanditDB 会在每次 checkpoint 时重新发出进行中的交互,因此延迟的奖励总会在后续周期中被捕获。

# 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 中提供了三种 OPE 估计器。它们回答的问题是:"如果采用不同的策略,我的平均奖励会是多少——而无需运行实时实验?"

安装评估依赖项:

pip install "banditdb-python[eval]"

Estimator

Function

工作原理

何时使用

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 校正。如果奖励模型或倾向得分中有一个正确,则估计是一致的。

统计效率最佳。在比较多个策略或扫描 alpha 时使用。

所有三种估计器:

  • 接受从 BanditDB Parquet 导出加载的 Polars 或 pandas DataFrame

  • 均匀随机策略评估为目标(需要超越的无偏基线)

  • 对 Thompson Sampling 活动抛出 ValueError(倾向性列为空 — TS 不记录倾向性)

  • 返回包含 estimatestd_errorn_usedn_totalmethodOPEResult

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 倾向性,因为 TS 臂选择是随机的,而倾向性评分需要确定性日志策略。


选择算法

BanditDB 支持四种算法,在活动创建时选择。

算法

algorithm

探索方式

使用时机

LinUCB

"linucb"(默认)

确定性 UCB 奖励:θ·x + α√(x·A⁻¹·x)

可预测、可调。离线扫描 alpha 以校准。

线性 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)

所有四种算法共享相同的 predictreward 循环。


错误处理

异常

抛出时机

BanditDBError

基础异常 — 捕获此异常以处理所有 SDK 错误。

ConnectionError

服务器离线或无法访问。

TimeoutError

请求超过配置的超时时间。

APIError

服务器返回错误(例如,活动未找到、未授权)。


许可证

Apache-2.0 — 版权所有 (C) 2026 Simeon Lukov 和 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