AAYMA
RU
Войти

Sergeek Campaign Agent

Статистический агент для Beeline: подбирает до 10 кампаний (сегмент, целевой тариф, канал) в рамках бюджета и лимита охвата через пилоты, плюс…

Доведённый продукт
Команда «sergeek» 17💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: sergeek
Кейс HackAlem.ai: Телеком — Beeline
Стадия: Доведённый продукт

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

Суть

Статистический агент для Beeline: подбирает до 10 кампаний (сегмент, целевой тариф, канал) в рамках бюджета и лимита охвата через пилоты, плюс React-дашборд для аналитика.

Как устроено

По историческим данным формируются 15 тарифных гипотез. Их проверяют 12 бесплатных push-пилотов по 100 клиентов и 5 подтверждающих по 160. Результаты объединяются взвешенным средним, решение принимается по нижней оценке weighted_mean − 0.75×0.804/√n. Конфликтующие аудитории удаляются, затем перебором комбинаций каналов (skip/push/SMS/digital/call) с учётом остатка бюджета, лимита контактов, стоимости контакта и ARPU сегмента собирается итоговый портфель. LLM не используется; FastAPI отдаёт результаты в дашборд на React/Recharts.

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

  • адаптивные пилоты
  • взвешенное среднее
  • uncertainty-adjusted lower bound
  • перебор каналов под бюджет
  • стресс-тесты
  • shrinkage генерация кандидатов (эксперимент)

Метрики

Mock-модель: прибыльных прогонов 100/100, медианный net gain 3 414 203, минимум 2 112 530, максимум 4 039 759, seed 42 — 2 702 002; 17 пилотов, 5 финальных кампаний

Особенности

Push используется для разведки, потому что не тратит бюджет; решение о масштабировании принимается по нижней границе с поправкой на неопределённость. Автогенератор гипотез со сглаживанием проверили стресс-тестами и не взяли в финал, решение задокументировано.

Стек

Python · pandas · NumPy · FastAPI · React · TypeScript · Vite · Recharts · Docker Compose · Nginx


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

README

README.md

Sergeek Campaign Agent

Адаптивный агент для планирования тарифных маркетинговых кампаний Beeline в условиях неполной информации. Агент проверяет гипотезы небольшими пилотами, учитывает неопределённость результата и формирует портфель кампаний с выбором канала коммуникации в рамках бюджета и лимита охвата.

Для проверки жюри: agent.py, submission.csv и requirements.txt находятся в папке beeline_case_participants (1). Интерфейс — вспомогательный инструмент для аналитика; агент запускается и проверяется отдельно от сайта. Все данные синтетические, суммы — в условных единицах.

Стек и архитектура

  • Python 3.12, pandas и NumPy — агент и локальная оценка.
  • FastAPI и Uvicorn — API, запускающий агента в официальной тестовой среде.
  • React, TypeScript, Vite и Recharts — русский интерфейс аналитика.
  • Docker Compose и Nginx — воспроизводимый запуск и единый адрес UI/API.

Браузер → Nginx → FastAPI → Agent.act(env) → пилоты → итоговый портфель. Агент использует только публичные методы и данные env. Внутренние результаты оценщика читает сервис демонстрации после выполнения агента, а не сам агент. LLM не используется, ключи OpenAI/NVIDIA и сетевой доступ для принятия решений не требуются. Агент реализует автономный цикл наблюдения, оценки и действия статистическим алгоритмом.

Задача

Для аудитории из 23 441 абонента требуется выбрать до 10 кампаний. Каждая кампания определяет:

  1. сегмент аудитории;
  2. целевой тариф;
  3. канал коммуникации.

При этом действуют ограничения: бюджет 100 000 у.е., общий охват до 15 000 контактов, до 20 пилотов и до 5 000 абонентов в одной кампании. Эффекты целевой аудитории заранее неизвестны, поэтому статическая стратегия по историческим данным недостаточна.

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

Исторические данные
        ↓
15 приоритетных тарифных гипотез
        ↓
12 широких push-пилотов × 100 клиентов
        ↓
