AAYMA
RU
Войти

SaqtaDauys

Голосовой ассистент страхового контакт-центра: распознаёт речь на RU/KK/смешанной, LLM-маршрутизатор выбирает один или несколько из 40…

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

О проекте

Команда: Zethus
Кейс HackAlem.ai: Коммуникации — Halyk Bank · кейс 2
Стадия: Рабочий MVP

Задача кейса: «Voice Router»: голосовой AI, маршрутизирующий звонки в контакт-центре страховой компании

Суть

Голосовой ассистент страхового контакт-центра: распознаёт речь на RU/KK/смешанной, LLM-маршрутизатор выбирает один или несколько из 40 бизнес-сценариев, диалоговый движок уточняет данные, проверяет полис и просит подтверждение. Работает в вебе с микрофоном, в Telegram-боте и в терминале.

Как устроено

Голос из браузера или Telegram распознаётся и передаётся в диалоговый движок на Python. LLM (gpt-4o-mini) разбирает реплику: какие сценарии (SC21, SC22…), какие поля и какой ответ. Движок держит состояние и очередь намерений, дозапрашивает слоты, обращается к учебному backend (полисы, запись к врачу) и перед действием запрашивает согласие. Ответ озвучивается, панель супервизора показывает транскрипт, сценарий, альтернативы, поля и тайминги этапов. Есть оценщик на dev-наборе и замеры задержки.

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

  • LLM intent routing (multi-intent)
  • slot filling
  • очередь намерений
  • подтверждение перед действием
  • mock backend
  • оценщик на dev-наборе
  • замеры латентности
  • Telegram long polling

Метрики

маршрутизация на dev-наборе 100%; 126 автоматических тестов

Особенности

Несколько намерений в одной реплике: вторая просьба ставится в очередь, а после смены темы разговор возвращается к незавершённой задаче. Один движок обслуживает три интерфейса. Telegram-бот печатает в терминале QR-код для жюри. Объяснение выбора сценария формируется фоновым запросом и не влияет на маршрутизацию.

Стек

Python · vanilla JS/HTML/CSS · Telegram Bot API · Segno

Модели

gpt-4o-mini


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

README

README.md

SaqtaDauys — от живой речи к нужному сценарию

Страховой ассистент, с которым можно говорить своими словами.
Хакатонный прототип для кейса Voice Router · Saqta Insurance

Запустить · Показать жюри · Архитектура · Результаты

Python 3.10+   gpt-4o-mini   RU · KK · mixed   Web + Telegram

«Можно своими словами?» — Именно так и задумано.

Карта проекта — перейти к нужному разделу

Идея · За минуту для жюри · Примеры запросов · Несколько намерений · Выбор интерфейса · Установка и запуск · Архитектура · Точность и тесты · Задержка · Ограничения · Карта файлов

Что мы делаем

«Запишите меня к лору. И ещё скажите, покроет ли страховка лекарства» — в одной реплике уже две просьбы. Клиент может передумать, сменить язык или вернуться к предыдущему вопросу. Голосовому роботу нужно понимать такой разговор и выбирать подходящий сценарий обслуживания.

SaqtaDauys соединяет LLM-маршрутизатор с диалоговым движком на Python. Модель разбирает речь и выбирает намерения; движок уточняет данные, проверяет полис, ведёт очередь вопросов и запрашивает подтверждение перед действием. Основное демо — микрофон и голосовой ответ в браузере, рядом панель супервизора. Также доступны Telegram-бот и текстовый чат в терминале.

ЯзыкиКаталогДемоПроверки
Русский, казахский, смешанная речь40 бизнес-сценариев + 3 системныхБраузер и Telegram126 автоматических тестов

Статус: хакатонный прототип. Клиенты, полисы и операции учебные. Результат маршрутизации на dev-наборе — 100%; свободный диалог ещё требует доработки.

За минуту для жюри

01 · ПОПРОБОВАТЬ

Начните разговор

