AAYMA
RU
Войти

SignBridge tariff campaign agent

Агент выбора тарифных кампаний для абонентов: проводит SMS-пилоты, обновляет байесовскую модель и выбирает сегмент, целевой тариф и канал, чтобы…

Рабочий MVP
Команда «signBridge» 7💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: signBridge
Кейс HackAlem.ai: Телеком — Beeline
Стадия: Рабочий MVP

Задача кейса: Агент, который решает, каким абонентам какой тариф предложить (чистый прирост ARPU)

Суть

Агент выбора тарифных кампаний для абонентов: проводит SMS-пилоты, обновляет байесовскую модель и выбирает сегмент, целевой тариф и канал, чтобы максимизировать чистый прирост ARPU. Результаты объясняет React-демо.

Как устроено

context/agent.py получает профили абонентов, справочник тарифов, стоимость каналов и лимиты. Первые 4 SMS-пилота проверяют гипотезы из анализа истории смен тарифов, пятый исследует новую крупную группу. BayesianPilotModel (байесовская линейная модель на признаках ARPU, размера группы, разницы цен и сегмента) обновляется после каждого пилота. Следующие гипотезы ранжируются по верхней оценке выгоды. Финальные кампании проходят риск-фильтр и ограничения бюджета и каналов, каналы сравниваются по результату на всю доступную аудиторию. Скрипты local_eval, benchmark и stress_eval проверяют план на мок-скорере.

Ключевые решения

  • Bayesian linear regression
  • UCB-подобная разведка (bandit)
  • risk filter
  • budget/channel constraints
  • stress testing по seed

Метрики

50 seed: 50/50 положительных; медиана ML 2 547 678 у.е. против 2 582 253 у.е. у фиксированной очереди; ML выше в 30/50 парных прогонов, медиана парной разницы +6 602 у.е.

Особенности

Модель учится онлайн прямо во время прогона на шумных результатах пилотов, без доступа к скрытым эффектам. Небольшое и нестабильное преимущество над фиксированной очередью README признаёт прямо. Есть стресс-сценарии (эффекты вдвое слабее, провал гипотез) и экран «Битва стратегий».

Стек

Python · NumPy · pandas · React · TypeScript · Rsbuild · Ant Design · Tailwind CSS · TanStack Query · Docker Compose


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-54febda9-signbridge.

README

README.md

SignBridge tariff campaign agent

Репозиторий для агента, который выбирает тарифные кампании по профилям абонентов и результатам пилотов. Подробности кейса — в context/PARTICIPANT_GUIDE.md.

Стек

  • Python 3.11
  • NumPy и pandas — зависимости закреплены в requirements.txt
  • React 19, TypeScript, Rsbuild, Ant Design 6, Tailwind CSS и TanStack Query — компонентный интерфейс в frontend/
  • Docker Compose — воспроизводимый запуск проверки, генерации отправки и веб-демо

Сдаваемый агент остаётся отдельным файлом context/agent.py. Веб-демо предназначено для локального просмотра его решений: React-приложение показывает данные, а небольшой Python-сервер на стандартной библиотеке рассчитывает мок-прогон и отдаёт API для запуска, проверки устойчивости и сравнения стратегий. FastAPI, Redis и другие зависимости backend-проекта сюда не переносились.

Как работает решение

  1. context/agent.py получает профиль абонентов, справочник тарифов, стоимость каналов и остатки лимитов через документированный интерфейс среды.
  2. Первые четыре SMS-пилота проверяют сильные гипотезы из исторического анализа. Пятый проверяет одну крупную группу, отсутствующую в исходном списке: агент переносит уже известный переход тарифа на другой ARPU-сегмент и выбирает группу по потенциальному охвату. Это разведка, а не предположение о положительном эффекте.
  3. После каждого SMS-пилота байесовская ML-модель обновляет прогноз. Остальные пилоты выбираются по ожидаемой выгоде и неопределённости. Дорогие каналы проверяются отдельно, если могут занять значительную часть бюджета.
  4. Агент выбирает сегмент, целевой тариф и канал для финальных кампаний. Каналы сравниваются по ожидаемому результату всей доступной аудитории после учёта бюджета и возможного сужения фильтра, а не только по выгоде на одного абонента.
  5. context/local_eval.py проверяет полученный план на синтетической мок-модели через context/scoring_core.py. context/web_app.py отдаёт расчёт через API, а frontend/ объясняет результат в браузере.

