AAYMA
RU
Войти

Подбор

Сервис подбора до трёх event-подрядчиков (ведущий, фотограф, зал, флорист и другие) по городу, дате, формату, категории и бюджету.

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

О проекте

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

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

Суть

Сервис подбора до трёх event-подрядчиков (ведущий, фотограф, зал, флорист и другие) по городу, дате, формату, категории и бюджету. Каждый выбор объясняется, а поверх детерминированного движка работает ИИ-агент, который понимает запрос свободным текстом.

Как устроено

Движок на стандартной библиотеке Python нормализует запрос и отбирает кандидатов жёсткими фильтрами (город, категория, занятость на дату, формат, бюджет, язык, часы), сохраняя все причины отказа. Прошедших он ранжирует по 5 критериям (смысл описания 35%, запас по бюджету 30%, язык 15%, часы 10%, надёжность данных 10%) и считает «эффект даты». Агент на OpenAI разбирает фразу и вызывает движок как инструмент, при пустом результате делает до двух альтернативных поисков, а каждое число в его совете сверяется с данными движка. Работает через веб-интерфейс, JSON API и CLI.

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

  • взвешенное ранжирование
  • жёсткие фильтры
  • function calling
  • проверка чисел в ответе
  • поиск альтернатив по дате и бюджету
  • словарь основ слов

Метрики

Подбор без ИИ <1 мс, ИИ-агент 2–7 с; 27 юнит-тестов; 66 профилей, 17 категорий

Особенности

Модель не может добавить подрядчика или выдумать цену: карточки и их порядок строит детерминированный движок, а схема инструмента разрешает только значения из каталога. Сервис различает три исхода, включая «кандидаты есть, но никто не подходит», и для каждого кандидата называет причины отказа и ближайшие свободные даты. Внешних pip-зависимостей нет.

Стек

Python · стандартная библиотека · HTML/JavaScript

Модели

gpt-5.4-mini (OpenAI)


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

README

README.md
  1. Что делает проект

«Подбор» от команды Steppe Tech помогает заказчику выбрать event-подрядчика: ведущего, фотографа, банкетный зал, флориста и других. Заказчик указывает город, дату, тип события, категорию и бюджет. Длительность и язык можно добавить по желанию. Сервис возвращает не длинный список, а до трёх подрядчиков. Каждый выбор объяснён фактами из профиля: цитатой из описания, ценой и её долей в бюджете, языком, часами работы и отличием от двух других карточек.

Запрос можно написать обычным текстом, например «свадьба в Алматы 14 ноября, бюджет 500к, ведущий на казахском». ИИ-агент разбирает фразу, сам запускает подбор и даёт короткий совет. Если никто не подошёл, агент ищет вариант на соседней дате или с другим бюджетом.

Сервис честно говорит, когда подходящих меньше трёх или нет совсем, и объясняет причину. Он различает три исхода:

  • Подобрали. Показаны до трёх карточек. Если их меньше трёх, сервис объясняет почему.
  • В этом городе такой категории нет. Сервис называет города, где она есть, а при опечатке предлагает похожие категории.
  • Кандидаты есть, но никто не подходит. Для каждого кандидата названы все причины отказа, а также ближайшие свободные даты и бюджет, при котором кто-то подошёл бы.

Бронирования и заявок в сервисе нет, он только рекомендует.

  1. Что реализовано
  • ИИ-агент на OpenAI. Понимает запрос обычным текстом и сам вызывает движок подбора как инструмент. При пустом результате он делает до двух дополнительных поисков. Если данных не хватает, агент задаёт один уточняющий вопрос.
  • Проверка фактов в советах ИИ. Каждое число в совете сверяется с данными движка. Если число не сошлось, вместо совета показывается текст движка. Альтернативный поиск явно помечается, поэтому агент не выдаст вариант дороже бюджета за подходящий.
  • Жёсткие фильтры. Город, категория, занятость на дату, формат события, бюджет, язык и максимум часов. Занятые на дату отсекаются во всех категориях, включая площадки и отели.
  • Прозрачное ранжирование. В каждой карточке видны итоговый балл и шкала по каждому критерию с его весом.
  • Эффект даты. Сервис называет подрядчиков, которые вошли бы в тройку, но заняты именно в выбранный день. Поэтому видно, почему выдача меняется от даты к дате.
  • Метка происхождения профиля. Бейдж показывает, реальный это профиль или синтетический. Отдельно помечено, если город или цену проставили при подготовке данных.
  • Три способа работы. Веб-интерфейс, JSON API и командная строка.
  • Готовые сценарии. Пять демо-запросов подбираются автоматически под загруженные данные и запускаются в один клик.
  • Детерминизм движка. Одни и те же параметры всегда дают одну и ту же выдачу.
  • Устойчивость к ошибкам. Некорректный ввод получает понятное сообщение, а не падение сервера.
  • Тесты. 27 юнит-тестов покрывают требования задачи, загрузку данных и ИИ-агента.
  1. Технологии и архитектура