Повторная оценка и 5 подтверждающих пилотов × 160 клиентов
        ↓
Weighted mean + uncertainty-adjusted lower bound
        ↓
Удаление конфликтующих аудиторий
        ↓
Совместная оптимизация skip / push / SMS / digital ads / call
        ↓
До 5 финальных кампаний в рамках бюджета и охвата

Push используется для разведки, поскольку не расходует денежный бюджет. Результаты повторных пилотов объединяются взвешенным средним. Для принятия решения применяется нижняя оценка эффекта с поправкой на стандартную ошибку — это снижает риск масштабировать кампанию из-за случайно удачного пилота.

Финальный оптимизатор перебирает допустимые комбинации каналов, учитывая:

  • остаток бюджета после пилотов;
  • остаток лимита контактов;
  • стоимость контакта;
  • множитель конверсии канала;
  • размер и средний predicted ARPU сегмента;
  • запрет на конкурирующие кампании для одной аудитории.

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

Допущения и ограничения подхода

История задаёт 15 стартовых гипотез; эффект и окончательный выбор определяются живыми пилотами. Гипотезы для подтверждения выбираются адаптивно, однако число и размеры пилотов фиксированы: 12 × 100 и 5 × 160. Полностью адаптивная остановка разведки пока не реализована.

Используется оценка weighted_mean − 0.75 × 0.804 / sqrt(n). Это штраф за неопределённость, а не калиброванный 95%-й доверительный интервал. Для звонков относительный множитель ограничен сверху 2.0 против push из-за насыщения конверсии. Финальные аудитории не пересекаются по паре «текущий тариф + ARPU-сегмент»; пилотные и финальные контакты могут пересекаться, и оценщик учитывает это.

Автоматический генератор гипотез со сглаживанием реализован в experiments/, но не включён в сдаваемый агент: в стресс-тестах он ухудшил часть сценариев. Результаты и решение описаны в отчёте эксперимента. Следующие улучшения — адаптивная остановка, объединение ручных и автоматически сгенерированных гипотез, калибровка неопределённости на новой аудитории.

Проверенные результаты

Результаты ниже получены на предоставленной организаторами локальной mock-модели. Они подтверждают механику и устойчивость агента, но не являются прогнозом результата на скрытой модели судейства.

ПроверкаРезультат
Прибыльные прогоны100 / 100
Медианный net gain3 414 203
Минимальный net gain2 112 530
Максимальный net gain4 039 759
Контрольный seed 422 702 002
Финальных кампаний5
Пилотов17

Во всех 100 сценариях отдельно проверены лимиты бюджета, охвата, количество кампаний и отсутствие пересечения финальных сегментов.

Финальная повторная проверка 23.09.2026 на seed 0–9: 10/10 прибыльных прогонов, медиана 3 305 739, минимум 2 213 979, максимум 4 039 759 у.е. Контрольный seed 42: 82 818 у.е. расходов, 4 190 контактов, 2 890 уникальных абонентов, 17 пилотов и 5 финальных кампаний. Строка «22 кампании» в отчёте оценщика включает пилоты и не нарушает лимит 10 финальных кампаний. Итоговый эффект учитывает дедупликацию между кампаниями, поэтому его нельзя получить простым сложением строк UI.

Быстрый запуск

Требуется Docker Desktop с Docker Compose.

git clone https://github.com/BAITC-Hacks/hack-5c2118d3-sergeek.git
cd hack-5c2118d3-sergeek
docker compose up -d --build

Локальная проверка агента:

docker compose exec hackathon python local_eval.py
docker compose exec hackathon python local_eval.py --runs 10

Воспроизводимая генерация файла сдачи:

docker compose exec hackathon python make_submission.py

Контрактные smoke-тесты на десяти seed:

docker compose exec api python -m unittest discover -s tests -v

Робастность к сдвигу скрытой impact-модели:

docker compose exec api python experiments/stress_eval.py

После запуска API доступно по адресу http://localhost:8000, интерактивная OpenAPI-документация — http://localhost:8000/docs.