Откройте веб-демо, включите микрофон и задайте вопрос о страховке. Выбранный сценарий появится рядом с ответом.

Перейти к запуску →
02 · РАЗОБРАТЬСЯ

Посмотрите на решение

В панели супервизора — транскрипт, сценарии, объяснение, альтернативы, поля и длительность этапов.

Открыть архитектуру →
03 · ПРОВЕРИТЬ

Повторите эксперимент

В репозитории есть оценщик, тесты и отчёты замеров. Результаты открытого набора и ограничения описаны отдельно.

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

Показ на 3–4 минуты: приветствие → запись к врачу → смена темы → возврат к задаче → подтверждение. Реплики и пояснения для выступления уже подготовлены; для оценки можно задавать и свои вопросы.

Что можно попробовать

Реплика клиентаЧто демонстрирует
«Проверьте, действует ли мой полис ОГПО»Поиск клиента, выбор полиса и проверку срока.
«Хочу записаться к лору завтра в Астане по ДМС»Сбор данных и запись после подтверждения.
«Проверьте полис и измените почту на [email protected]»Несколько просьб в одном сообщении.
«А сначала скажите адрес офиса в Алматы»Смену темы с сохранением незавершённой задачи.
«ДМС полисімнің мерзімін тексеріңізші»Обращение на казахском языке.

Одна реплика — несколько задач

Иллюстрация: просьба записать к лору и проверить покрытие лекарств разделяется на SC21 и SC22. Движок уточняет данные, запрашивает подтверждение записи и предлагает вернуться к следующему вопросу.

Иллюстрация работы с несколькими намерениями, а не запись конкретного прогона. SC21 отвечает за запись к врачу, SC22 — за проверку покрытия. Вторая просьба остаётся в очереди; перед выполнением записи движок запрашивает согласие.

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

Выберите удобный вход

Один движок диалога, три способа поговорить с ним. Команды выполняются после подготовки окружения; данные для первого разговора — ниже.

🎙️ В браузере💬 В Telegram⌨️ В терминале
Для основного показа жюриДля проверки с телефонаДля разбора логики
Микрофон, голосовой ответ и панель супервизора рядом с чатом.Голосовые сообщения, текст и QR текущего бота при запуске.Реплики с клавиатуры или из файла, подробная трассировка.
python src/web_demo.pypython src/telegram_bot.pypython src/chat_demo.py --trace
Нужен ключ OpenAI.Нужны ключ OpenAI и токен Telegram.Нужен ключ OpenAI.

Сеансы разных интерфейсов независимы: разговор из браузера не переносится в Telegram.

Быстрый старт

Нужны Python 3.10+, интернет и ключ OpenAI API. Для браузера и текстового чата достаточно ключа OpenAI; токен нужен только Telegram. Команды ниже выполняются из корня проекта.

1. Подготовить окружение

python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

Если .env ещё нет, скопируйте шаблон:

cp -n .env.example .env

Заполните файл своими значениями. Существующие ключи менять не нужно.

OPENAI_API_KEY=ваш_ключ_OpenAI
TELEGRAM_BOT_TOKEN=токен_от_BotFather
TELEGRAM_ALLOWED_USER_IDS=

Токен Telegram выдаёт @BotFather по команде /newbot. Пустой TELEGRAM_ALLOWED_USER_IDS разрешает доступ всем, кто напишет боту. Чтобы оставить доступ команде, узнайте ID через /id, перечислите их через запятую и перезапустите процесс. Файл .env исключён из Git.

Команды для Windows PowerShell
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
if (!(Test-Path .env)) { Copy-Item .env.example .env }

2. Открыть голосовое веб-демо

python src/web_demo.py

Откройте http://localhost:8000, разрешите микрофон и нажмите «Говорить». После реплики нажмите «Стоп». Ответ прозвучит в браузере; справа появятся сценарий, объяснение, альтернативы, поля, действия и время этапов. Если браузер запретил автоматическое воспроизведение, нажмите ▶ на плеере. Для другого порта: python src/web_demo.py --port 8080.