Проект написан на Python 3.10+ и использует только стандартную библиотеку. Устанавливать пакеты через pip не нужно. ИИ-агент работает через OpenAI API на модели gpt-5.4-mini. Интерфейс сделан одной HTML-страницей на чистом JavaScript.

Модули проекта:

  • podbor/data.py загружает данные из CSV, XLSX и JSONL, понимает русские заголовки и нормализует поля.
  • podbor/engine.py выполняет подбор: проверку запроса, фильтры, ранжирование, объяснения и выбор исхода.
  • podbor/ai.py содержит ИИ-агента: разбор текста, вызов движка как инструмента и проверку фактов.
  • podbor/server.py запускает HTTP-сервер со страницей и API.
  • podbor/cli.py реализует командную строку.
  • podbor/text.py склоняет русские слова и форматирует деньги и даты.
  • podbor/scenarios.py подбирает демо-сценарии под загруженные данные.

Подбор идёт по шагам:

  1. Запрос проверяется и нормализуется: регистр, буква «ё», формат даты.
  2. Отбираются кандидаты нужной категории в нужном городе.
  3. К каждому кандидату применяются жёсткие фильтры, и все причины отказа сохраняются.
  4. Прошедшие ранжируются, и остаются три лучших.
  5. Выдача пересчитывается без учёта занятости, чтобы показать эффект даты.
  6. Для каждой карточки строится объяснение с учётом двух соседних.

Ранжирование использует пять критериев:

┌────────────────────────────────┬─────┐ │ Критерий │ Вес │ ├────────────────────────────────┼─────┤ │ Смысл описания и специализация │ 35% │ ├────────────────────────────────┼─────┤ │ Запас по бюджету │ 30% │ ├────────────────────────────────┼─────┤ │ Язык │ 15% │ ├────────────────────────────────┼─────┤ │ Часы на площадке │ 10% │ ├────────────────────────────────┼─────┤ │ Надёжность данных │ 10% │ └────────────────────────────────┴─────┘

ИИ-агент работает поверх движка, а не вместо него. Модель понимает запрос и решает, какие поиски сделать. Карточки, их порядок и объяснения всегда строит движок. Поэтому на одни и те же параметры выдача не меняется, а модель не может добавить подрядчика или выдумать цену. Схема инструмента разрешает только города, категории, форматы и языки из каталога.

  1. Порядок установки и запуска

Нужен Python 3.10 или новее.

git clone https://github.com/BAITC-Hacks/hack-7c6720cb-steppe-tech.git cd hack-7c6720cb-steppe-tech

Для ИИ-агента создайте в корне проекта файл .env. Файл исключён из git. Без него работает всё, кроме ИИ.

OPENAI_API_KEY=sk-...

Запуск веб-интерфейса:

python -m podbor.server

Затем откройте в браузере http://127.0.0.1:8000. На Windows лучше открывать именно этот адрес, а не localhost: с localhost каждый запрос ждёт около двух секунд.

Командная строка:

python -m podbor.cli --city Алматы --date 2026-11-14 --format свадьба --category Ведущий --budget 500000 python -m podbor.ai "той 5 декабря в Алматы, нужен флорист, бюджет 250 тысяч"

  1. Пример проверки

Все обязательные сценарии запускаются одной командой:

python scripts/demo.py

Скрипт прогоняет пять сценариев: плотная категория, тот же запрос на другую дату, редкая категория, категории нет в городе и кандидаты есть, но никто не подходит. Потом он повторяет каждый сценарий пять раз и проверяет, что выдача не меняется.

Тесты запускаются так:

python -m unittest discover -s tests -v

Для проверки в браузере есть быстрые ссылки. Адрес http://127.0.0.1:8000/#s1 сразу запускает первый сценарий. Адрес с окончанием #ask=текст запроса сразу отправляет текст ИИ-агенту.

Пример работы агента на запросе «той 5 декабря в Алматы, флорист, бюджет 250 тысяч»:

  1. На 5 декабря оба флориста в Алматы заняты, подходящих нет.
  2. Агент сам ищет на 1 декабря и находит подходящего флориста.
  3. Агент советует этого флориста и указывает, что это другая дата. Совет прошёл проверку фактов.

Ответ через API можно получить так:

curl -X POST http://127.0.0.1:8000/api/recommend -H "Content-Type: application/json"
-d '{"city":"Алматы","date":"2026-11-14","event_format":"свадьба","category":"Ведущий","budget":500000}'

Подбор без ИИ занимает меньше миллисекунды. Запрос к ИИ-агенту занимает от 2 до 7 секунд, это укладывается в лимит в 10 секунд.

  1. Используемые данные и внешние сервисы

