AAYMA
RU
Войти

Сәт

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

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

О проекте

Команда: Чайка PRIME
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Доведённый продукт

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

Суть

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

Как устроено

Цепочка: CSV → SQLite (снимок каталога в памяти с версией SHA256) → строгие фильтры (занятость, формат, цена, язык, длительность) → сортировка по стартовой цене и id → до трёх кандидатов. evidence.py выделяет полные фрагменты описаний. explainer.py выбирает цитату через gpt-4o-mini или локальный fallback, после чего проверяется качество объяснений всей тройки. LLM-вызовы кешируются, объединяются и ограничены по частоте, после серии сбоев включается fallback. Состав тройки модель не определяет.

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

  • детерминированная фильтрация
  • grounded quote selection
  • кеш и дедупликация LLM-запросов
  • rate limiting
  • fallback после серии сбоев
  • openapi-typescript

Особенности

Сравнение двух дат показывает, кто стал занят, кто освободился и кто вышел из первой тройки. AI только подбирает цитату-обоснование. Контракт API генерируется в типы фронтенда, есть сборка Windows EXE и подробный QA-отчёт.

Стек

Python 3.12 · FastAPI · Uvicorn · Pydantic · SQLite · React 19 · TypeScript · Vite · Zod · pytest · Vitest · Playwright · GitHub Actions · PyInstaller

Модели

gpt-4o-mini · NVIDIA API


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

README

README.md

Сәт — умный подбор подрядчиков

Проект команды «Чайка PRIME» для HackAlem AI, кейс #79-lite.

Для жюри: приложение запускается на вашем компьютере из этого репозитория. Без API-ключа работает весь подбор и базовые объяснения; для проверки живого AI замените placeholder своим ключом по инструкции ниже. Ключ команды для запуска не нужен и в GitHub не передаётся.

Краткое описание

Сервис помогает организатору мероприятия в Казахстане выбрать подрядчика из готового каталога. Вместо длинного списка он получает до трёх карточек с объяснением соответствия запросу. Основная ценность — понятное обоснование выбора и честное объяснение отсутствия результатов.

Что реализовано

  • Подбор по городу, дате, типу мероприятия, категории и бюджету в тенге; язык и длительность опциональны.
  • Строгая проверка занятости, формата, цены, языка и применимой длительности, включая площадки.
  • До трёх карточек с именем, категориями, городом, ценой и объяснением на основе исходных данных.
  • Три разных исхода: подобрали; категории в городе нет; кандидаты есть, но условия не проходят. Неполная выдача объясняется.
  • Повторяемый порядок по стартовой цене, затем id.
  • Сравнение двух дат: кто стал занят, кто освободился, а кто остался подходящим, но вышел из первых трёх.
  • AI-выбор законченной исходной цитаты с приоритетом конкретных отличий услуги; локальный fallback при отсутствии ключа, сбое или таймауте модели.
  • Отдельные проверенные альтернативы при изменении даты, бюджета, языка или длительности.
  • SQLite-каталог, единый запуск сайта и API, маркировка синтетических профилей и дополненных данных.
  • Проверка качества объяснений всей тройки после AI, объединение одинаковых AI-запросов, лимиты вызовов, кеш и переход на fallback после серии сбоев.

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

Пользователь заполняет пять обязательных полей и при необходимости язык и длительность. После нажатия «Подобрать подрядчиков» сервер фильтрует каталог, упорядочивает прошедших кандидатов и показывает первые три. В каждой карточке есть конкретная цитата, цена и проверенные условия. Если результатов меньше трёх или нет, интерфейс объясняет причину. Альтернативы содержат явные отличия от запроса; применение изменений требует нового поиска.

Технологии

ЧастьИспользуемые технологии
BackendPython 3.12, FastAPI, Uvicorn, Pydantic, HTTPX, python-dotenv
ХранениеSQLite из стандартной библиотеки Python; CSV как источник первого импорта
FrontendReact 19, TypeScript 5.9, Vite, Zod, Lucide React
AIOpenAI Chat Completions API, модель по умолчанию gpt-4o-mini; альтернативно NVIDIA API с указанной в конфигурации моделью
Проверкиpytest, Vitest, Testing Library, Playwright, axe-core; GitHub Actions; openapi-typescript для типов API
Упаковкаpnpm и lock-файлы; PyInstaller для Windows EXE

Точные закреплённые зависимости находятся в backend/requirements-lock.txt и frontend/pnpm-lock.yaml. AI-модель не определяет цену, календарь или состав тройки. Дообучение и эмбеддинги не используются.