Объяснение готовится отдельным фоновым запросом и не меняет выбранные сценарии. Его оценка уверенности не является калиброванной вероятностью. Текстовый ввод пригодится для учебного телефона или при ошибке распознавания.

Как выглядит веб-демо

Веб-демо: реальный голосовой прогон и панель трассировки

Дополнительно: Telegram-бот с QR для жюри
python src/telegram_bot.py

В терминале появятся ссылка и QR-код — жюри сможет открыть бота камерой телефона. Адрес определяется автоматически через getMe для токена из .env: при запуске другого бота QR тоже изменится. QR создаётся локально библиотекой Segno. Если терминал не поддерживает символы QR, останется обычная ссылка.

Откройте бота по QR или ссылке, нажмите Start и отправьте «Здравствуйте» голосовым сообщением. Бот покажет распознанный текст и ответит текстом и голосом. Оставьте терминал открытым; остановка — Ctrl+C. После изменения кода нужен перезапуск. Домен и публичный сервер для этого демо не требуются: используется long polling. Запускайте один процесс на токен; для бота с существующим webhook создайте отдельного демо-бота.

3. Провести первый разговор

В браузере нажмите «Новый разговор»; в Telegram отправьте /reset и /demo. Отправляйте по одной реплике и дожидайтесь ответа:

Хочу записаться к лору завтра в Астане по ДМС.
+77010000002
Да.

«Да» отправьте после предложения подтвердить запись. Телефон удобно вводить текстом; остальные реплики можно произнести. В учебной базе «сегодня» — 1 октября 2026, поэтому «завтра» означает 2 октября.

Учебный телефонДля чего подходит
+77010000002ДМС: запись к врачу и вопросы о покрытии.
+77010000001Действующие ОГПО и КАСКО.
+77010000003Проверка просроченного ОГПО.

Личный номер может отсутствовать в учебной базе. «Новый разговор» в браузере или /reset в Telegram возвращает исходные данные. Готовый план выступления — демо за 3–4 минуты.

Команды Telegram-бота
КомандаДействие
/demoПоказать учебных клиентов.
/resetСбросить разговор и изменения учебной базы.
/voice_on · /voice_offВключить или выключить голосовые ответы.
/trace_on · /trace_offПоказать или скрыть файлы трассировки.
/idУзнать свой Telegram ID для списка доступа.
/helpОткрыть справку.

Как это работает

flowchart LR
    T["Браузер / Telegram<br/>голос или текст"] -->|голос| S["Распознавание<br/>голоса"]
    T -->|текст| D["Диалоговый движок<br/>состояние · проверки"]
    S --> D
    D <--> L["LLM<br/>сценарии · поля · ответ"]
    D <--> B["Учебный backend<br/>полисы · расчёты · запись"]
    D --> R["Ответ<br/>текст + голос"]
    R --> T
    classDef accent fill:#d1fae5,stroke:#059669,color:#064e3b
    class D,L accent

LLM получает каталог сценариев, контекст и факты. Python проверяет допустимые ID, формат данных, принадлежность полиса и подтверждение операции. На новом запросе маршрутизация и извлечение полей выполняются параллельно; действия — последовательно. В браузер озвучка передаётся потоком. При смене темы незавершённая задача сохраняется; у каждого пользователя свой сеанс.

ЭтапМодель
Выбор сценария и диалогgpt-4o-mini
Распознавание голосового сообщенияgpt-4o-mini-transcribe
Диктовка телефона или ИИНgpt-4o-transcribe
Голосовой ответgpt-4o-mini-tts, голос coral

Подробнее: карта модулей, состояние и подтверждения.