Основной источник данных — анонимизированный датасет хакатона. Он лежит в репозитории в файле data/hackathon dataset anonymized .csv.

┌──────────────────────┬──────────────────────────────┐ │ Показатель │ Значение │ ├──────────────────────┼──────────────────────────────┤ │ Профилей │ 66 │ ├──────────────────────┼──────────────────────────────┤ │ Из них синтетических │ 13 │ ├──────────────────────┼──────────────────────────────┤ │ Категорий │ 17 │ ├──────────────────────┼──────────────────────────────┤ │ Городов │ 3: Алматы, Астана, Зарубежье │ ├──────────────────────┼──────────────────────────────┤ │ Окно календаря │ с 23.09.2026 по 31.12.2026 │ └──────────────────────┴──────────────────────────────┘

В репозитории также есть демо-набор data/demo-dataset.jsonl из 66 синтетических профилей с той же схемой. Он создан скриптом с фиксированным seed и нужен, если датасета хакатона нет. Можно подключить и свою таблицу в CSV, XLSX или JSONL: достаточно положить её в папку data/ или указать путь в переменной PODBOR_DATA.

Внешний сервис один: OpenAI API, он нужен только ИИ-агенту. Агенту отправляются текст запроса и сжатые результаты подбора: имена из каталога, цены и причины отказа. Движок, форма, API подбора и командная строка в сеть не ходят и работают без ключа.

  1. Известные ограничения
  • Совет ИИ проверяется только по числам. Имена модель берёт из результатов подбора, но код их отдельно не сверяет.
  • Совет ИИ может слегка меняться между запусками. Формулировка и выбор альтернативного поиска зависят от модели. Карточки на одни и те же параметры всегда одинаковы.
  • Описания подрядчиков сопоставляются по словарю основ слов. Перефразирования вне словаря сервис не находит. Например, «проводы невесты» без слова «узату» не распознаются.
  • Веса ранжирования подобраны вручную. Данных о том, кого заказчики выбирают на самом деле, нет.
  • Бюджет относится к одному подрядчику. Сравнивается только цена «от», а итоговая цена может оказаться выше.
  • Профили без цены, форматов или языков не отсекаются. Пробел отражается в тексте карточки и снижает балл.
  • Занятость известна только с 23.09.2026 по 31.12.2026. Для дат вне этого окна сервис предупреждает, что занятость неизвестна.
  • Склонения прописаны вручную. Для нового города текст будет корректным, но более казённым.
  • Судьям без своего ключа OpenAI ИИ-агент недоступен. Остальной сервис работает полностью.

Планы развития: эмбеддинги для поиска по смыслу описаний, разметка описаний через LLM с кешированием, диалог с агентом поверх готового подбора, подбор нескольких подрядчиков на одну дату и настройка весов по реальным выборам заказчиков.

  1. Ссылка на развёрнутую версию

Развёрнутой версии пока нет. Сервис можно развернуть на любом хостинге с Python 3.10+ без сборки и установки пакетов:

python -m podbor.server --host 0.0.0.0 --port $PORT

Ключ OpenAI на хостинге задаётся переменной окружения OPENAI_API_KEY.

Репозиторий: https://github.com/BAITC-Hacks/hack-7c6720cb-steppe-tech

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

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

diwarti 5ar1anbek 4D1ret1 1

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

  • 2026-09-23 17:46Add files via uploaddiwarti
  • 2026-09-23 17:46Delete README.mddiwarti
  • 2026-09-23 17:45Delete README (1).mddiwarti
  • 2026-09-23 17:44Update README.mddiwarti
  • 2026-09-23 17:40Add files via uploaddiwarti
  • 2026-09-23 17:30ИИ-агент: явно помечать альтернативный поиск, чтобы совет не выдавал вариант дороже бюджета за подходящийar1anbek
  • 2026-09-23 17:27ИИ-агент: запрос текстом, поиск альтернатив, проверка фактовar1anbek
  • 2026-09-23 16:29Update projectD1ret1
Все коммиты (10)
  • 2026-09-23 15:00Initial commit: podbor vendor recommendation servicear1anbek
  • 2026-09-23 14:58Add files via uploadar1anbek
Структура репозитория (20 файлов)
.gitignore
README.md
data/demo-dataset.jsonl
data/hackathon dataset anonymized .csv
data/hackathon dataset preview.html
podbor/__init__.py
podbor/ai.py
podbor/cli.py
podbor/data.py
podbor/engine.py
podbor/scenarios.py
podbor/server.py
podbor/text.py
podbor/xlsx.py
scripts/demo.py
scripts/make_demo_data.py
static/favicon.svg
static/index.html
tests/test_ai.py
tests/test_engine.py

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

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

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