Аналитический dashboard доступен по адресу http://localhost:5173. Интерфейс полностью на русском. В Docker запросы /api/* проходят через Nginx к сервису API, поэтому браузеру достаточно одного адреса сайта. Кнопка «Запустить симуляцию» выполняет 10 новых локальных прогонов. Диапазон продолжается после последнего результата API: после 10–19 запускаются 20–29, после обновления страницы — 30–39. Текущий и следующий диапазоны показаны на странице. После перезапуска API история сбрасывается к стартовой сводке 0–99. Если API недоступен, интерфейс явно показывает «Демо-данные» и сохранённый результат; он не считается новым вычислением.

Проверка без Docker

Требуется Python 3.12; сайт и Node.js для проверки агента не нужны.

cd "beeline_case_participants (1)"
python -m pip install -r requirements.txt
python local_eval.py
python local_eval.py --runs 10
python make_submission.py

Основной сценарий аналитика

  1. «Обзор» — проверить общий результат и расход лимитов.
  2. «Портфель кампаний» — отфильтровать сегмент/канал, открыть детали предложения.
  3. «Работа агента» — просмотреть 17 пилотов и нижние оценки эффекта.
  4. «Симуляция» — запустить следующую десятку случайных выборок пилотов.
  5. «Данные и лимиты» — проверить доступные ресурсы и экономику четырёх каналов.

Браузерная регрессия находится в tests/frontend_smoke.cjs: требует Playwright и установленного Edge, запускается node tests/frontend_smoke.cjs при работающем Docker. Проверяет также продолжение сценариев после обновления страницы, мобильную вёрстку и резервный режим без API.

API для dashboard

МетодEndpointНазначение
GET/api/healthПроверка доступности
GET/api/dashboardKPI, лимиты и каналы
GET/api/campaigns?seed=42Финальный портфель кампаний
GET/api/pilots?seed=42Результаты пилотных запусков
GET/api/simulations/latestПоследняя сводка устойчивости
POST/api/simulations/runЗапуск 1–100 mock-симуляций

Пример запуска симуляции:

curl -X POST http://localhost:8000/api/simulations/run \
  -H "Content-Type: application/json" \
  -d '{"runs": 10, "seed_start": 0}'

Структура проекта

.
├── api/                         # FastAPI для dashboard
├── frontend/                    # React + TypeScript dashboard
├── beeline_case_participants (1)/
│   ├── agent.py                 # сдаваемый адаптивный агент
│   ├── submission.csv           # воспроизводимый план кампаний
│   ├── local_eval.py            # официальный локальный evaluator
│   ├── make_submission.py       # генерация submission.csv
│   └── data/                    # данные организаторов
├── top_tariff_hypotheses.csv    # offline-анализ гипотез
└── compose.yaml                 # агент, API и frontend

Команда

  • Рахман — агент, интеграция и инфраструктура;
  • Медина — анализ данных и экономика каналов;
  • Даурен — frontend и UX аналитического dashboard.

Сценарий трёхминутной демонстрации находится в docs/DEMO_SCRIPT.md, финальная проверка перед сдачей — в docs/FINAL_CHECKLIST.md.

Файлы сдачи

Обязательные файлы находятся в beeline_case_participants (1):

  • agent.py;
  • submission.csv.

Обязательные прогоны выполнены в отдельных контейнерах без локальных томов. Генерация submission.csv проверена; результат совпадает с файлом в репозитории. Сводка по критериям и ограничениям — FINAL_CHECKLIST.md. Оценку по 100-балльной шкале выставляет жюри; локальные проверки не предсказывают балл на скрытых эффектах.

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

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

rakhmankh 16Yan Harms 7

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

  • 2026-09-23 17:38fix: continue simulation scenarios and finalize submission documentationrakhmankh
  • 2026-09-23 17:30merge: integrate Russian dashboard with live campaign APIrakhmankh
  • 2026-09-23 17:17feat: finalize responsive campaign dashboardYan Harms
  • 2026-09-23 17:09experiment: generate tariff candidates with shrinkagerakhmankh
  • 2026-09-23 16:32feat: harden agent against hidden model shiftsrakhmankh
  • 2026-09-23 16:07docs: add demo script and final checklistrakhmankh
  • 2026-09-23 16:04test: expose and verify pilot uncertaintyrakhmankh
  • 2026-09-23 16:01style: add neon chart bar hover statesYan Harms