Три решения, на которых держится демо
  • Понимание и исполнение разделены. LLM выбирает сценарий и извлекает поля; Python проверяет их и привязывает подтверждение к конкретной операции.
  • Контекст принадлежит разговору. У каждого сеанса свои задачи и учебный backend. Смена темы сохраняет незавершённую просьбу; сброс начинает разговор заново.
  • Объяснение и скорость видны отдельно. Объясняющая модель работает в фоне и не может поменять выбранные ID. Панель отделяет время серверных этапов от начала воспроизведения в браузере.

Результаты и проверки

Сохранённый predictions.json проверен на 104 репликах открытого dev-набора. Для сравнения приведены результаты первого прогона:

МетрикаИсходный промптУточнённый промпт
Верный первый сценарий98 / 104 · 94,2%104 / 104 · 100%
Полное совпадение набора сценариев96 / 104 · 92,3%104 / 104 · 100%
Полнота намерений в составных запросах96,2%100%

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

Свежий независимый вызов текущего маршрутизатора тоже дал 104/104: отчёт проверки. Сохранённый predictions.json при аудите не перезаписывался.

Проверить сохранённые результаты и запустить тесты без внешних API и ключа (HTTP-тесты используют локальный loopback):

python data/evaluate.py predictions.json data/dev_utterances.json
python -m unittest discover -s tests -v

126 тестов проверяют загрузку данных, ответы маршрутизатора, переходы диалога, подтверждения, разбор номеров, Telegram и QR, изоляцию веб-сеансов, потоковую передачу аудио и независимость объяснений от выбора сценария. Внешние API в них подменены. Отдельно проверен живой диалог ДТП: сообщение о погибшем заполняет признак пострадавших, короткий адрес сохраняется дословно, бот сообщает о необходимости экстренного обращения и учебном характере передачи.

В финальном прогоне перед сдачей через настоящий API прошли запись к лору с подтверждением, проверка полиса на казахском, ДТП и возврат к задаче после обращения к оператору. Отдельно проверены смешанная реплика и голосовой запрос в браузере с объяснением маршрута. В последнем прогоне голос зазвучал через 4765 мс от оценённого конца речи; это один замер, а не новая медиана и не гарантия времени ответа на площадке.

Текстовый чат, повторяемые диалоги и новый прогон маршрутизатора

Эти команды обращаются к OpenAI и расходуют API-квоту:

# Интерактивный чат с трассировкой
python src/chat_demo.py --trace

# Диалоги из файлов
python src/chat_demo.py --script examples/chat_demo.json --trace
python src/chat_demo.py --script examples/dialog_regression.json --trace
python src/chat_demo.py --script examples/handoff_regression.json --trace
python src/chat_demo.py --script examples/accident_regression.json --trace

# Заново классифицировать dev-набор и заменить predictions.json
python src/main_router.py
python data/evaluate.py predictions.json data/dev_utterances.json

Команды внутри текстового чата: /demo, /reset, /state, /quit. После нового прогона метрики нужно пересчитать.

Задержка: что измерено

Замеры SaqtaDauys: медиана диалога 2566,5 → 1559,5 мс, снижение на 39,2%; полный голосовой прогон — 5190 мс, один замер. Ориентир 1,5 с пока не достигнут.

Нажмите на карточку, чтобы открыть методику. Значения взяты из сохранённых отчётов; условия двух измерений различаются.

На пяти запросах, повторённых дважды в обоих режимах, медиана обработки диалога снизилась с 2566,5 до 1559,5 мс — на 39,2%. Все 10 пар сохранили выбранные сценарии. Это время диалога без STT, TTS и воспроизведения.

Полный голосовой smoke-тест с настоящим OpenAI API и синтетическим голосом дал 5190 мс от оценённого конца речи до события playing в Chromium; сам маршрутизатор занял 733 мс. Это один замер, не репрезентативная медиана. Ориентиры 500 мс / 1,5 с пока не достигнуты. По PDF они дают бонус за скорость и не являются условием сдачи.

Методика, сырые замеры и повторный запуск · Сверка с техническим заданием PDF

От результата — к доказательствам

