Firebird — умный подбор event-подрядчиков
Сервис подбора до 3 подрядчиков мероприятия по городу, дате, формату, категории и бюджету с объяснениями, цитатами из профилей, сравнением карточек…
О проекте
Команда: Aya & Dilya
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Доведённый продукт
Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор
Суть
Сервис подбора до 3 подрядчиков мероприятия по городу, дате, формату, категории и бюджету с объяснениями, цитатами из профилей, сравнением карточек и «Планом Б» (ближайшие даты или минимальный бюджет).
Как устроено
CSV подрядчиков нормализуется в catalog.json и audit.json. POST /api/recommend валидирует запрос, применяет обязательные фильтры (включая занятость на дату) и ранжирует кандидатов по числу подтверждённых тем пожеланий, затем по цене и id. «План Б» меняет ровно одно условие: ищет до двух ближайших дат в календаре или минимальный бюджет. OpenAI (gpt-4.1-mini) по желанию переформулирует объяснения, не меняя состав и порядок выдачи; в браузере есть локальный резервный подбор.
Ключевые решения
- детерминированная фильтрация и ранжирование
- сопоставление пожеланий с цитатами
- поиск альтернатив «План Б»
- AI-редактор объяснений с проверкой
- кэш
Особенности
Выдача не дополняется искусственно: если подходят 1–2 подрядчика, сервис объясняет причину. Альтернатива меняет ровно одно условие и применяется только по клику пользователя. Состав и порядок результатов не зависят от AI-ключа. В README есть таблица сценариев для жюри с ожидаемыми ID.
Стек
TypeScript · React 19 · Vite · Node.js · tsx · csv-parse
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-34cd10d9-aya-dilya.
README
README.mdFirebird — умный подбор event-подрядчиков
До трёх подходящих подрядчиков вместо длинного каталога — с понятным объяснением каждого выбора.
Проект команды Aya & Dilya для кейса Firebird на HackAlem AI. Он помогает заказчику мероприятия выбрать подрядчика из уже имеющегося каталога: учитывает город, дату, формат, категорию и бюджет, а затем объясняет, почему показанные варианты подходят.
Основной сценарий полностью работает без API-ключей. OpenAI можно подключить дополнительно для формулировки объяснений; он не определяет состав и порядок выдачи.
Что реализовано
- Подбор по всем обязательным условиям: город, дата, формат мероприятия, категория и бюджет в тенге за одного подрядчика на событие. Дополнительно можно указать язык и длительность.
- От нуля до трёх уникальных карточек с ценой «от», объяснением и статусом занятости по данным каталога. Если найдено только один или два варианта, сервис объясняет причину и не дополняет список искусственно.
- Пожелания до 500 символов: распознаваемые темы сопоставляются с описаниями профилей и влияют на порядок подходящих кандидатов. Совпадения сопровождаются дословными цитатами.
- Необязательные AI-объяснения с маркировкой и раскрываемыми фактами-источниками. При отсутствии ключа или проблемах с моделью используются объяснения по правилам.
- «План Б» при отсутствии совпадений: ближайшие подходящие даты или изменение бюджета. Новые условия применяются только после нажатия пользователя.
- Сравнение двух или трёх результатов в таблице: цена, объяснения, подтверждения пожеланий, календарь и происхождение данных.
- Раздельные состояния для отсутствующей категории, отсутствия подходящих кандидатов, ошибок ввода и технических ошибок.
- Маркировка синтетических профилей, предположенного города и оценочной цены.
- Адаптивный русскоязычный интерфейс, быстрые примеры, сохранение условий показанного результата и защита от устаревших ответов при повторном подборе.
Как работает решение
- Пользователь заполняет условия мероприятия или выбирает пример. Пример только заполняет форму — подбор запускается кнопкой «Подобрать подрядчиков».
- Сервис проверяет запрос и применяет обязательные фильтры к каталогу. Занятые на выбранную дату профили исключаются. Если
max_hours = null, ограничение длительности присутствия неприменимо и профиль по нему не исключается. - Среди прошедших фильтры кандидатов первыми идут профили с большим количеством подтверждённых тем пожеланий, затем — с меньшей начальной ценой. Равенство разрешается по
id. Без пожеланий порядок определяется ценой иid. - Сервис возвращает до трёх карточек и объяснение общего результата. У каждой карточки есть обоснование по данным профиля. При настроенном ключе сервер может заменить его проверенным AI-текстом, сохраняя кандидатов и их порядок.
- Пользователь изучает цитаты, сравнивает карточки или применяет предложенную альтернативу и запускает подбор с новыми условиями.
Как устроен «План Б»
Каждая альтернатива меняет ровно одно условие:
- Поиск даты охватывает весь поддерживаемый календарь 23.09.2026–31.12.2026. Показываются до двух ближайших подходящих дат; при равном расстоянии сначала будущая.
- На выбранную дату вычисляется минимальный бюджет, при котором появляется кандидат. Повышение до 20% может показываться вместе с датами. Более существенное повышение предлагается, только если подходящих дат с исходным бюджетом нет, и явно помечается. При нулевом бюджете процент не вычисляется.
Город, категория, формат, язык, длительность и пожелания сохраняются. Если изменение только даты или только бюджета не помогает, готовой альтернативы нет. При отсутствующей категории «План Б» не предлагается.
Технологии
| Компонент | Реализация |
|---|---|
| Язык | TypeScript 6.0.3 |
| Интерфейс | React / React DOM 19.2.4, CSS |
| Разработка и сборка | Vite 7.3.6 |
| Сервер | Node.js, встроенный node:http, запуск TypeScript через tsx |
| Подготовка данных | csv-parse 7.0.2, локальные CSV и JSON |
| AI, необязательно | OpenAI Responses API через серверный fetch; модель по умолчанию gpt-4.1-mini |
| Проверки | Встроенный тестовый раннер Node.js, node:assert, TypeScript и проверка браузерной сборки |
Отдельная база данных не требуется. Подключений к CRM, платёжным системам и внешним календарям в текущей версии нет.
Архитектура
CSV → нормализация → catalog.json + audit.json
↓
Форма React → HTTP-адаптер → POST /api/recommend
↓
Валидация → фильтры → ранжирование
↓
Карточки, объяснения и «План Б»
↓
Необязательный редактор OpenAI
↓
Результат и сравнение в интерфейсе
При недоступности HTTP API адаптер выполняет тот же подбор локально в браузере и показывает объяснения по правилам. Серверные секреты в браузерный код не передаются.
| Путь | Назначение |
|---|---|
src/pages/RecommendationPage.tsx | Форма, состояния результатов, применение альтернатив |
src/pages/recommendationServiceAdapter.ts | Обращение к API, резервный локальный подбор, защита от устаревших ответов |
src/components/ | Карточки и таблица сравнения |
src/shared/contracts.ts | Общий контракт запросов, ответов и ошибок |
src/core/ | Валидация, фильтры, ранжирование, пожелания, объяснения и «План Б» |
src/data/ | Исходный CSV, нормализованный каталог, аудит и демозапросы |
server/api.ts | HTTP API и ограничения запросов |
server/ai-explanations.ts | Обращение к OpenAI, проверка ответа, кеш и резервные объяснения |
server/index.ts | Раздача собранного интерфейса, API и /healthz |
scripts/, tests/ | Подготовка данных, воспроизводимые сценарии и проверки |
Единый интерфейс сервиса: getCatalogOptions() возвращает справочники и диапазон дат, recommend(request) — Promise<RecommendationResponse>. Бизнес-статусы: matched, category_absent, no_match. Ошибки валидации и технические ошибки обрабатываются отдельно; HTTP API возвращает для них 400 и 500 соответственно.
Установка и запуск
1. Получить проект и установить зависимости
Нужны Git, npm и Node.js 20.x от 20.19.0 либо Node.js от 22.12.0 согласно package.json. Для закрытого репозитория потребуется доступ GitHub.
git clone https://github.com/BAITC-Hacks/hack-34cd10d9-aya-dilya.git
cd hack-34cd10d9-aya-dilya
На момент подготовки README совместная версия находится в ветке codex/smart-integration-check:
git switch codex/smart-integration-check
npm ci
Если проект уже скачан, выполните команды из корня этой версии. Для первой установки зависимостей нужен доступ к npm registry.
2. Запустить без внешнего AI
Для основного сценария .env не нужен:
npm run dev
Откройте адрес, который напечатает Vite, обычно http://localhost:5173. Если порт занят, Vite выберет следующий. Dev-сервер обслуживает и интерфейс, и /api/recommend.
3. При необходимости подключить OpenAI
Если .env ещё нет, создайте его из примера:
cp .env.example .env
Заполните локально:
OPENAI_API_KEY=ваш_ключ
OPENAI_MODEL=gpt-4.1-mini
Перезапустите сервер. Ключ должен находиться только в серверном окружении: не используйте префикс VITE_, не добавляйте ключ в Git. .env исключён через .gitignore. С настроенным ключом запрос пользователя и факты выбранных профилей отправляются OpenAI; вызовы API могут тарифицироваться.
4. Запустить собранное приложение
npm run build
npm run start
По умолчанию приложение доступно на http://127.0.0.1:4173. HOST и PORT задаются окружением или .env. Сервер раздаёт dist, обслуживает API и предоставляет GET /healthz.
Для этого запуска нужны исходные серверные файлы и установленные devDependencies, поскольку tsx находится в них. npm run preview обслуживает только статику, без API; для проверки полной версии используйте npm run start.
Как проверить решение
Сценарии для жюри
В форме есть список «Нужна отправная точка?» с готовыми запросами. После выбора нажмите «Подобрать подрядчиков». Если вводите данные вручную, оставьте необязательные поля пустыми, кроме явно указанных в сценарии.
| Сценарий | Условия | Ожидаемый результат |
|---|---|---|
| Плотная категория | Алматы · 04.10.2026 · корпоратив · Ведущий · 2 000 000 ₸ | Подходят 5, показаны 3: HK-29829, HK-35215, HK-27222. Можно раскрыть сравнение. |
| Изменение даты | Те же условия, дата 05.10.2026 | HK-88430, HK-44733, HK-77838. Прежние три профиля исключены по занятости. |
| Редкая категория | Алматы · 23.09.2026 · свадьба · Флорист · 350 000 ₸ | Два результата: HK-39372, HK-90001; третья карточка не добавляется. |
| Категории нет | Астана · 04.10.2026 · корпоратив · Лайв-бэнд · 2 000 000 ₸ | category_absent, карточек нет. |
| Все заняты | Астана · 02.12.2026 · корпоратив · Флорист · 350 000 ₸ | no_match, основная выдача пустая; можно проверить предложенные альтернативные даты. |
| Тематические пожелания | Алматы · 01.10.2026 · корпоратив · Ведущий · 2 000 000 ₸ · пожелание «IT-корпоратив» | Первым Джинбей (HK-75012) с цитатой о технологических форумах, затем HK-88430, HK-44923. Без пожелания первым идёт HK-88430. |
| «План Б» по бюджету | Алматы · 10.10.2026 · корпоратив · Ведущий · 480 000 ₸ | no_match; предложен бюджет 500 000 ₸ (+4,2%). Только после применения появляется Куррапика (HK-88430). |
Идентификаторы приведены для сверки API и автоматических проверок; в интерфейсе показаны имена. Состав и порядок результатов не зависят от наличия AI-ключа, формулировка AI-текста может отличаться.
Автоматические проверки
npm run check
npm run build
npm run demo
npm run check проверяет актуальность данных, типы, 51 тест ядра, сервера и UI-адаптера, а также браузерную сборку ядра. Среди проверок — 6 600 запросов по всем 100 датам календаря, неизменность исходных данных, границы фильтров, ранжирование, альтернативы и обработка ошибок. npm run demo воспроизводит восемь базовых сценариев, проверяет ожидаемые id и печатает замеры локального сервиса без UI и внешнего API.
Для проверки собранного приложения оставьте npm run start запущенным и выполните в другом терминале:
npm run smoke:release -- http://127.0.0.1:4173
Проверяются health endpoint, HTML, IT-подбор, «План Б», применение бюджета и ошибка даты. При настроенном ключе эта команда может вызвать OpenAI.
Отдельная проверка реального AI-вызова:
npm run check:ai
Нужен настроенный ключ. Успех — ai.mode: openai и код завершения 0. Код 2 означает отсутствие ключа, код 1 — переход на резервное объяснение. Обычные автоматические тесты используют подмену ответов OpenAI и не требуют ключа.
Данные и интеграции
Источник — предоставленный для кейса анонимизированный CSV, сохранённый в src/data/raw/contractors.csv. Продукт использует подготовленный каталог; статистика и контрольная сумма источника находятся в audit.json.
- 66 профилей: Алматы — 50, Астана — 15, значение «Зарубежье» — 1.
- 13 профилей помечены как синтетические, у 8 предположен город, у 18 оценочная цена. Эти группы могут пересекаться.
- У 9 профилей ограничение длительности присутствия неприменимо.
- Календарь фиксирован: с 23 сентября по 31 декабря 2026 года включительно.
Нормализация сохраняет флаги происхождения данных. Команда npm run data:check проверяет соответствие подготовленных файлов исходнику; npm run data:prepare пересоздаёт их. Демо использует настоящий каталог, а не заранее зашитые ответы.
Единственная внешняя интеграция приложения — необязательный OpenAI Responses API. Сервер отправляет выбранные факты, требует структурированный ответ, проверяет id, ссылки на факты, числа и некоторые неподтверждённые утверждения. Успешные ответы кешируются на 15 минут, таймаут обращения — 6,5 секунды. При ошибке или отклонении текста возвращаются объяснения по правилам.
Ограничения текущей версии
- Цена «от» не гарантирует итоговую стоимость. Отсутствие занятой даты в CSV не подтверждает реальную доступность подрядчика; внешнего календаря и актуализации занятости нет.
- Подбор работает только по данному каталогу и фиксированному диапазону дат. Синтетические и оценочные данные не выдаются за проверенные сведения.
- Пожелания распознаются словарём из десяти тем, а не универсальным семантическим поиском. Неизвестные темы не влияют на порядок; отрицания и сложные формулировки могут распознаваться неполностью. Цитаты взяты из описаний профилей, а не из отзывов клиентов.
- AI помогает только с формулировками. Проверки ответа снижают риск неподтверждённых утверждений, но не доказывают смысловую достоверность каждого предложения. При отклонении ответа AI-маркировка не показывается.
- «План Б» не меняет несколько условий одновременно и не гарантирует альтернативу для любого запроса.
- Нет регистрации, личного кабинета подрядчика, редактирования каталога, бронирования, оплаты и отправки заявок.
- API ограничен 30 запросами в минуту на адрес соединения. За прокси пользователи могут делить этот лимит; отдельной авторизации и распределённого контроля расходов нет.
- Автоматические проверки подтверждают поведение на имеющихся данных, но не измеряют пользовательскую пользу и нагрузочную устойчивость публичного сервиса.
Развёрнутая версия
Публичная deployed-версия не опубликована. Репозиторий содержит рабочие варианты локального запуска с сервером. Адреса localhost и 127.0.0.1 доступны только на машине, где запущен проект, и не являются публичной ссылкой.
Настройки для возможного размещения описаны в docs/release.md.
Дополнительные материалы
Некоторые дополнительные документы фиксируют промежуточные этапы разработки. Инструкция запуска и обзор текущих возможностей приведены в этом README.
Авторы коммитов
История коммитов
- 2026-09-23 17:14Merge pull request #3 from BAITC-Hacks/codex/smart-integration-checkayanat-amangeldi
- 2026-09-23 17:05Document Firebird setup architecture and jury verification in RussianAyanat Amangeldi
- 2026-09-23 16:58Expand Plan B date search and explain larger budget alternativesAyanat Amangeldi
- 2026-09-23 16:42Add contractor comparison and accessible card transitionsAyanat Amangeldi
- 2026-09-23 16:34Polish recommendation UI with quick examples and clearer explanationsAyanat Amangeldi
- 2026-09-23 16:26docs: record live OpenAI verification and hackathon submission requirementsAyanat Amangeldi
- 2026-09-23 15:45Prepare deployable release and Firebird defense materialsAyanat Amangeldi
- 2026-09-23 15:31feat: connect smart matching API, evidence and explicit Plan B actionsDilyara Anetbayeva
Все коммиты (15)
- 2026-09-23 15:22Add evidence-based preferences, Plan B and optional server OpenAI explanationsAyanat Amangeldi
- 2026-09-23 14:45test: verify integrated Firebird app and run UI checks by defaultAyanat Amangeldi
- 2026-09-23 14:35feat: build Russian recommendation UI with real matching serviceDilyara Anetbayeva
- 2026-09-23 14:17Merge remote-tracking branch 'origin/codex/matching-core' into codex/recommendation-uiDilyara Anetbayeva
- 2026-09-23 14:13feat: implement deterministic contractor matching with source-backed explanationsAyanat Amangeldi
- 2026-09-23 13:51chore: scaffold Firebird and define shared recommendation contractAyanat Amangeldi
- 2026-09-23 13:50docs: plan Firebird recommendation UI and integrationDilyara Anetbayeva
Структура репозитория (57 файлов)
.env.example .gitignore README.md deliverables/Firebird-defense.pptx docs/backend.md docs/defense.md docs/demo-script.md docs/integration-check.md docs/release.md docs/smart-matching.md docs/ui-plan.md index.html package-lock.json package.json scripts/check-ai-live.ts scripts/check-browser-build.ts scripts/demo.ts scripts/generate-demos.ts scripts/prepare-data.ts scripts/smoke-release.ts server/ai-explanations.ts server/api.ts server/index.ts src/components/ContractorCard.tsx src/components/ContractorComparison.tsx src/core/explanations.ts src/core/index.ts src/core/matching.ts src/core/model.ts src/core/plan-b.ts src/core/preferences.ts src/core/service.ts src/core/validate-request.ts src/data/audit.json src/data/catalog.json src/data/demo-queries.json src/data/parse-csv.ts src/data/raw/contractors.csv src/data/smart-examples.ts src/main.tsx src/pages/RecommendationPage.tsx src/pages/recommendationServiceAdapter.ts src/shared/contracts.ts src/styles/app.css tests/core/data.test.ts tests/core/fixtures.ts tests/core/integration.test.ts tests/core/service.test.ts tests/core/smart-matching.test.ts tests/server/ai.test.ts tests/server/api.test.ts tests/ui/browser.html tests/ui/browser.tsx tests/ui/http-adapter.test.ts tests/ui/requests.test.ts tsconfig.json vite.config.ts
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.