Skip to main content
Glama

BanditDB Python SDK

Официальный Python-клиент и сервер Model Context Protocol (MCP) для BanditDB — сверхбыстрой, неблокирующей базы данных контекстуальных бандитов, написанной на Rust.

BanditDB скрывает сложную линейную алгебру обучения с подкреплением (LinUCB, семплирование Томпсона) за предельно простым API. Создавайте персонализаторы реального времени, динамические A/B-тесты и давайте LLM-агентам математически строгую постоянную память.

Установка

pip install banditdb-python

Требуется запущенный Rust-сервер BanditDB (по умолчанию: 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()

Возвращает True, если сервер доступен и WAL-писатель исправен.

health_detail()

Возвращает полный словарь состояния, включая entropy и status ("ok" / "warning" / "critical") по каждой кампании.

Кампании

Метод

Описание

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

Зарегистрировать новую кампанию. algorithm принимает "linucb", "thompson_sampling", NeuralLinUCBConfig или ProgressiveConfig. metadata — произвольный JSON-словарь (≤ 64 КБ).

list_campaigns()

Возвращает список всех кампаний (активных и архивных) с alpha, arm_count и algorithm.

campaign_info(campaign_id)

Возвращает полное состояние по каждому arm: theta, theta_norm, счётчики предсказаний и наград. Вызывает APIError (404), если не найдено.

report(campaign_id)

Отчёт о сходимости на бизнес-уровне. converged=True означает, что один arm имеет статистически значимое преимущество при 95% ДИ — можно останавливаться. converged=False означает лидерство, но доверительные интервалы всё ещё пересекаются. converged=None означает недостаточно данных (< 30 наград на arm).

diagnostics(campaign_id)

Операторская диагностика: нормы theta по arm, границы неопределённости A_inv, состояние энтропии (selection_entropy, entropy_status, entropy_trend, likely_cause, suggested_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_id в reward(), чтобы замкнуть цикл.

batch_predict(predictions)

Предсказание для до 100 пар кампания/контекст за один запрос. Каждый элемент: {"campaign_id": str, "context": List[float]}. Возвращает список {arm_id, interaction_id} или {error} для каждого элемента.

reward(interaction_id, reward)

Записать результат. reward должен быть в диапазоне [0.0, 1.0]. Вызывает APIError, если взаимодействие уже было вознаграждено или истекло (TTL по умолчанию: 24 ч).

Данные и экспорт

Метод

Описание

checkpoint()

Сброс WAL, снимок моделей, запись Parquet-шардов, нейронное переобучение + турнирная оценка, ротация WAL. Возвращает сводную строку.

export()

Список Parquet-шардов экспорта, сгруппированных по кампаниям. Возвращает {export_dir, shards}.


2. ИИ-«коллективный разум» (Model Context Protocol)

Стандартные LLM-агенты не имеют состояния — если они направляют задачу не той модели и терпят неудачу, завтра они повторят ту же ошибку. Встроенный MCP-сервер BanditDB даёт всему рою агентов общую постоянную память.

Запуск 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"
      }
    }
  }
}

Теперь у роя агентов есть девять инструментов:

Инструмент

Что делает

create_campaign

Создать новую кампанию принятия решений. Принимает algorithm ("linucb" или "thompson_sampling") и alpha. Используйте семплирование Томпсона для естественной байесовской разведки без настройки.

list_campaigns

Список всех активных кампаний (показывает algorithm и alpha) — полезно проверить, что существует, перед вызовом get_intuition.

campaign_diagnostics

Проверить состояние обучения по каждому arm: theta_norm, количество предсказаний, частоту наград и состояние энтропии. Используйте, когда кампания, похоже, не обучается или один arm доминирует.

campaign_report

Отчёт о сходимости на бизнес-уровне. Сообщает, достигла ли кампания статистической сходимости и какой arm выигрывает с доверительными интервалами.

get_intuition

Спросить BanditDB, какой arm выбрать для данного контекста. Возвращает arm и interaction_id для сохранения.

batch_get_intuition

Получить решения для нескольких кампаний за один запрос. Передайте список словарей {campaign_id, context}.

record_outcome

Сообщить, успешно ли выбранное действие (1.0) или нет (0.0). Обновляет общую модель.

archive_campaign

Мягкое удаление кампании. Приостанавливает предсказания/награды, но сохраняет все обученные веса.

restore_campaign

Восстановить архивную кампанию в активный статус со всеми весами.

Каждое решение, принятое любым агентом в сети, улучшает маршрутизацию для всех будущих агентов.


3. Наука о данных и офлайн-оценка

BanditDB записывает каждое предсказание и награду в журнал упреждающей записи (WAL). Вызов checkpoint() компилирует завершённые пары предсказание→награда в 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 включает три OPE-оценщика в banditdb.eval. Они отвечают на вопрос: «какой была бы моя средняя награда при другой политике — без проведения живого эксперимента?»

Установите зависимости для оценки:

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-коррекцию к остаткам. Состоятелен, если верна либо модель награды, либо пропенсити.

Наилучшая статистическая эффективность. Используйте при сравнении нескольких политик или переборе alpha.

Все три оценщика:

  • Принимает DataFrame Polars или pandas, загруженный из экспорта BanditDB Parquet

  • Оценивает равномерную случайную политику как целевую (непредвзятый базовый уровень, который нужно превзойти)

  • Вызывает ValueError для кампаний Thompson Sampling (столбец propensity равен null — TS не логирует склонности)

  • Возвращает OPEResult с estimate, std_error, n_used, n_total и method

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, затем воспроизведите различные значения alpha через doubly_robust(), чтобы найти лучший уровень исследования — без необходимости живого эксперимента.

Примечание: 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 в пространстве встраивания

Нелинейные функции вознаграждения. Переобучает MLP каждые N вознаграждений.

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 — 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