Архитектура проекта

CSV → SQLite → строгие фильтры → порядок по цене/id → до трёх кандидатов → проверяемые объяснения → карточки.

  • backend/catalog.py и storage.py импортируют данные и держат общий снимок каталога в памяти с версией SHA256.
  • backend/recommender.py применяет условия и формирует проверенные альтернативы.
  • backend/evidence.py выделяет полные фрагменты и факты, explainer.py выбирает цитату через AI или fallback; recommendations.py собирает ответ.
  • backend/application.py и api.py обслуживают три маршрута: health, options, recommend.
  • frontend/src/components/ содержит форму, результаты, карточку и сравнение дат; useRecommendation.ts управляет запросами и отменой устаревших ответов.
  • backend/models.py задаёт контракт, contracts/openapi.json и frontend/src/generated/api.d.ts получаются из него автоматически; frontend/src/contracts.ts проверяет ответы при выполнении.
  • run.py, backend/launcher.py и runtime.py запускают один процесс и отделяют настройки от ресурсов приложения.

Подробная архитектура · Контракт API.

Установка и запуск

Нужны Python 3.12 и Node.js 22.12+ с npm. Для первой установки нужен интернет. Репозиторий private: у проверяющего должен быть доступ к нему либо архив исходников от команды.

Скачайте исходники через GitHub → Code → Download ZIP и распакуйте либо выполните:

git clone https://github.com/BAITC-Hacks/hack-8d6786f2-prime.git
cd hack-8d6786f2-prime

Windows (PowerShell), из корня проекта:

.\scripts\setup.ps1
.\.venv\Scripts\python.exe -X utf8 run.py

Один процесс открывает сайт http://127.0.0.1:8765 вместе с API. Отдельный сервер SQL не нужен. setup.ps1 устанавливает зависимости по lock-файлам и собирает frontend. Если Python не на PATH: scripts/setup.ps1 -Python <путь-к-python.exe>. Если локальная политика блокирует скрипт, запустите powershell -ExecutionPolicy Bypass -File .\scripts\setup.ps1; системную политику менять не требуется.

Linux/macOS, из корня проекта:

python3.12 -m venv .venv
.venv/bin/python -m pip install -r backend/requirements-lock.txt
cd frontend
npx --yes [email protected] install --frozen-lockfile
npx --yes [email protected] build
cd ..
.venv/bin/python run.py

Для отдельной чистой демонстрации: python run.py --data-dir <новая-папка>. Дополнительные параметры: --no-browser, --port 8766. Ctrl+C останавливает приложение. API-документация доступна по /docs.

Готовый Windows EXE собирается отдельно: сборка и проверка ZIP. GitHub «Download ZIP» скачивает исходники, для них нужны команды выше. Ссылка на готовый релиз в текущую поставку репозитория не включена.

Собственный API-ключ жюри

  1. После первого запуска откройте созданный backend/.env в текстовом редакторе. Если приложение ещё не запускалось, скопируйте backend/.env.example в backend/.env. Не перезаписывайте уже настроенный файл.

  2. Для OpenAI заполните эти строки, заменив placeholder своим API-ключом:

    LLM_PROVIDER=openai
    OPENAI_API_KEY=PASTE_YOUR_OPENAI_API_KEY_HERE
    OPENAI_MODEL=gpt-4o-mini
    LLM_TIMEOUT_SECONDS=6
    
  3. Сохраните файл, остановите приложение через Ctrl+C и запустите снова той же командой.

  4. Проверьте реальное обращение к модели из корня проекта:

    .\.venv\Scripts\python.exe -X utf8 -m backend.check_llm
    

    На Linux/macOS: .venv/bin/python -m backend.check_llm. Успех — "ok": true и "explanation_mode": "llm". Команда делает один платный запрос по тарифу вашего провайдера и не выводит ключ. Нет ключа — код выхода 2; сбой вызова или ответа — код 1.

Незаменённый placeholder и пустой ключ означают fallback: подстановка вымышленных карточек не происходит. Ключ нужен только серверу; его не следует вставлять в frontend или коммитить. .env исключён из Git. При запуске с --data-dir редактируйте .env внутри этой папки; для проверки CLI задайте тот же SAT_DATA_DIR. Переменные окружения имеют приоритет над файлом.