Что хотите проверитьГде посмотретьКак читать результат
Выбор сценариевПрогон маршрутизатора104 открытые реплики; промпт дорабатывался по этому набору.
Выигрыш от параллельных вызововПарные замеры диалогаСравнение обработки текста; без распознавания и озвучки.
Полный голосовой путьТрассировка браузерного прогонаОдин запрос через настоящий API с синтетическим голосом; не медиана на наборе жюри.
Исправление диалога ДТПДо и после исправленияСохранение сообщения о пострадавших и короткого адреса; варианты ответов RU/KK.
Готовность перед сдачейФинальный прогонЧетыре диалога через настоящий API, смешанная реплика и один голосовой запрос с объяснением.
Соответствие кейсуАудит требований PDFЧто реализовано, что проверено и что остаётся проверить на площадке.

Границы демо

  • Исполнение сценариев. Для 33 бизнес-сценариев есть обработчики. SC02, SC04, SC05, SC06, SC12, SC27, SC28 передаются оператору в демо. Полное оформление всех продуктов ещё не реализовано.
  • Учебные операции. Записи, обращения и изменения контактов хранятся в памяти. Реальные полисы, SMS и письма не отправляются; живой оператор не подключается. Расписание клиник сгенерировано для демонстрации.
  • Голосовые сообщения. Записи до 60 секунд и 10 МБ. Телефонные звонки, непрерывный разговор и перебивание бота пока не реализованы.
  • Качество и скорость. При ошибке распознавания можно отправить текст. Браузер оценивает конец речи по энергии микрофона и измеряет начало воспроизведения. Для оценки жюри нужна серия живых реплик и контроль секундомером. Telegram не сообщает момент первого звука на телефоне; эта метрика там остаётся пустой.
  • Локальный сервер. Веб-демо слушает только 127.0.0.1; оно предназначено для запуска на ноутбуке. Публичный хостинг, телефония и промышленная авторизация не настроены. Chromium проверен; другие браузеры требуют отдельной проверки.

Текст, короткая история и аудио обрабатываются OpenAI; при использовании Telegram сообщения также остаются в чате. Используйте синтетические данные из комплекта. Аудио приложения хранится в памяти. В .runtime/ сохраняются номер обновления Telegram и отчёты, если запускать диагностику. Идентификация по телефону упрощена. Внутри одного сеанса реплики обрабатываются последовательно; сеанс сбрасывается после часа простоя или перезапуска.

Если на демонстрации что-то не сработало
Что происходитЧто сделать
Бот отвечает по старой логике после правки кодаОстановить старый процесс через Ctrl+C, запустить его заново и сбросить разговор.
Не найден клиент по личному телефонуВзять учебный номер под веб-чатом или через /demo в Telegram. Для ДМС — +77010000002.
Браузер не записывает голосОткрыть демо через localhost, разрешить микрофон в браузере и проверить выбранное устройство ввода.
Ответ пришёл, но звука нетПроверить переключатель «Голос», громкость и кнопку ▶. В Telegram включить /voice_on.
Цифры распознаны неверноОтправить номер текстом. Голосовой и текстовый ввод используют один разговор.
API временно недоступенПроверить интернет, доступ и квоту используемого ключа; затем повторить реплику.

Новый независимый пример начинайте с «Новый разговор» или /reset. Так предыдущая задача не вмешается в следующую проверку.

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

Это направления дальнейшей работы. Текущее демо и его ограничения описаны выше.

Где что лежит

src/
├── main_router.py      # Пакетная маршрутизация → predictions.json
├── chat_demo.py        # Разговор в терминале
├── web_demo.py         # Локальный HTTP-сервер и голосовой API
├── web/                # Микрофон, плеер и панель супервизора
├── telegram_bot.py     # Telegram и QR текущего бота
├── benchmark.py        # Парные замеры диалога через настоящий API
├── config.py           # Модели, пути и лимиты
├── agent/              # Состояние, каталог и управление диалогом
└── tools/              # Учебный backend, аудио и Telegram API
data/                   # Материалы кейса и оценщик
examples/               # Реплики для повторяемых прогонов
tests/                  # Проверки без внешних API
docs/                   # Архитектура и сценарий выступления