Все коммиты (23)
  • 2026-09-23 15:57fix: vary simulation seeds between runsYan Harms
  • 2026-09-23 15:52fix: show simulation progress and API resultYan Harms
  • 2026-09-23 15:51fix: harden frontend data integrationrakhmankh
  • 2026-09-23 15:48feat: localize dashboard contentYan Harms
  • 2026-09-23 15:43merge: integrate campaign dashboardrakhmankh
  • 2026-09-23 15:39feat: add campaign analytics dashboardYan Harms
  • 2026-09-23 15:39fix: adapt dashboard to FastAPI responsesYan Harms
  • 2026-09-23 15:19docs: describe agent architecture and local demorakhmankh
  • 2026-09-23 15:18feat: add dashboard API servicerakhmankh
  • 2026-09-23 15:06feat: optimize campaign channel allocationrakhmankh
  • 2026-09-23 14:40build: add reproducible Docker environmentrakhmankh
  • 2026-09-23 14:33feat: integrate ranked tariff hypothesesrakhmankh
  • 2026-09-23 14:27data: add ranked tariff hypothesesrakhmankh
  • 2026-09-23 13:54feat: add first working adaptive campaign agentrakhmankh
  • 2026-09-23 13:42chore: add hackathon case and starter kitrakhmankh
Структура репозитория (64 файлов)
.dockerignore
.gitignore
HackAlem AI_ Beeline Tariff Marketing Campaigns Case.md
README.md
api/Dockerfile
api/README.md
api/main.py
api/requirements.txt
beeline_case_participants (1)/.dockerignore
beeline_case_participants (1)/Dockerfile
beeline_case_participants (1)/PARTICIPANT_GUIDE.md
beeline_case_participants (1)/PARTICIPANT_GUIDE.pdf
beeline_case_participants (1)/agent.py
beeline_case_participants (1)/agent_template.py
beeline_case_participants (1)/customer_profile.csv
beeline_case_participants (1)/data/arpu_monthly.csv
beeline_case_participants (1)/data/change_tariff.csv
beeline_case_participants (1)/data/dict_tariff.csv
beeline_case_participants (1)/data/traffic.csv
beeline_case_participants (1)/environment.py
beeline_case_participants (1)/feature_dictionary.csv
beeline_case_participants (1)/local_eval.py
beeline_case_participants (1)/make_submission.py
beeline_case_participants (1)/mock_environment.py
beeline_case_participants (1)/requirements.txt
beeline_case_participants (1)/scoring_core.py
beeline_case_participants (1)/submission.csv
beeline_case_participants (1)/tariff_dictionary.csv
compose.yaml
docs/AUTO_CANDIDATE_EXPERIMENT.md
docs/DEMO_SCRIPT.md
docs/FINAL_CHECKLIST.md
experiments/agent_variants.py
experiments/candidate_generator.py
experiments/stress_eval.py
frontend/.env.example
frontend/.gitignore
frontend/.oxlintrc.json
frontend/Dockerfile
frontend/README.md
frontend/index.html
frontend/nginx.conf
frontend/package-lock.json
frontend/package.json
frontend/src/App.css
frontend/src/App.tsx
frontend/src/components/MetricCard.tsx
frontend/src/data/mockData.ts
frontend/src/hooks/useDashboard.ts
frontend/src/index.css
frontend/src/layouts/README.md
frontend/src/main.tsx
frontend/src/pages/README.md
frontend/src/services/api.ts
frontend/src/types/api.ts
frontend/tailwind.config.ts
frontend/tsconfig.app.json
frontend/tsconfig.json
frontend/tsconfig.node.json
frontend/vite.config.ts
tests/frontend_smoke.cjs
tests/test_agent_contract.py
tests/test_candidate_generator.py
top_tariff_hypotheses.csv
Ветки (2)

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

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

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