Поддержан и NVIDIA API: задайте LLM_PROVIDER=nvidia, NVIDIA_API_KEY=<ваш ключ> и NVIDIA_MODEL=<доступный вам id модели>. Модель NVIDIA по умолчанию не задана; этот провайдер проверен тестовым транспортом, текущая живая приёмка выполнена с OpenAI.

Лимиты по умолчанию на один процесс: 4 одновременных внешних вызова, 30 новых вызовов в минуту, 500 за запуск. Они настраиваются через LLM_MAX_CONCURRENCY, LLM_CALLS_PER_MINUTE, LLM_CALLS_PER_SESSION. После достижения лимита подбор продолжает работать через fallback. Для публичного сервера дополнительно задайте денежный лимит у провайдера: лимит числа вызовов не равен ограничению расходов в валюте.

Настройки backend · Разработка frontend.

Как проверить решение

База: Алматы → 14.11.2026 → корпоратив → Ведущий → 1 500 000 ₸ → русский → 6 ч.

ПроверкаИзменение от базыРезультат на исходных 66 профилях
Плотная категорияНетТри карточки из четырёх: HK-44923, HK-29829, HK-27222
ПовторПовторить без измененийТот же порядок
Смена даты при успешной выдачеОт базы: 15.11.2026, остальные поля прежниеHK-88430, HK-44923, HK-35215. Сравнение объясняет занятость HK-29829 и выход всё ещё подходящего HK-27222 за пределы тройки
Редкая категорияФлорист, свадьба, 300 000 ₸, 8 ч, язык не заданHK-90001; второй профиль занят
Никто не подходитБюджет 600 000 ₸Точных карточек нет; причины и отдельные альтернативы
Меняется только датаОт предыдущего: 15.11.2026HK-88430, от 500 000 ₸
Категории нет в городеОт базы: Астана, ДекораторОтдельное состояние отсутствия категории
Различимые описанияАлматы, 23.09.2026, свадьба, Лайв-бэнд, 10 000 000 ₸, без языка и длительностиУ HK-23752 — два вокалиста и духовые; у HK-83709 — четыре вокалиста и струнный квартет

Сценарий защиты, матрица требований, известные ограничения.

Проверка без ключа: выполните базовый сценарий до настройки API. На карточках появляется подпись «Базовые объяснения по данным каталога (fallback)». После настройки ключа повторите базовый сценарий и выполните backend.check_llm. В ответе POST /api/recommend фактический режим находится в meta.explanation_mode; meta.ai.cache_hit отличает кеш, fallback_reason объясняет fallback, quality_repaired показывает восстановление фактов сервером. ai_available в /api/health сообщает только наличие настроек.

После установки зависимостей, из корня (здесь python — Python из созданной .venv; на Windows можно использовать полный путь .\.venv\Scripts\python.exe, на Linux/macOS — .venv/bin/python):

python -m pytest backend/tests qa -q
python qa/run_e2e.py
python qa/evaluate_explanations.py

Из frontend: pnpm test и pnpm build. Все изменяющие состояние проверки используют временные базы; массовые тесты не вызывают платный API. На Windows браузерные проверки используют Edge, на Linux/macOS установите Chromium: pnpm exec playwright install chromium в frontend. Если системная папка pytest недоступна, добавьте -p no:cacheprovider --basetemp <новая-тестовая-папка>.

Набор qa/evaluation-cases.json содержит 28 запросов по всем 17 категориям. python qa/evaluate_explanations.py --live сравнивает fallback и ваш живой API на том же наборе: до 24 новых платных вызовов, остальные запросы не имеют кандидатов. Отчёт сохраняется в qa/artifacts/evaluation.json; проверки без --live ключ не используют. Нагрузка: python qa/load_recommendations.py --requests 100 --concurrency 100.

Workflow CI настроен на backend/HTTP, frontend, сборку, генерацию контракта, оценочный набор и полный браузерный набор без секретов. Артефакт привязывается к SHA: запуски Acceptance. На 23.09.2026 GitHub не начал первый запуск из-за блокировки оплаты Actions у владельца репозитория; успешный облачный прогон не заявляется. Локальная приёмка и установка проходят: verification.md. Это не мешает локальному запуску проекта.

Результаты сравнения fallback/живого AI на опубликованном коммите: evaluation-report.md.

Данные и интеграции

Источник — предоставленный для хакатона data/contractors.csv: 66 профилей, 17 категорий, анонимизированные имена. В наборе 13 synthetic-профилей, 18 подготовленных цен и 8 подготовленных городов; все флаги сохраняются. Календарь охватывает 23.09–31.12.2026. Цена — «от» за мероприятие, max_hours=null означает неприменимость присутствия.