Для работы с кодом:

python -m pip install -r requirements-dev.txt
ruff check src tests
ruff format --check src tests

Общий стиль задан в pyproject.toml. Применить форматирование: ruff format src tests.


Команда Zethus · Voice Router

Материалы кейса · Қазақша сипаттама · План демонстрации · Архитектура

Слушать человека. Понимать просьбу. Показывать решение.
SaqtaDauys · HackAlem AI · Команда Zethus

↑ Вернуться к началу

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

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

Abzal Nurlanuly 12Abzal Nurlanuly 4Sagimbekov Sanat 3

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

  • 2026-09-23 17:30fix: stabilize dialog flows and sanitize public examplesAbzal Nurlanuly
  • 2026-09-23 17:11docs: enhance README visuals and demo navigationAbzal Nurlanuly
  • 2026-09-23 16:43feat: add web voice demo and improve accident dialog handlingAbzal Nurlanuly
  • 2026-09-23 15:55Add Dynamic Telegram QR and fix dialog handlingAbzal Nurlanuly
  • 2026-09-23 15:15Visual UpdateAbzal Nurlanuly
  • 2026-09-23 15:02UpdateAbzal Nurlanuly
  • 2026-09-23 14:41updateAbzal Nurlanuly
  • 2026-09-23 13:52updateAbzal Nurlanuly
Все коммиты (19)
  • 2026-09-23 13:30UpdateAbzal Nurlanuly
  • 2026-09-23 13:12updateAbzal Nurlanuly
  • 2026-09-23 12:21updateAbzal Nurlanuly
  • 2026-09-23 12:00updateAbzal Nurlanuly
  • 2026-09-23 11:59test5678Abzal Nurlanuly
  • 2026-09-23 11:57testAbzal Nurlanuly
  • 2026-09-23 11:55testSagimbekov Sanat
  • 2026-09-23 10:43DeletedSagimbekov Sanat
  • 2026-09-23 10:42test from second teammateSagimbekov Sanat
  • 2026-09-23 10:14Merge remote changesAbzal Nurlanuly
  • 2026-09-23 10:02initial commitAbzal Nurlanuly
Структура репозитория (63 файлов)
.env.example
.gitattributes
.gitignore
README.md
data/README.kz.md
data/README.md
data/README.ru.md
data/actions.json
data/dev_utterances.json
data/dialogs_sample.json
data/evaluate.py
data/knowledge_base.json
data/mock_backend.json
data/scenarios.json
data/slots.json
docs/ARCHITECTURE.md
docs/DEMO.md
docs/LATENCY.md
docs/REQUIREMENTS.md
docs/assets/conversation.svg
docs/assets/hero.svg
docs/assets/latency.svg
docs/assets/web-demo.png
docs/measurements/accident-dialog.json
docs/measurements/final-readiness.json
docs/measurements/latency-dialog.json
docs/measurements/router-audit.json
docs/measurements/voice-smoke.json
examples/README.md
examples/accident_regression.json
examples/chat_demo.json
examples/dialog_regression.json
examples/handoff_regression.json
predictions.json
pyproject.toml
requirements-dev.txt
requirements.txt
src/__init__.py
src/agent/__init__.py
src/agent/catalog.py
src/agent/dialog_manager.py
src/agent/llm.py
src/agent/numbers.py
src/agent/state.py
src/benchmark.py
src/chat_demo.py
src/config.py
src/main_router.py
src/telegram_bot.py
src/tools/__init__.py
src/tools/audio.py
src/tools/backend.py
src/tools/telegram_api.py
src/tools/terminal_qr.py
src/web/app.js
src/web/index.html
src/web/style.css
src/web_demo.py
tests/test_dialog.py
tests/test_latency.py
tests/test_main_router.py
tests/test_telegram.py
tests/test_web.py

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

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

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