AAYMA
RU
Войти

Умный подбор event-подрядчиков

Лёгкий локальный MVP на стандартной библиотеке Python: по городу, дате, формату, категории и бюджету возвращает до 3 свободных подрядчиков с…

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

О проекте

Команда: USAnlog
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Рабочий MVP

Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор

Суть

Лёгкий локальный MVP на стандартной библиотеке Python: по городу, дате, формату, категории и бюджету возвращает до 3 свободных подрядчиков с объяснениями либо статус no_catalog/no_match с причинами.

Как устроено

Сервер на http.server читает DataProviders.csv, отбирает записи по городу и категории, исключает синтетические и отсеивает кандидатов по busy_dates, цене выше бюджета, формату, языку и длительности. При наличии ключа text-embedding-3-small (с кэшем в .cache/embeddings.json) только переупорядочивает прошедших фильтр, gpt-4o-mini формулирует объяснения по фактам карточек; без ключа порядок идёт по цене и ID, объяснения собираются по правилам. smoke_check.py офлайн проверяет три исхода и стабильность порядка.

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

  • жёсткие фильтры по календарю, бюджету и формату
  • ранжирование эмбеддингами
  • rule-based fallback объяснений
  • кэш эмбеддингов

Особенности

Нулевые зависимости (только stdlib Python и HTML без сборщика), при этом явно различаются три исхода (recommendations / no_catalog / no_match), а флаги price_imputed/city_imputed показываются как ориентировочные.

Стек

Python · http.server · HTML/CSS/JavaScript

Модели

gpt-4o-mini · text-embedding-3-small


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

README

README.md

Умный подбор event-подрядчиков

Локальный MVP агрегатора подрядчиков для мероприятий в Казахстане. Пользователь задаёт город, дату, формат события, категорию и бюджет; длительность и язык — по желанию. Приложение показывает до трёх свободных вариантов и объясняет совпадения фактами из каталога.

Состав проекта

.
├── server.py             # HTTP-сервер, фильтры, эмбеддинги и генерация объяснений
├── index.html            # форма и карточки результатов; без frontend-библиотек
├── DataProviders.csv     # исходный каталог из 66 записей
├── smoke_check.py        # автономная проверка основных сценариев
├── .env.example          # названия переменных для API
└── .gitignore

Технологии

  • Python 3.9+ и стандартная библиотека: http.server, csv, urllib; зависимости устанавливать не нужно.
  • HTML, CSS и JavaScript без сборщика и внешних frontend-пакетов.
  • OpenAI-compatible API, если задать OPENAI_API_KEY: [скрыто] используется для семантического порядка среди уже прошедших фильтры кандидатов, gpt-4o-mini — для формулировки объяснений по фактам каталога.
  • Без ключа приложение работает локально: применяет те же ограничения и выводит короткие объяснения по полям каталога. Запросы к внешнему API не выполняются.

Запуск локально

Из корневой папки проекта:

python3 --version
python3 server.py

Откройте http://localhost:8000. Остановить сервер можно сочетанием Ctrl+C в терминале.

Если порт 8000 занят, задайте другой перед запуском:

PORT=8001 python3 server.py

Подключение LLM и эмбеддингов

Настройка необязательна. Переменные задаются в том же терминале, из которого запускается сервер; .env.example служит списком имён и автоматически не загружается.

export OPENAI_API_KEY="ваш-ключ"
export EMBEDDING_MODEL="text-embedding-3-small"
export LLM_MODEL="gpt-4o-mini"
python3 server.py

Для совместимого провайдера можно также задать OPENAI_BASE_URL, указав адрес API с окончанием /v1. Ключ не добавляйте в код или CSV. Первый запрос может занять больше времени: описания подрядчиков отправляются в API эмбеддингов и сохраняются в локальном .cache/embeddings.json; повторные запросы используют кэш. Объяснения LLM каждый раз строятся только по карточкам, прошедшим фильтры. Если API недоступен, приложение возвращается к объяснениям по правилам.

Как формируется рекомендация

  1. Отбираются записи по городу и категории; синтетические записи исключаются.
  2. Кандидат исключается, если дата есть в busy_dates, цена выше бюджета, формат не указан в event_formats или не совпадает, а также если заданные язык или длительность не подтверждаются данными карточки.
  3. Если кандидатов нет в городе и категории, API возвращает no_catalog. Если исходные кандидаты есть, но условиям не соответствует ни один — no_match со списком причин. Иначе возвращается recommendations с максимум тремя карточками.
  4. При настроенном API эмбеддинги влияют только на порядок прошедших фильтры кандидатов. При равных оценках порядок определяется ценой и ID. Без API порядок также стабилен: сначала цена, затем ID.
  5. Признаки price_imputed и city_imputed отображаются как ориентировочные значения. Площадки представлены обычными категориями, с тем же календарным фильтром.

Бронирования, заявки и уведомления подрядчикам не выполняются. В исходной строке Ани Форджер добавлена занятая дата 2026-09-25 для сценария проверки календаря.

Проверка воспроизводимости

В отдельном терминале из корневой папки выполните:

python3 smoke_check.py

Скрипт отключает API для проверки, поэтому не расходует токены и работает офлайн. Он проверяет три состояния (recommendations, no_catalog, no_match), максимум три карточки, стабильность порядка и исключение Ани Форджер на 25 сентября 2026 года.

Также API можно вызвать напрямую. Пример запроса, для которого в каталоге есть фотографы:

curl -s http://localhost:8000/api/recommend \
  -H 'Content-Type: application/json' \
  -d '{"city":"Алматы","event_date":"2026-09-24","event_type":"свадьба","category":"Фотограф","budget_kzt":500000}'

Форма автоматически загружает доступные города, категории, форматы и языки через GET /api/options. Рекомендации возвращаются через POST /api/recommend.

Данные и ограничения

Каталог содержит 66 анкет, категорий, площадок, цен и занятых дат. Занятость задаётся датами ISO (YYYY-MM-DD), разделёнными символом |. Чтобы обновить наличие, меняйте DataProviders.csv и перезапускайте сервер: CSV считывается при запуске. Данные и календарь учебные, поэтому перед реальным бронированием их нужно сверить с подрядчиком — само приложение бронь не оформляет.

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

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

Ulbolsyn 8wonderdeadkp 5alens0809-design 1

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

  • 2026-09-23 17:30Update index.htmlalens0809-design
  • 2026-09-23 17:21Update server.pywonderdeadkp
  • 2026-09-23 17:21Fix typos and formatting in README.mdwonderdeadkp
  • 2026-09-23 17:13Main datawonderdeadkp
  • 2026-09-23 17:10Add files via uploadwonderdeadkp
  • 2026-09-23 17:01Add offline smoke checks for recommendation outcomesUlbolsyn
  • 2026-09-23 16:58Modified version: Handling the requirmentswonderdeadkp
  • 2026-09-23 16:45Fix formatting and punctuation in README.mdUlbolsyn
Все коммиты (14)
  • 2026-09-23 16:44Fix punctuation in project descriptionUlbolsyn
  • 2026-09-23 15:47Add example environment variables for OpenAI APIUlbolsyn
  • 2026-09-23 15:24Revise README for project overview and setupUlbolsyn
  • 2026-09-23 14:27Veb versionUlbolsyn
  • 2026-09-23 14:21the first version of definitionUlbolsyn
  • 2026-09-23 14:05Filtration programm by requestUlbolsyn
Структура репозитория (6 файлов)
.env.example
DataProviders.csv
README.md
index.html
server.py
smoke_check.py

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

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

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