AI-компонент: BayesianPilotModel находится в context/agent.py. Это небольшая байесовская линейная модель, которая учится прямо во время запуска на наблюдаемых результатах SMS-пилотов. Её признаки: средний прогнозный ARPU и размер группы, разница цен тарифов, ARPU-сегмент. Начальный прогноз намеренно неопределённый; после пилота модель обновляет коэффициенты с учётом размера выборки и шума измерения. Она ранжирует ещё не проверенные гипотезы по верхней оценке возможной чистой выгоды. Финальные кампании дополнительно проходят риск-фильтр и ограничения бюджета/каналов. Модель использует только документированный результат пилота, не получает доступ к скрытой модели эффекта и не обучается на мок-скорере. LLM в этой версии не используется.

Исторические смены тарифов помогают составить список кандидатов, но не служат метками эффекта маркетинговой кампании: это другая аудитория и уже совершённые переходы. Дополнительная группа выбирается без просмотра истинных или мок-эффектов. Если расчёт ML-модели не удаётся, агент продолжает разведку в фиксированном порядке. Для сравнения решений доступны режимы Agent(use_bandit=False) (фиксированная очередь) и Agent(explore_new_groups=False) (ML без дополнительной группы).

Как читать результаты

  • ARPU — средняя выручка на одного абонента. Здесь показывается суммарный прирост выручки по аудитории. у.е. — условные денежные единицы синтетического кейса.
  • Прогон — один полный запуск агента: пилоты, выбор кампаний и подсчёт результата. Seed — номер воспроизводимого варианта случайной выборки и шума пилотов; исходная база абонентов не меняется и seed не является баллом качества.
  • Пилот — пробная кампания на небольшой группе. Она тратит бюджет и контакты, а её измеренный эффект содержит шум. SMS-пилоты дают данные ML-модели; пятый SMS-пилот исследует ранее не охваченную крупную группу. Реклама и звонки при необходимости проверяются отдельно.
  • Прогноз до / наблюдение / прогноз после — оценка модели до пилота, измерение на небольшой группе и уточнённая оценка после него. Процент означает относительное изменение выручки группы, а не вероятность успеха.
  • Чистый результат = прирост выручки по уникальным абонентам − затраты на все контакты, включая пилотные. Процент рядом с ним показывает отношение к исходной суммарной выручке всей базы.
  • Контакты и уникальные абоненты различаются: один человек может получить несколько предложений; каждое обращение стоит денег, но эффект от одного человека засчитывается один раз. Процент охвата — доля уникальных людей от всей базы.
  • Люди с минусом — доля охваченных, для которых мок-модель рассчитала снижение выручки. 0% не означает отсутствие риска на реальных данных.
  • Тариф 4 → Тариф 8 означает предложение перейти между тарифами с внутренними кодами tariff_4 и tariff_8; номера не обозначают цену. Сегменты LOW / MID / HIGH относятся к уровню выручки, HEAVY — к большому потреблению интернета, NON_USER — к отсутствию его использования.
  • Проверка устойчивости повторяет прогон при разных seed. 15/15 в плюс означает 15 положительных результатов на мок-модели. Медиана — средний по порядку результат; минимум и максимум показывают разброс.
  • Прирост по строкам кампаний показан до устранения повторного охвата и до вычета затрат. Общий результат засчитывает каждого абонента один раз, поэтому строки не нужно складывать для проверки итоговой суммы.

Эффекты на судействе отличаются от мок-модели. Числа на панели показывают работу алгоритма и соблюдение ограничений, но не будущий балл.

Сравнение с прежней логикой