CSV импортируется в SQLite один раз. При старте создаётся общий снимок в памяти; health/options/recommend не перечитывают SQL на каждый запрос. Последующие запуски могут работать без исходного CSV. HTTP API доступен только для чтения. Для новой версии CSV используйте новую папку --data-dir: импорт будет отдельным, старая база сохранится. При ручном обновлении SQLite остановите приложение и перезапустите после завершения транзакции. Внутренний Store.refresh() атомарно заменяет снимок, публичного маршрута обновления нет.

Внешние интеграции: https://api.openai.com/v1/chat/completions либо https://integrate.api.nvidia.com/v1/chat/completions. Модель получает параметры запроса, факты выбранных кандидатов и допустимые исходные цитаты. Сервер проверяет id, индексы и конкретность фактов всей группы относительно fallback; числовые факты формирует сам. Таймаут по умолчанию — 6 секунд, максимум 8, включая очередь AI. Одинаковые выполняющиеся запросы объединяются; 256 успешных результатов кешируются с учётом версии каталога. После трёх сбоев новые вызовы на 30 секунд переходят на fallback. Одна неудачная модель не скрывает подходящих подрядчиков.

Ограничения

  • Бронирование, заявки, уведомления, оплата, регистрация и административная панель отсутствуют. Сервис только рекомендует.
  • Свободное поле пожеланий исключено: API принимает только параметры кейса. Семантический рейтинг качества подрядчиков не заявляется.
  • Даты вне исходного календаря отклоняются. Итоговая стоимость и фактическое качество услуги не проверяются.
  • Проверяемость цитаты не гарантирует качество исходного описания. Правила выбора фактов эвристические; при скудных или одинаковых исходных данных нельзя выдумывать отличия. Обрывы и совпадения из QA-отчёта исправлены и проверены: приёмка объяснений. Оставшиеся ограничения — в known-issues.md.
  • Наличие ключа не гарантирует доступность провайдера. Работа без интернета поддерживается через fallback, после установки зависимостей или в готовом EXE.
  • Автоматические проверки не заменяют ручной оценки объяснений, проверки на другом компьютере и нагрузочных измерений.
  • Качество источников ограничивает различимость. Сервис явно отмечает недостаток конкретных отличий; сходство или отсутствие отдельных слов — эвристические сигналы, а не доказательство качества услуги. Живой AI не гарантирует преимущество над fallback на каждой карточке.
  • Альтернативы ищут ближайшую свободную дату внутри всего известного календаря, в том числе раньше исходной; увеличение бюджета ограничено фактической ценой профиля, отдельного пользовательского потолка нет. Каждая правка показана до применения.
  • Лимиты AI, кеш и снимок каталога локальны одному процессу. Общие квоты нескольких серверов, автоматическое обновление календарного окна и SQL-фильтрация большого каталога оставлены для развития.

Развёрнутая версия

Подтверждённой ссылки на публичную deployed-версию в репозитории нет. Для демонстрации используется локальный сайт http://127.0.0.1:8765. Windows ZIP — отдельная локальная поставка, а не публичное развёртывание. Порядок сборки описан в distribution.md.

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

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

chinusoid 16Artem 8abilkhayrbigali-design 7

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

  • 2026-09-23 17:41docs(qa): add extended load security and installation resultsArtem
  • 2026-09-23 17:33Document judge setup and measured acceptance on the published revisionchinusoid
  • 2026-09-23 17:28Address architecture review with date explanations and bounded AI requestschinusoid
  • 2026-09-23 17:23docs(qa): add final verification report and testing historyArtem
  • 2026-09-23 16:21Clarify recommendation outcomes, evidence and explicit alternativesabilkhayrbigali-design
  • 2026-09-23 17:01docs(qa): publish acceptance matrix and reproducible evidenceArtem
  • 2026-09-23 16:59test(qa): cover recommendation clarity in the browserArtem
  • 2026-09-23 16:59test(qa): add calendar and explanation quality regressionsArtem
