Сәт
Сервис подбора подрядчиков для мероприятий в Казахстане: строгие фильтры по городу, дате, формату, категории, бюджету, языку и длительности, до трёх…
О проекте
Команда: Чайка 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 после серии сбоев.
Как работает решение
Пользователь заполняет пять обязательных полей и при необходимости язык и длительность. После нажатия «Подобрать подрядчиков» сервер фильтрует каталог, упорядочивает прошедших кандидатов и показывает первые три. В каждой карточке есть конкретная цитата, цена и проверенные условия. Если результатов меньше трёх или нет, интерфейс объясняет причину. Альтернативы содержат явные отличия от запроса; применение изменений требует нового поиска.
Технологии
| Часть | Используемые технологии |
|---|---|
| Backend | Python 3.12, FastAPI, Uvicorn, Pydantic, HTTPX, python-dotenv |
| Хранение | SQLite из стандартной библиотеки Python; CSV как источник первого импорта |
| Frontend | React 19, TypeScript 5.9, Vite, Zod, Lucide React |
| AI | OpenAI 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-ключ жюри
-
После первого запуска откройте созданный
backend/.envв текстовом редакторе. Если приложение ещё не запускалось, скопируйтеbackend/.env.exampleвbackend/.env. Не перезаписывайте уже настроенный файл. -
Для OpenAI заполните эти строки, заменив placeholder своим API-ключом:
LLM_PROVIDER=openai OPENAI_API_KEY=PASTE_YOUR_OPENAI_API_KEY_HERE OPENAI_MODEL=gpt-4o-mini LLM_TIMEOUT_SECONDS=6 -
Сохраните файл, остановите приложение через Ctrl+C и запустите снова той же командой.
-
Проверьте реальное обращение к модели из корня проекта:
.\.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.2026 | HK-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.
Авторы коммитов
История коммитов
- 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
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.