Умный подбор event-подрядчиков
FastAPI-бэкенд подбирает до 3 event-подрядчиков из анонимизированного каталога (66 профилей) по городу, дате, формату, категории и бюджету и…
О проекте
Команда: Esil university
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Рабочий MVP
Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор
Суть
FastAPI-бэкенд подбирает до 3 event-подрядчиков из анонимизированного каталога (66 профилей) по городу, дате, формату, категории и бюджету и генерирует объяснения через LLM; веб-интерфейса нет, проверка через /docs.
Как устроено
Запрос валидируется, детерминированный фильтр исключает профили по городу, категории, занятой дате, бюджету, формату, языку и длительности, затем стабильное ранжирование по фиксированным правилам. LLM (OpenAI SDK или совместимый NVIDIA endpoint) пишет 1–2 предложения объяснения по фактам профиля; при сбое — локальный fallback. Различаются три исхода: подобраны, категории нет в городе, кандидаты не прошли условия.
Ключевые решения
- deterministic filtering
- stable ranking
- LLM explanation
- rejection reason analysis
Стек
Python · FastAPI · Uvicorn · pytest
Модели
OpenAI · NVIDIA API
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-ae3f40fe-esil-university.
README
README.mdУмный подбор event-подрядчиков
Сервис подбирает до трёх event-подрядчиков из уже сформированного каталога и объясняет, почему каждый из них подходит под конкретное мероприятие. Решение предназначено для заказчиков мероприятий в Казахстане, которым нужно быстро сократить длинный список исполнителей с учётом города, даты, формата, категории и бюджета.
[!IMPORTANT] В репозитории уже есть backend с фильтрацией, FastAPI и подключённым модулем объяснений. Пользовательского веб-интерфейса пока нет; проверить API можно на странице
/docs.
Что реализует решение
- принимает город, дату, тип мероприятия, категорию подрядчика и бюджет;
- дополнительно учитывает язык работы и требуемую длительность присутствия;
- исключает подрядчиков, занятых в выбранную дату;
- проверяет город, категорию, формат, бюджет, язык и длительность;
- возвращает не более трёх карточек в стабильном порядке;
- показывает в карточке имя, категорию, город, цену и конкретное объяснение выбора;
- отличает синтетические профили от исходных;
- явно разделяет три результата: кандидаты подобраны, в городе нет такой категории, кандидаты есть, но не прошли условия;
- объясняет пустую выдачу вместо показа пустого экрана или технической ошибки.
Бронирование, отправка заявок и уведомления подрядчиков не входят в текущий сценарий.
Как работает решение
- Клиент отправляет параметры мероприятия в HTTP API.
- Сервис валидирует запрос и загружает каталог подрядчиков.
- Детерминированный фильтр исключает неподходящие профили: другой город или категория, занятая дата, превышенный бюджет, неподдерживаемый формат, язык или длительность.
- Оставшиеся кандидаты ранжируются по фиксированным правилам. LLM не решает, кто допускается в выдачу, поэтому не может вернуть занятого или слишком дорогого подрядчика.
- Для лучших кандидатов LLM формирует по 1–2 предложения на основе фактов профиля и параметров запроса. Общие формулировки вроде «отличный выбор» не используются.
- API возвращает до трёх карточек либо понятную причину, почему результатов нет или их меньше трёх.
Одинаковый запрос должен давать один и тот же порядок карточек. Изменение даты может менять выдачу из-за календаря занятости.
Архитектура
flowchart LR
A[Клиент или интерфейс] --> B[Валидация запроса]
D[(Каталог JSONL/CSV)] --> C[Детерминированный фильтр]
B --> C
C --> E[Стабильное ранжирование]
E --> F[LLM-объяснения]
F --> G[До 3 карточек]
C --> H[Анализ причин отказа]
H --> I[Понятный пустой результат]
Основные файлы репозитория:
hackathon-contractors/
├── api.py
├── main.py
├── demo.py
├── data/
│ ├── hackathon-dataset-anonymized.csv
│ └── hackathon-dataset-anonymized.jsonl
├── src/
│ ├── __init__.py
│ ├── data_loader.py
│ ├── filter_engine.py
│ ├── llm_contract.py
│ ├── llm_explainer.py
│ ├── models.py
│ └── recommendation_service.py
├── docs/
├── examples/
├── tests/
├── requirements.txt
├── .env.example
└── README.md
| Компонент | Ответственность |
|---|---|
api.py | HTTP API для проверки доступности, параметров и рекомендаций |
src/filter_engine.py | фильтрация, причины отказа и стабильное ранжирование |
src/recommendation_service.py | соединяет фильтрацию и объяснения |
src/llm_explainer.py | объяснения по переданным фактам и локальный fallback |
data/ | анонимизированный каталог подрядчиков и их календарь занятости |
Технологии
Используемые технологии:
- Python 3.10+;
- FastAPI и Uvicorn — HTTP API;
- OpenAI SDK — OpenAI API или совместимый NVIDIA endpoint;
- LLM API — генерация коротких объяснений;
- python-dotenv — локальная конфигурация API-ключей;
- JSONL/CSV — формат данных подрядчиков.
Зависимости и версии указаны в requirements.txt. Настройки провайдера и модели — в .env.example.
Данные и интеграции
В исходном анонимизированном датасете содержится 66 профилей подрядчиков:
- 17 категорий;
- 50 профилей из Алматы, 15 из Астаны и 1 профиль из категории «Зарубежье»;
- 13 полностью синтетических профилей с признаком
synthetic: true; - 8 восстановленных значений города и 18 восстановленных цен;
- цены от 100 000 до 6 000 000 ₸;
- календарь занятости с 23 сентября по 31 декабря 2026 года.
Основные поля: id, anon_name, categories, city, price_from_kzt, event_formats, languages, max_hours, busy_dates, description, synthetic, city_imputed, price_imputed.
Персональные данные отсутствуют: имена вымышлены, дополнительная анонимизация не требуется. API-ключ LLM хранится только в локальном .env и не должен попадать в Git.
Установка и запуск
Команды для Windows PowerShell:
# Windows PowerShell
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
Copy-Item .env.example .env
Для macOS/Linux:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
В .env укажите свой OPENAI_API_KEY, затем запустите API:
python -m uvicorn api:app --reload --host 127.0.0.1 --port 8000
Откройте http://127.0.0.1:8000/docs и отправьте запрос через POST /recommendations. Подробная инструкция находится в BACKEND_README.md.
Как проверить решение
Ниже приведены сценарии, которые можно отправить через страницу API /docs на исходном датасете.
1. Плотная категория
| Параметр | Значение |
|---|---|
| Город | Алматы |
| Дата | 18.10.2026 |
| Тип мероприятия | корпоратив |
| Категория | Ведущий |
| Бюджет | 1 300 000 ₸ |
| Язык и длительность | не указывать |
Ожидается три карточки из нескольких подходящих профилей. Повторный запуск должен сохранить их порядок и объяснения должны ссылаться на разные факты из профилей.
2. Редкая категория
| Параметр | Значение |
|---|---|
| Город | Алматы |
| Дата | 15.10.2026 |
| Тип мероприятия | свадьба |
| Категория | Флорист |
| Бюджет | 500 000 ₸ |
| Язык | русский |
В исходном датасете условия проходят два профиля. API должен вернуть обе карточки и объяснить, почему результатов меньше трёх.
3. Кандидаты есть, но условия не проходят
| Параметр | Значение |
|---|---|
| Город | Алматы |
| Дата | 26.12.2026 |
| Тип мероприятия | свадьба |
| Категория | Ведущий |
| Бюджет | 100 000 ₸ |
| Язык | русский |
| Длительность | 6 часов |
В Алматы есть ведущие, однако запрос не должен вернуть карточки. Пользователь должен увидеть конкретные причины: бюджет, занятость, формат или сочетание ограничений.
Дополнительно можно проверить отдельный исход «в городе нет такой категории» запросом на декоратора в Астане.
Для проверки влияния календаря повторите первый сценарий с другой датой. Состав выдачи может измениться, но занятый на выбранную дату профиль появляться не должен.
Ограничения
- каталог содержит только 66 профилей и не является полноценной базой рынка;
- данные ограничены Алматы, Астаной и одним зарубежным профилем;
- календарь покрывает только период 23.09.2026–31.12.2026;
- цена
price_from_kztявляется стартовой и не заменяет итоговый расчёт подрядчика; - часть городов и цен была восстановлена при подготовке датасета;
- качество объяснений зависит от доступности и поведения внешнего LLM API;
- решение не выполняет бронирование, оплату и коммуникацию с подрядчиком;
- полноценный пользовательский веб-интерфейс пока не добавлен;
- внешняя LLM используется только для объяснений; при отсутствии ключа или сбое остаются локальные сообщения.
Deployed-версия
Публичная deployed-версия пока не опубликована.
Авторы коммитов
История коммитов
- 2026-09-23 17:58docs: preserve project guide with accurate API instructionsdimash
- 2026-09-23 17:57docs: update project README for integrated APIdimash
- 2026-09-23 17:56Merge project README contributiondimash
- 2026-09-23 17:56Merge contractor filtering backend and LLM integrationdimash
- 2026-09-23 17:46Connect recommendation API to team LLM module and verify integrationlioshka-alt
- 2026-09-23 17:29Add deterministic contractor filtering backend and datasetlioshka-alt
- 2026-09-23 17:18Merge remote-tracking branch 'team/main' # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting wdimash
- 2026-09-23 17:14docs: add project READMEm1tello
Все коммиты (11)
- 2026-09-23 17:11Add OpenAI LLM explainerdimash
- 2026-09-23 16:36feat: add LLM explainer moduledimash
- 2026-09-23 15:58первый коммитdimash
Структура репозитория (38 файлов)
.env.example .gitignore BACKEND_README.md README.md api.py data/hackathon-dataset-anonymized.csv data/hackathon-dataset-anonymized.jsonl demo.py docs/DEFENSE.md docs/TEAM_INTEGRATION.md docs/VALIDATION.md docs/demo-results.json docs/integration-results.json examples/01_dense_request.json examples/01_dense_response.json examples/02_rare_request.json examples/03_no_matches_request.json examples/04_no_category_request.json examples/05_other_date_request.json examples/06_languages_duration_request.json main.py pytest.ini requirements-dev.txt requirements-lock.txt requirements.txt src/__init__.py src/data_loader.py src/filter_engine.py src/llm_contract.py src/llm_explainer.py src/models.py src/recommendation_service.py tests/conftest.py tests/test_api.py tests/test_backend.py tests/test_pipeline.py tests/test_team_integration.py uwh.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.