Проект для хакатона Альфа: маскирование персональных данных (ПДн) в тексте.
main-module/— точка входа: FastAPI-приложение, которое параллельно опрашивает все сервисы-детекторы, объединяет результаты, маскирует явные ПДн и хранит корреляциюpayload_idв Redis (поддерживает демаскирование).regex-module/— детектор ПДн на регулярных выражениях + справочник адресов (КЛАДР), WebSocket-эндпоинт/scan.gliner_famous/— сервис на базе GLiNER для распознавания сущностей (FastAPI + WebSocket), с проверкой «известных персон».llm_service/— сервис распознавания сущностей на базе LLM (провайдер ALFA), тот же контракт, что иgliner_famous.ml_for_all_types/— ансамбль лёгковесных ML-детекторов ПД (numpy, без тяжёлых зависимостей), тот же контракт.load_balanser/— балансировщик нагрузки на базе Nginx.monitoring/— Prometheus + Grafana (+ cAdvisor) для мониторинга всех сервисов.e2e_tests/— end-to-end тесты всей цепочки маскирования по датасету.test-data/— датасеты и вспомогательные данные для тестов.training_data/— данные и скрипты обучения моделей.docker-compose.yml— полный стек (все сервисы + мониторинг);docker-compose.services.yml— только сервисы;docker-compose.server.yml— конфигурация для деплоя на Yandex Cloud.setup-server.sh,build-push.sh— скрипты сборки/публикации образов и развёртывания на сервере Yandex Cloud.
Клиент обращается к main-module (POST /process с {payload, payload_id}).
main-module параллельно (с таймаутом) опрашивает четыре детектора через
балансировщик:
regex-module(WebSocket/scan);llm-service(REST/process);gliner_famous(REST/process);ml_for_all_types(REST/process).
Полученные сущности объединяются, фильтруются (ФИО сверяются со справочником
имён), а явные ПДн заменяются на маски вида {{ TYPE1,TYPE2 N }}. Результат и
исходный текст сохраняются в Redis по payload_id, что позволяет демаскировать
строку повторным запросом с тем же payload_id.
Компонентная и sequence-диаграммы (PlantUML) лежат в docs/:
docs/component.puml— компонентная диаграмма системы;docs/sequence.puml— sequence-диаграмма маскирования текста черезmain-module.
Поднимите весь стек (все сервисы + Redis + балансировщик + мониторинг):
docker compose up -d --buildПроверьте, что main-module поднялся:
curl http://localhost:8000/healthmain-module — точка входа для маскирования/демаскирования:
POST /process— тело{"payload": "<текст>", "payload_id": "<id>"}. Возвращаетresults(сущности по каждому сервису),masked_text(замаскированный текст) иreplacements(список замен).POST /processс тем жеpayload_idиpayload, равным ранее возвращённомуmasked_text, — демаскирование (возвращает исходную строку вresults).GET /health— проверка живости.GET /metrics— метрики Prometheus.
Пример маскирования:
curl -X POST http://localhost:8000/process \
-H "Content-Type: application/json" \
-d '{"payload": "Иван Петров, тел. +7 900 123-45-67", "payload_id": "demo-1"}'Пример демаскирования (тем же payload_id и замаскированной строкой):
curl -X POST http://localhost:8000/process \
-H "Content-Type: application/json" \
-d '{"payload": "{{ FIO 1 }}, тел. {{ PHONE 2 }}", "payload_id": "demo-1"}'Список детекторов задаётся переменной окружения MASKING_SERVICES (JSON-массив).
Каждый элемент: name, protocol (rest | websocket), url, timeout,
опционально pool (для WebSocket-пула). По умолчанию в docker-compose.yml
подключены regex (WS), llm (REST), gliner (REST), ml (REST).
Корреляция payload_id хранится в Redis (REDIS_URL).
Все детекторы отдают сущности в едином контракте Entity:
{text, type[], score, slice, will_be_used}.
Детектор на регулярных выражениях + справочник адресов (КЛАДР). При старте
загружает адресную книгу из BASE/. Эндпоинт:
WS /scan— принимает текст, возвращает найденные ПДн.
Детектор на базе GLiNER (FastAPI + WebSocket) с проверкой «известных персон». Эндпоинты:
POST /process— обработка текста (JSON{"text": "..."});WS /ws— WebSocket-обработка текста.
Детектор на базе LLM провайдера ALFA (тот же контракт, что и gliner_famous).
Ориентирован на скорость: один запрос к LLM возвращает все сущности сразу.
Креды провайдера ALFA задаются в llm_service/.env (см. .env.example):
LLM_BASE_URL=https://alfagen.alfabank.ru/continue-dev/
LLM_API_KEY=<ваш ключ>
LLM_MODEL=deepseek-ai/DeepSeek-V4-Flash-0731Примечание:
.envне коммитится в git (добавлен в.gitignore). Для локального запуска скопируйте.env.exampleв.envи заполните ключ.
Ансамбль лёгковесных numpy-классификаторов (по одному на каждый тип ПД), тот же
контракт, что и gliner_famous. Не требует GPU и тяжёлых зависимостей.
Nginx-балансировщик слушает порт 80 и проксирует запросы на бэкенды
(имена задаются переменными окружения *_BACKENDS, по умолчанию — один бэкенд):
WS /gliner-famous/ws→/ws;POST /gliner-famous/process→/process;WS /llm-service/ws→/ws;POST /llm-service/process→/process;WS /regex-module/scan→/scan;POST /main-module/process→/process;GET /main-module/health→/health;WS /ml-for-all-types/ws→/ws;POST /ml-for-all-types/process→/process;GET /nginx_status— метрики nginx для Prometheus.
Пример запроса к детектору через балансировщик:
curl -X POST http://localhost:8080/gliner-famous/process \
-H "Content-Type: application/json" \
-d '{"text": "Иван Петров работает в Альфа-Банке"}'Тесты в e2e_tests/ прогоняют датасет через POST /process main-module и
сверяют найденные сущности с ожидаемыми personal_data.
cd e2e_tests
pip install -e .
MAIN_MODULE_URL=http://localhost:8000 pytest test_e2e_dataset.pyПеременные окружения: MAIN_MODULE_URL (по умолчанию http://localhost:8000) и
DATASET_PATH (по умолчанию test-data/deepseek_json_20260922_merged.json).
Все FastAPI-сервисы отдают метрики Prometheus на эндпоинте /metrics (через
prometheus-fastapi-instrumentator), балансировщик — через sidecar-контейнер
nginx-prometheus-exporter (эндпоинт /nginx_status), а cAdvisor собирает
метрики CPU/RAM контейнеров.
Prometheus, Grafana и cAdvisor поднимаются вместе со стеком через
docker-compose.yml:
docker compose up -d| Сервис | URL | Логин/пароль |
|---|---|---|
| Prometheus | http://localhost:9090 | — |
| Grafana | http://localhost:3000 | admin/admin |
| cAdvisor | http://localhost:8081 | — |
- Prometheus (
monitoring/prometheus/prometheus.yml) — скрейпит все сервисы (main-module,regex-module,llm-service,gliner-famous,ml-for-all-types), балансировщик через exporter и cAdvisor. - Grafana (
monitoring/grafana/) — авто-провижининг datasource Prometheus и готовый дашборд «ALFA Hack — Мониторинг сервисов»:- статус сервисов (
up); - RPS по сервисам;
- задержка ответа (p95/p99);
- ошибки 4xx/5xx;
- запросы по эндпоинтам;
- метрики nginx (RPS, соединения);
- метрики CPU/RAM контейнеров (cAdvisor).
- статус сервисов (
Дашборд доступен сразу после старта Grafana (обновляется каждые 10 секунд).
# Метрики конкретного сервиса
curl http://localhost:8000/metrics
# Метрики балансировщика (через exporter)
curl http://localhost:9113/metricsdocker build -t alfa-prometheus ./monitoring/prometheus
docker build -t alfa-grafana ./monitoring/grafanaОбразы публикуются в Yandex Container Registry, а сервер разворачивается через
docker-compose.server.yml.
./build-push.sh # тег latest
./build-push.sh v1.0.0 # конкретный тегСкрипт собирает и пушит образы main-module, regex-module, llm-service,
gliner-famous, ml-for-all-types, load-balancer в реестр
cr.yandex/crpjr8em43c2vgubc740.
Скопируйте на сервер docker-compose.server.yml, llm_service.env и
monitoring/, затем выполните:
./setup-server.shСкрипт установит yc CLI, настроит авторизацию (OAuth-токен или сервисный
аккаунт с ролью container-registry.images.puller), настроит Docker для реестра
и запустит контейнеры через docker compose -f docker-compose.server.yml up -d.
Примечание:
docker-compose.server.ymlиспользует готовые образы из реестра (безbuild:), аdocker-compose.ymlсобирает образы локально.

