AAYMA
RU
Войти

EventMatch

AI-консультант по выбору event-подрядчиков: диалог (текстом или голосом) собирает условия мероприятия, Go-сервер строго фильтрует каталог и выдаёт…

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

О проекте

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

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

Суть

AI-консультант по выбору event-подрядчиков: диалог (текстом или голосом) собирает условия мероприятия, Go-сервер строго фильтрует каталог и выдаёт до трёх подрядчиков с фактами и цитатами, а при пустой выдаче показывает ближайшие альтернативы.

Как устроено

OpenAI Responses API со структурированным ответом извлекает из рассказа город, дату, формат, категорию, бюджет и пожелания, задавая по одному вопросу. Голос записывается MediaRecorder и расшифровывается через Transcriptions API. Go проверяет обязательные условия по каталогу и занятости в PostgreSQL. Прошедших сортирует смысловой индекс (эмбеддинги цитат и пожеланий), если он подготовлен, иначе по цене. Если совпадений нет, модуль alternatives показывает конкретные расхождения по цене, формату, дате и городу. В последней версии подключён Python-пайплайн (filters, ranker, generator).

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

  • structured outputs
  • strict constraint filtering
  • embedding semantic ranking
  • nearest alternatives
  • occupancy calendar
  • speech-to-text

Особенности

Размытые требования вроде «обязательно без конкурсов» не засчитываются молча: их нужно уточнить или явно согласиться продолжить без проверки. Бюджет, город и дату система сама не меняет. Демо закреплено на конкретном коммите ab45c2c.

Стек

Go · PostgreSQL · Python · JavaScript · HTML/CSS · Docker Compose

Модели

OpenAI Responses API · OpenAI Transcriptions API


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

README

README.md

EventMatch — от идеи события к подходящим людям. Проект команды Soda для HackAlem AI.

AI-консультант для выбора event-подрядчиков из каталога.
Понимает идею события, уточняет детали и объясняет каждый вариант фактами.

Возможности · Скриншоты · Запустить · Архитектура · Проверить за 5 минут · Технический справочник

Go 1.25   PostgreSQL 17   OpenAI API   JavaScript · HTML · CSS

Версия демонстрации: возможности, скриншоты и контрольные результаты ниже проверены на Go-версии ab45c2c. Запуск закреплён на этом коммите. В актуальной версии подключён Python-поиск: он получает каталог из PostgreSQL, а Go дополняет ответ ближайшими вариантами и датами. Способы запуска и различия алгоритмов описаны в справочнике.


Хорошее событие начинается с подходящих людей

У заказчика уже есть каталог подрядчиков, но выбрать по нему непросто. Кто работает в нужном городе? Кто свободен? У кого подходящий формат? Почему один вариант лучше другого — и что делать, если никто не подошёл?

EventMatch превращает каталог в понятный выбор. Заказчик рассказывает о мероприятии обычными словами или голосом, вместе с AI уточняет условия и получает до трёх подрядчиков с конкретными объяснениями. Если совпадений нет, сервис показывает причины и ближайшие варианты для пересмотра условий.