Из папки context запустите python benchmark_ml.py --runs 50 (или docker compose run --build --rm agent python benchmark_ml.py --runs 50 из корня репозитория). Скрипт сравнивает новую модель с прежней фиксированной очередью на одинаковых seed через предоставленный локальный скорер.

На 50 одинаковых seed обе стратегии дали 50/50 положительных результатов. Медиана фиксированной очереди — 2 582 253 у.е., текущей ML-логики — 2 547 678 у.е.; ML выше в 30/50 парных прогонов, медиана парной разницы +6 602 у.е. Это небольшое и нестабильное преимущество, а положительный локальный результат не доказывает улучшение балла: мок-эффекты отличаются от судейских.

Проверка при изменённых эффектах

docker compose run --build --rm agent python stress_eval.py --runs 30

Без Docker: из папки context выполните python stress_eval.py --runs 30. Скрипт сравнивает текущую ML-логику с Agent(explore_new_groups=False) на одинаковых seed в четырёх сценариях: исходная мок-модель, эффекты вдвое слабее, провал первых четырёх гипотез и искусственно выгодная крупная группа вне прежнего списка. Он проверяет лимиты и сообщает медиану, минимум, число положительных прогонов и число выигрышей новой логики. Изменённые эффекты используются только локальным оценщиком; агент получает обычный документированный интерфейс. Сценарии не являются официальным прогоном и не оценивают вероятность получить определённый балл.

Что демонстрировать по критериям оценки

КритерийЧто есть в репозитории
Соответствие задачеAgent.act(env) проводит пилоты и возвращает план тарифных кампаний; local_eval.py проверяет сценарий и лимиты, make_submission.py создаёт отправляемый файл.
Техническая реализация и AIБайесовская модель обновляет оценки после пилотов и влияет на выбор следующих проверок; канал выбирается с учётом доступного охвата, стоимости и риска. Код модели и принятия решений находится в context/agent.py. LLM не используется.
README и воспроизводимостьDocker и локальный запуск описаны ниже; benchmark_ml.py сравнивает с фиксированной очередью, stress_eval.py воспроизводит изменённые эффекты, веб-демо объясняет один прогон.
ЦенностьОптимизируется чистый прирост ARPU после стоимости контактов; учитываются дублирование аудитории, бюджет, размер группы и неопределённость пилота.
Развитие и оригинальностьОдин пилот ищет возможность за пределами исходного списка гипотез. Выбор новых групп и размера пилота можно расширять; результат на скрытых эффектах пока неизвестен.

Эта таблица показывает проверяемые части решения, а не обещает баллы жюри.

Сравнение стратегий пилотов

Чтобы сравнить адаптивный выбор гипотез с фиксированной очередью, проверку новой группы и строгие лимиты расходов, запустите из папки context:

python benchmark_strategy.py --runs 30

Скрипт сравнивает текущий адаптивный алгоритм, прежнюю фиксированную очередь пилотов, вариант без проверки новой группы и более строгие лимиты кампаний. Для всех вариантов используются одинаковые seed. В отчёте есть медианная чистая выгода, нижняя часть результатов, доля прибыльных запусков, число побед над текущим вариантом, пилотные затраты и максимальная стоимость кампании. Те же варианты доступны на экране «Битва стратегий» в локальном демо. Подробности для каждого seed можно сохранить через --csv strategy-results.csv.

Этот инструмент помогает выбирать параметры стратегии на мок-данных; он не меняет agent.py, не читает скрытые эффекты и не гарантирует результат судейства.

Веб-демо

docker compose up --build web

Откройте http://localhost:8765. Можно запустить один прогон с выбранным seed, проверить устойчивость на 5–30 прогонах и открыть «Битву стратегий»: сравнить четыре подхода — текущую адаптивную логику, фиксированную очередь пилотов, вариант без разведки новой группы и более строгие лимиты — на одинаковых сценариях. Турнир показывает лидера, медианную выгоду, нижнюю часть результатов, долю прибыльных запусков и затраты на каналы. Панель также показывает пилоты, кампании, расходы, охват и изменения прогноза ML-модели после SMS-пилотов. Все значения получены на мок-модели кейса: они помогают сравнивать механику, но не предсказывают оценку на судействе.