Все коммиты (31)
  • 2026-09-23 16:57Use complete distinguishing source facts in contractor explanationschinusoid
  • 2026-09-23 15:13Document platform verification and capture responsive screensabilkhayrbigali-design
  • 2026-09-23 15:10Align application duration rules with updated platform APIabilkhayrbigali-design
  • 2026-09-23 15:07Clarify alternatives and preserve explicit search flowabilkhayrbigali-design
  • 2026-09-23 16:07Focus hackathon submission on contractor recommendationschinusoid
  • 2026-09-23 14:59Harden admin sessions, conflict handling and profile managementabilkhayrbigali-design
  • 2026-09-23 14:52Improve contractor application validation and busy-date entryabilkhayrbigali-design
  • 2026-09-23 15:41Prefer service evidence over promotional copy in fallback explanationschinusoid
  • 2026-09-23 15:38test(qa): add live acceptance checks and demo documentationArtem
  • 2026-09-23 15:31Remove trailing blank line from recommendation servicechinusoid
  • 2026-09-23 15:31Serve UI and API together and add a tested Windows application bundlechinusoid
  • 2026-09-23 15:18Verify integrated platform and align null-duration QA fixturechinusoid
  • 2026-09-23 15:16Merge provider application and admin UI for integration reviewchinusoid
  • 2026-09-23 14:02Build Russian contractor matching frontend and API integrationabilkhayrbigali-design
  • 2026-09-23 14:54Validate service duration and decouple SQL startup from CSVchinusoid
  • 2026-09-23 14:38Prepare SQL platform draft and task prompts for team handoffchinusoid
  • 2026-09-23 14:09Document combined frontend and backend launchchinusoid
  • 2026-09-23 14:05Merge backend implementation for integrated site reviewchinusoid
  • 2026-09-23 14:05Merge frontend design and API integrationchinusoid
  • 2026-09-23 13:59Improve backend validation, grounded explanations and diagnosticschinusoid
  • 2026-09-23 13:39Add contractor recommendation API with grounded AI explanationschinusoid
  • 2026-09-23 12:22deletedArtem
  • 2026-09-23 12:08src addedArtem
Структура репозитория (93 файлов)
.github/workflows/acceptance.yml
.gitignore
README.md
backend/.env.example
backend/README.md
backend/__init__.py
backend/api.py
backend/app.py
backend/application.py
backend/catalog.py
backend/check_llm.py
backend/evidence.py
backend/explainer.py
backend/http_limits.py
backend/launcher.py
backend/models.py
backend/recommendations.py
backend/recommender.py
backend/requirements-lock.txt
backend/requirements.txt
backend/runtime.py
backend/storage.py
backend/tests/test_api.py
backend/tests/test_architecture.py
backend/tests/test_catalog.py
backend/tests/test_evidence_quality.py
backend/tests/test_explainer.py
backend/tests/test_runtime.py
backend/tests/test_seed_lifecycle.py
contracts/api.md
contracts/openapi.json
data/contractors.csv
docs/architecture-review-resolution.md
docs/architecture.md
docs/demo.md
docs/distribution.md
docs/evaluation-report.md
docs/explanation-quality.md
docs/final-qa-report.md
docs/known-issues.md
docs/requirements-audit.md
docs/verification.md
frontend/.gitignore
frontend/.prettierignore
frontend/.prettierrc.json
frontend/README.md
frontend/index.html
frontend/package.json
frontend/playwright.config.ts
frontend/pnpm-lock.yaml
frontend/public/favicon.svg
frontend/src/App.test.tsx
frontend/src/App.tsx
frontend/src/api.test.ts
frontend/src/api.ts
frontend/src/components/Alternatives.tsx
frontend/src/components/ContractorCard.tsx
frontend/src/components/EventForm.tsx
frontend/src/components/RecommendationResults.tsx
frontend/src/components/SelectionDetails.tsx
frontend/src/components/conditions.tsx
frontend/src/contracts.test.ts
frontend/src/contracts.ts
frontend/src/generated/api.d.ts
frontend/src/main.tsx
frontend/src/mocks/fixtures.ts
frontend/src/styles.css
frontend/src/test-setup.ts
frontend/src/useRecommendation.ts
frontend/tests/alternatives.spec.ts
frontend/tests/backend.spec.ts
frontend/tests/form.ts
frontend/tests/interface.spec.ts
frontend/tsconfig.json
frontend/vite.config.ts
packaging/READ-ME.txt
packaging/requirements.txt
packaging/windows.spec
qa/.gitignore
qa/README.md
qa/evaluate_explanations.py
qa/evaluation-cases.json
qa/load_recommendations.py
qa/playwright.config.cjs
qa/results/extended-8579db7.json
qa/run_e2e.py
qa/test_explanation_quality.py
qa/test_recommendation_http.py
run.py
scripts/build_windows.py
scripts/export_openapi.py
scripts/setup.ps1
scripts/verify_windows.py
Ветки (11)

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

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

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