Проект команды Soda для HackAlem AI, кейс Firebird «Умный подбор подрядчиков» (#79-lite). Основной пользователь — человек, который организует свадьбу, корпоратив, день рождения или другое событие и хочет разобраться в предложениях своего города.

Понятный результатКонтроль у заказчикаФакты вместо общих похвал
До 3 подходящих карточекУсловия подтверждаются перед поискомПроверенные поля и точные цитаты
Редкие категории и пустая выдача объясняютсяБюджет, город и дату не меняем молчаЗанятые исключены из совпадений

От «есть идея» до «вот подходящие варианты»

01 · Рассказать, а не заполнять всё с нуля

«Хочу оформить свадьбу, но не знаю, кто нужен» — достаточное начало разговора. AI помогает различить флориста и декоратора, задаёт по одному вопросу, предлагает короткие ответы и принимает свободный текст. Для фотографа уточняет стиль съёмки, для ведущего — характер подачи.

Рядом заполняется карточка «Мы поняли так». Уже известные условия передаются в следующий запрос вместе с историей и ручными исправлениями. Необязательное уточнение о стиле можно пропустить.

02 · Проверить, как нас поняли

Город, дата, формат, категория и бюджет в тенге обязательны. Язык и длительность — дополнительные ограничения. Все поля доступны для правки; диктовку тоже можно отредактировать до отправки.

Неоднозначные требования не исчезают: например, «обязательно без конкурсов» нельзя выдать за подтверждённую услугу только потому, что ведущий описан как спокойный. Такой пункт требует уточнения или явного согласия продолжить без его проверки.

03 · Выбрать дату с пониманием занятости

Интерактивный календарь показывает свободных кандидатов на каждый день и среднюю занятость по месяцам с учётом условий. Если выбранный подрядчик занят, сервис предлагает ближайшие даты без отметки о занятости в известном периоде.

04 · Сравнить конкретные причины

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

Если никто не подошёл, «Ближайшие варианты» показывают все различия: на сколько выше цена, какой формат не указан, другая ли это дата или город. Эти предложения отделены от строгих совпадений. Выбор новой даты возвращает к подтверждению, а не запускает бронирование.

Посмотрите, как это выглядит

Скриншоты работающей Go-версии ab45c2c. Каталог и результаты настоящие для предоставленного датасета; имена анонимизированы, синтетические профили отмечены в интерфейсе.

Первое знакомство

Главная EventMatch: оливковая палитра, иллюстрация события и вход в AI-подбор

Диалог и живая карточка условий
Один вопрос за раз. Ответ — кнопкой, текстом или голосом.

Настоящий AI-диалог и распознанные условия мероприятия
Календарь с занятостью
Доступность по дням и нагрузка по месяцам из каталога.

Интерактивный календарь: месяцы и доступность подрядчиков по дням

Результат, который можно объяснить

Три подрядчика с ценами, происхождением данных и индивидуальными объяснениями

Даже пустая выдача помогает сделать следующий шаг

Ближайшие варианты: конкретные несовпадения с бюджетом, форматом, городом и датой

И на телефоне — тот же понятный сценарий

Мобильная версия EventMatch с диалогом и условиями

Интерфейс проверен на ширинах 320, 768, 1024 и 1440 px. Есть управление с клавиатуры, подписи полей, озвучивание нового вопроса и поддержка системного уменьшения движения. Маленький персонаж-консультант, плавные появления и движение иллюстрации отключаются кнопкой паузы в шапке.

Запустить у себя

Нужны: Go 1.25+, Docker с Compose и Git. При первом запуске нужен интернет для загрузки зависимостей и образа PostgreSQL. Node.js, npm и сборка интерфейса не требуются.

git clone https://github.com/BAITC-Hacks/hack-d3e8cd85-soda.git
cd hack-d3e8cd85-soda
git checkout --detach ab45c2ca999be63447b47c055bf77d504759b4d6
docker compose up -d --wait db
go run .

Откройте localhost:8080. Команда go run . остаётся работать в терминале. Используйте отдельную копию репозитория для демонстрации: переключение на закреплённый коммит сохраняет проверенное поведение приложения.

Без API-ключа сразу доступны ручные условия, календарь, строгий подбор, объяснения и ближайшие варианты. Данные автоматически импортируются в PostgreSQL при первом запуске и сохраняются между перезапусками.

Включить диалог и диктовку через OpenAI

Создайте локальный файл настроек, если его ещё нет:

cp -n .env.example .env

Откройте .env в редакторе и задайте OPENAI_API_KEY. Затем остановите сервер через Ctrl+C и снова выполните:

go run .

Ключ хранится на сервере; .env исключён из Git. Текстовый диалог и диктовка не требуют подготовки смыслового индекса. Микрофон доступен на localhost или HTTPS при разрешении браузера. Аудио записывается до 60 секунд, расшифровка появляется в редактируемом поле.

Включить смысловую сортировку по пожеланиям

После настройки ключа:

go run . -prepare
go run .

Первая команда создаёт data/semantic-index.json: фиксированные числовые представления цитат и пожеланий. Если сервер уже работал, перезапустите его после подготовки. Файл не перезаписывается автоматически.

Для воспроизводимого смыслового порядка на другой машине нужен тот же файл индекса, а не его повторная генерация. Сохраните подготовленный индекс вместе с решением; ключей в нём нет. Пока индекс не подготовлен, интерфейс прямо сообщает о сортировке по начальной цене.

Статус представленной версии: текстовый диалог проверен через настоящий OpenAI API. Подготовка смыслового индекса реализована, но в текущем демо индекс отсутствует — порядок по цене. Диктовка реализована и проверена с искусственным микрофоном и подменённым ответом распознавания; качество настоящей транскрипции ещё нужно проверить отдельно.

Настройки внешней БД, переменные окружения и подробности сохранения данных — в техническом справочнике.

Где работает AI, а где — строгие правила

В проверенном Go-сценарии AI участвует до выдачи карточек: разбирается в идее мероприятия, уточняет специализацию и преобразует рассказ в поля и пожелания. Проверку обязательных условий выполняет Go. Поэтому красивое описание профиля не позволяет обойти бюджет или календарь.

flowchart TD
    U["Рассказ или диктовка"] --> C["AI-консультант: смысл и уточнения"]
    C --> R["Редактируемые условия и подтверждение"]
    R --> F["Go: строгая проверка условий"]
    DB[("PostgreSQL: каталог и занятость")] --> F
    F -->|Есть совпадения| S["Смысловой индекс, если подготовлен; иначе цена"]
    S --> E["До 3 карточек: проверенные факты и цитаты"]
    F -->|Нет совпадений| N["Причины и ближайшие варианты"]
    N -->|Пользователь меняет условия| R
СлойРеализацияЗачем
ИнтерфейсHTML, CSS, обычный JavaScriptОдин Go-сервер раздаёт готовый интерфейс; нет этапа фронтенд-сборки
ДиалогOpenAI Responses API, структурированный ответИзвлечение условий и вопрос по контексту за один вызов
ГолосMediaRecorder → сервер → Transcriptions APIДиктовка с правкой текста и отдельным подтверждением
ПодборGo, общие правила для поиска и календаряСтрогие ограничения одинаково работают во всех сценариях
ХранениеPostgreSQL 17, драйвер pgxПостоянные данные, атомарный импорт, актуальная занятость
СмыслEmbeddings, фиксированный файл индексаСравнение пожеланий без нового вызова модели при сортировке
ОбъясненияПроверенные поля + точная цитатаКонкретная причина выбора, которую можно сверить с каталогом

Embeddings — числовые представления текстов для сравнения смысла. Первая версия использует 12 направлений пожеланий и одну проверенную цитату на профиль. Произвольные обязательные требования, например оборудование или вместимость, не превращаются в доказанные возможности подрядчика.

В Go-сценарии во время поиска по подтверждённым условиям внешняя языковая модель не вызывается. Ориентир ответа — до 10 секунд; это цель задания, а не заявленная гарантия под нагрузкой.

Python-модуль: поиск в актуальной версии

Команда добавила загрузку JSONL-каталога, фильтрацию, локальное сравнение пожеланий и генератор объяснений на Python. Интерфейс актуальной версии обращается к /api/search: Python ранжирует профили из PostgreSQL, а Go добавляет ближайшие варианты и даты из того же снимка данных. /api/matches сохраняет прежний Go-алгоритм. У этих путей разные сортировка и объяснения; подготовка Go-индекса не включает Python-поиск.

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

Почему повтор в Go-сценарии возвращает тот же порядок

При одинаковых подтверждённых условиях, пожеланиях, данных, коде и индексе сортировка фиксирована:

  1. Смысловая близость, если индекс подготовлен и пожелания выбраны.
  2. Начальная цена.
  3. Стабильный id при равенстве.

Порядок выбора пожеланий и их дубли не меняют результат. Изменение каталога делает старый индекс несовместимым. Сам свободный текст внешняя модель может разобрать по-разному — поэтому условия обязательно показываются для подтверждения. temperature=0 и кеш не выдаются за гарантию повторяемости.

Что защищает качество Go-подбора

Требование кейсаПоведение EventMatch
Город, дата, формат, категория, бюджетОбязательны и проверяются на сервере
Язык и длительностьУчитываются как строгие условия, если указаны
Занятый подрядчикИсключается из совпадений, включая площадки
Меньше трёх подходящихПоказываем сколько есть и объясняем причину
Такой категории в городе нетОтдельный исход category_unavailable
Категория есть, условия не проходятОтдельный исход no_matches
Конкретные объясненияЦитата профиля и факты соответствия, а не универсальные похвалы
Неизвестные условияЯвное уточнение или решение пользователя; молчаливого удаления нет
Ближайший вариантВсе несовпадения раскрыты; он не становится строгим совпадением

Важные различия: цена «от» не равна итоговой стоимости; отсутствие отметки о занятости не гарантирует бронирование; смысловая близость не подтверждает услугу; другой город не означает возможность выезда.

Проверка для жюри · пять минут

В AI-консультанте есть кнопки готовых примеров: они открывают подтверждение, а не обходят проверки. Таблица ниже проверена на версии ab45c2c и исходном каталоге; для точного порядка оставьте пожелания пустыми.

ШагЧто проверитьУсловия и ожидаемый результат
1Массовая категорияАлматы · ведущий · корпоратив · 06.10.2026 · 1 300 000 ₸ · русский · 6 ч. Семь совпадений; карточки: Куррапика → Мицури Канроджи → Аня Форджер
2Повтор и смена датыПовторить шаг 1: тот же порядок. Изменить только дату на 02.10.2026: Кики и Буллма; прошлые варианты исключены по занятости
3Редкая категорияАстана · флорист · свадьба · 01.10.2026 · 300 000 ₸ · русский. Единственный вариант — Хаку
4Занятость и ближайшие дниДля Хаку выбрать 02.10.2026. Совпадений нет; среди альтернатив — Хаку с датами 03.10, 01.10, 30.09. Выбор даты требует подтверждения
5Пустая выдача с несколькими причинамиАлматы · фото и видеобудки · день рождения · 23.09.2026 · 10 000 ₸. Совпадений нет; отдельно Кадзума Сато, Аква, Аска Ленгли с объяснением различий
6Отсутствующая категорияАстана · декоратор · свадьба · 01.10.2026 · 2 000 000 ₸. Отдельное сообщение: такой категории в городе нет

Для живого AI-сценария: «Хочу оформить свадьбу в Алматы 10 октября 2026. До 300 000 тенге на специалиста, но не знаю, кто нужен». Уточните «цветы и букеты» и проследите, как заполняются поля. Или попросите фотографа и выберите репортажный стиль. Непроверяемое «обязательно без конкурсов» должно остаться для отдельного решения перед поиском.

Тот же подбор одним API-запросом
curl http://localhost:8080/api/matches \
  -H 'Content-Type: application/json' \
  -d '{"city":"Алматы","event_date":"2026-10-06","event_type":"корпоратив","category":"Ведущий","budget_kzt":1300000,"language":"русский","duration_hours":6,"wishes":[],"unverified_requirements":[]}'

Ответ содержит status, cards, число совпадений, причины исключения, способ сортировки, версию данных и отдельные альтернативы. Описание API-маршрутов Go-сценария — в справочнике.

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

Команды и результаты в этом разделе относятся к закреплённой Go-версии ab45c2c. Проверки нового Python-модуля описаны отдельно.

go test -race ./...
go vet ./...

Обычные Go-тесты не обращаются к внешнему AI. Они проверяют ограничения, происхождение цитат, три исхода, ближайшие варианты, повторяемость, ошибки провайдера и фиксированный смысловой индекс на контрольных векторах.

ПроверкаЧто доказывает
main_test.go, alternatives_test.goСтрогие условия, объяснения, редкие категории, лимит карточек и порядок альтернатив
calendar_test.goКалендарь и подбор согласуются на всех 100 днях, границы периода и ближайшие даты проверены
consultation_test.goКонтекст диалога, обязательные поля, необязательный стиль, валидация и сбои AI
database_test.goАтомарный импорт, сохранность изменений, одновременные старты и актуальность БД
voice_test.goФормат и размер записи, ошибки распознавания, отсутствие ключа
ui_consultation_check.py, ui_requirements_check.pyБраузерный сценарий, ручные правки, отказ/повтор, явное согласие, адаптивность и анимации
Запустить проверки PostgreSQL и интерфейса

Для интеграционной проверки с локальной БД по умолчанию:

docker compose up -d --wait db
TEST_DATABASE_URL='postgres://eventmatch:[email protected]:5432/eventmatch?sslmode=disable' go test -race ./...

Тест создаёт и удаляет свою отдельную БД; требуется право CREATE DATABASE. Рабочий каталог не очищается. Без TEST_DATABASE_URL интеграционная проверка пропускается. При собственных настройках используйте соответствующий адрес БД.

При запущенном приложении, с установленными Firefox и uv:

uv run --with selenium python ui_consultation_check.py
uv run --with selenium python ui_requirements_check.py

Selenium устанавливается во временное окружение uv, не в зависимости приложения. В этих сценариях ответы AI подменяются; каталог, календарь и подбор работают через настоящий локальный сервер.

Данные, которым можно проследить источник

Для показанного Go-сценария каталог — исходный CSV организаторов: 66 профилей, 17 категорий. Это 50 профилей Алматы, 15 Астаны и один с городом «Зарубежье». Данные из сокращённого HTML-превью не используются.

  • 13 синтетических профилей организаторов, 8 дополненных городов и 18 дополненных цен сохраняют исходные флаги. Их происхождение видно в интерфейсе; добавлений команды в рабочем каталоге нет.
  • Цитаты проверяются на буквальное присутствие в описании. Это отобранные фрагменты, а не придуманные сведения о подрядчиках.
  • max_hours = null означает, что услуга не привязана к присутствию на площадке. Это допустимо, а не повод исключить флориста или декоратора.
  • Календарь известен только за 23.09.2026–31.12.2026. За его границами доступность не предполагается.

В проверенной Go-версии PostgreSQL хранит профили, занятость, цитаты и происхождение. Повторный запуск не затирает изменения, а каждый новый запрос читает актуальный каталог.

Границы версии и развитие

Текущая версия предназначена для локальной демонстрации. Публичного развёртывания и подтверждённого доступа к API Firebird нет. Бронирование, оплата и уведомления подрядчикам не входят в реализованный сценарий.

Диалог и форма живут в памяти вкладки: обновление страницы их сбрасывает. История ограничена 11 ответами пользователя, затем можно продолжить вручную. Ключи остаются на сервере; тексты и аудио не записываются приложением в БД или файлы, но отправляются OpenAI для обработки. Первичный разбор AI требует проверки человеком.

Следующие шаги: проверить качество реальной транскрипции и смыслового индекса; расширить проверяемые характеристики специалистов; добавить актуализацию занятости из подтверждённого источника; оценить качество рекомендаций на размеченных запросах. Сохранение проектов мероприятий и публичное размещение — отдельные этапы с настройкой доступа и ограничением расходов API.


Сделано командой Soda для HackAlem AI
AI-агент разработки — Codex: реализация, проверки, работа с цитатами и документация.

Полная техническая документация · Изменения проекта · Запуск

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

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

Miras Zhumazhan 12Zack-MV 3Zack-MV 2Zhasmina 2

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

  • 2026-09-23 17:32Merge pull request #4 from BAITC-Hacks/feat/catalog-aiMiras Zhumazhan
  • 2026-09-23 17:30Merge main and reconcile README with the integrated Python searchMiras Zhumazhan
  • 2026-09-23 17:09Present EventMatch with a visual README and real product screenshotsMiras Zhumazhan
  • 2026-09-23 16:42Merge pull request #2 from BAITC-Hacks/feat/catalog-aiMiras Zhumazhan
  • 2026-09-23 16:39Add contextual AI consultation and accessible interface motionMiras Zhumazhan
  • 2026-09-23 16:23Offer nearest catalog alternatives with explicit constraint differencesMiras Zhumazhan
  • 2026-09-23 17:18Fix merged app startup, UI and live PostgreSQL searchZack-MV
  • 2026-09-23 16:13Make unresolved requirements explicit and actionable before matchingMiras Zhumazhan
Все коммиты (19)
  • 2026-09-23 17:05Merge pull request #3 from BAITC-Hacks/feat/ai-event-matchingZack-MV
  • 2026-09-23 17:05Merge branch 'main' into feat/ai-event-matchingZack-MV
  • 2026-09-23 15:58Redesign EventMatch and add occupancy calendar with date alternativesMiras Zhumazhan
  • 2026-09-23 16:53feat: Implement CORS and logging middleware for improved API handlingZack-MV
  • 2026-09-23 15:10Add persistent PostgreSQL catalog and editable voice dictationMiras Zhumazhan
  • 2026-09-23 15:03Merge pull request #1 from BAITC-Hacks/feat/catalog-aiMiras Zhumazhan
  • 2026-09-23 14:47feat: connect EventMatch to organizer catalog and confirmed AI preferencesMiras Zhumazhan
  • 2026-09-23 15:46feat: add AI event matching pipelineZack-MV
  • 2026-09-23 14:01docs: describe contractor selection concept and project statusMiras Zhumazhan
  • 2026-09-23 14:17Rename README.md to README_CSS_HTML.mdZhasmina
  • 2026-09-23 14:16css, htmlZhasmina
Структура репозитория (49 файлов)
.env.example
.gitattributes
.gitignore
README.md
Soda_UI/EventMatch/README_CSS_HTML.md
ai.go
alternatives.go
alternatives_test.go
calendar.go
calendar_test.go
compose.yaml
consultation.go
consultation_test.go
data/catalog.csv
data/evidence.json
data/hackathon-dataset-anonymized.jsonl
database.go
database_test.go
docs/TECHNICAL.md
docs/images/alternatives.png
docs/images/calendar.png
docs/images/consultation.png
docs/images/home.png
docs/images/mobile.png
docs/images/readme-cover.svg
docs/images/results.png
go.mod
go.sum
main.go
main_pipeline.py
main_test.go
pipeline_api.py
requirements.txt
schema.sql
search.go
server_test.go
src/__init__.py
src/data_loader.py
src/filters.py
src/generator.py
src/ranker.py
tests/__init__.py
tests/test_e2e_pipeline.py
tests/test_pipeline_api.py
tests/test_ranker.py
ui_consultation_check.py
ui_requirements_check.py
voice.go
voice_test.go
Ветки (3)

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

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

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