В Docker фронтенд собирается отдельно на Node.js, после чего готовые файлы помещаются в Python-образ веб-демо. Для локального запуска без Docker сначала установите Python-зависимости по разделу ниже, затем соберите интерфейс:

cd frontend
npm ci
npm run build
cd ..
python context/web_app.py

В этом случае адрес тот же: http://localhost:8765. Сервер доступен только на локальном компьютере. Для разработки компонентов запустите Python-сервер отдельно, затем из frontend/ выполните npm run dev и откройте http://localhost:3000; запросы /api перенаправляются на Python-сервер. npm run preview показывает собранную версию, а npm run lint и npm run format:check проверяют код. При npm ci в Git-клоне устанавливается pre-commit hook для ESLint и Prettier на изменённых файлах фронтенда.

Структура интерфейса: app подключает провайдеры; pages/dashboard собирает экран; widgets показывают сводку, пилоты, кампании и устойчивость; features содержат кнопки запуска; entities/run и entities/robustness типизируют ответы API и хранят запросы/преобразования; shared содержит общий API-клиент и форматирование. Эти части не влияют на отправляемый agent.py.

Запуск в Docker

Собрать образ и запустить локальную проверку:

docker compose run --build --rm agent

Создать context/submission.csv:

docker compose run --build --rm agent python make_submission.py

Папка context подключена внутрь контейнера, поэтому созданный файл останется на хосте.

Локальный запуск без Docker

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cd context
python local_eval.py
python make_submission.py

make_submission.py сохраняет submission.csv в текущую папку context.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
17
Авторы
4
Файлы
104
Ветки
1

Авторы коммитов

Damir Yessenayev 10Nazgul 4jonycalifornication 4Nazgul 1

История коммитов

  • 2026-09-23 18:03some updtsNazgul
  • 2026-09-23 17:59some updtsNazgul
  • 2026-09-23 17:39Build component-based SignBridge demo and stress checksDamir Yessenayev
  • 2026-09-23 16:22Add adaptive pilot model and explained web demoDamir Yessenayev
  • 2026-09-23 15:13Ask before committing SignBridge project changesDamir Yessenayev
  • 2026-09-23 15:06Merge remote-tracking branch 'origin/main'jonycalifornication
  • 2026-09-23 15:04Define channel risk diversification strategyNazgul
  • 2026-09-23 15:04Document reserve tariff hypotheses for developer onejonycalifornication
Все коммиты (17)
  • 2026-09-23 14:52Assign follow-up tasks: reserve hypotheses and channel diversificationDamir Yessenayev
  • 2026-09-23 14:48Integrate task 1/2 findings into agent pilot strategyDamir Yessenayev
  • 2026-09-23 14:41Add adaptive pilot strategyDamir Yessenayev
  • 2026-09-23 14:26Document tariff analysis and pilot hypothesesjonycalifornication
  • 2026-09-23 14:13Add lightweight Docker workflow for SignBridge agentDamir Yessenayev
  • 2026-09-23 14:00Track team tasks as checklists and chronologyDamir Yessenayev
  • 2026-09-23 13:53delete unused filesDamir Yessenayev
  • 2026-09-23 13:53Add SignBridge campaign agent skillDamir Yessenayev
  • 2026-09-23 13:40Add hackathon case context and participant materialsjonycalifornication
Структура репозитория (104 файлов)
.agents/skills/signbridge-campaign-agent/SKILL.md
.agents/skills/signbridge-campaign-agent/agents/openai.yaml
.agents/skills/signbridge-frontend/SKILL.md
.dockerignore
.gitignore
.husky/pre-commit
Dockerfile
Dockerfile.web
README.md
context/PARTICIPANT_GUIDE.md
context/PARTICIPANT_GUIDE.pdf
context/agent.py
context/agent_template.py
context/benchmark_ml.py
context/benchmark_strategy.py
context/customer_profile.csv
context/data/arpu_monthly.csv
context/data/change_tariff.csv
context/data/dict_tariff.csv
context/data/traffic.csv
context/environment.py
context/feature_dictionary.csv
context/local_eval.py
context/make_submission.py
context/mock_environment.py
context/scoring_core.py
context/stress_eval.py
context/submission.csv
context/tariff_dictionary.csv
context/web_app.py
docker-compose.yml
frontend/.prettierignore
frontend/eslint.config.js
frontend/package-lock.json
frontend/package.json
frontend/rsbuild.config.ts
frontend/src/app/index.ts
frontend/src/app/ui/App.tsx
frontend/src/entities/robustness/api/getRobustness.ts
frontend/src/entities/robustness/api/index.ts
frontend/src/entities/robustness/api/types.ts
frontend/src/entities/robustness/index.ts
frontend/src/entities/robustness/model/index.ts
frontend/src/entities/robustness/model/mappers.ts
frontend/src/entities/robustness/model/types.ts
frontend/src/entities/robustness/model/useRobustness.ts
frontend/src/entities/run/api/getRun.ts
frontend/src/entities/run/api/index.ts
frontend/src/entities/run/api/types.ts
frontend/src/entities/run/index.ts
frontend/src/entities/run/model/index.ts
frontend/src/entities/run/model/mappers.ts
frontend/src/entities/run/model/types.ts
frontend/src/entities/run/model/useRun.ts
frontend/src/entities/strategy-comparison/api/getStrategyComparison.ts
frontend/src/entities/strategy-comparison/api/index.ts
frontend/src/entities/strategy-comparison/api/types.ts
frontend/src/entities/strategy-comparison/index.ts
frontend/src/entities/strategy-comparison/model/index.ts
frontend/src/entities/strategy-comparison/model/mappers.ts
frontend/src/entities/strategy-comparison/model/types.ts
frontend/src/entities/strategy-comparison/model/useStrategyComparison.ts
frontend/src/features/check-robustness/index.ts
frontend/src/features/check-robustness/ui/RobustnessControls.tsx
frontend/src/features/check-robustness/ui/index.ts
frontend/src/features/compare-strategies/index.ts
frontend/src/features/compare-strategies/ui/StrategyComparisonControls.tsx
frontend/src/features/compare-strategies/ui/index.ts
frontend/src/features/run-agent/index.ts
frontend/src/features/run-agent/ui/RunControls.tsx
frontend/src/features/run-agent/ui/index.ts
frontend/src/index.tsx
frontend/src/pages/dashboard/index.ts
frontend/src/pages/dashboard/ui/DashboardPage.tsx
frontend/src/pages/dashboard/ui/index.ts
frontend/src/shared/api/apiClient.ts
frontend/src/shared/api/index.ts
frontend/src/shared/i18n/LanguageProvider.tsx
frontend/src/shared/i18n/index.ts
frontend/src/shared/i18n/translations.ts
frontend/src/shared/lib/format.ts
frontend/src/shared/lib/index.ts
frontend/src/styles.css
frontend/src/widgets/campaign-plan/index.ts
frontend/src/widgets/campaign-plan/ui/CampaignPlan.tsx
frontend/src/widgets/campaign-plan/ui/index.ts
frontend/src/widgets/overview/index.ts
frontend/src/widgets/overview/ui/Overview.tsx
frontend/src/widgets/pilot-analysis/index.ts
frontend/src/widgets/pilot-analysis/ui/PilotAnalysis.tsx
frontend/src/widgets/pilot-analysis/ui/index.ts
frontend/src/widgets/robustness/index.ts
frontend/src/widgets/robustness/ui/RobustnessPanel.tsx
frontend/src/widgets/robustness/ui/index.ts
frontend/src/widgets/strategy-showdown/index.ts
frontend/src/widgets/strategy-showdown/ui/StrategyShowdown.tsx
frontend/src/widgets/strategy-showdown/ui/index.ts
frontend/tsconfig.json
requirements.txt
tasks/01-data-analysis.md
tasks/02-pilot-strategy.md
tasks/03-agent-implementation.md
tasks/README.md
tasks/chronology.md

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.