SaqtaDauys
Голосовой ассистент страхового контакт-центра: распознаёт речь на RU/KK/смешанной, LLM-маршрутизатор выбирает один или несколько из 40…
О проекте
Команда: 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
Страховой ассистент, с которым можно говорить своими словами.
Хакатонный прототип для кейса Voice Router · Saqta Insurance
Запустить · Показать жюри · Архитектура · Результаты
Python 3.10+ gpt-4o-mini RU · KK · mixed Web + Telegram
«Можно своими словами?» — Именно так и задумано.
Карта проекта — перейти к нужному разделу
Идея · За минуту для жюри · Примеры запросов · Несколько намерений · Выбор интерфейса · Установка и запуск · Архитектура · Точность и тесты · Задержка · Ограничения · Карта файлов
Что мы делаем
«Запишите меня к лору. И ещё скажите, покроет ли страховка лекарства» — в одной реплике уже две просьбы. Клиент может передумать, сменить язык или вернуться к предыдущему вопросу. Голосовому роботу нужно понимать такой разговор и выбирать подходящий сценарий обслуживания.
SaqtaDauys соединяет LLM-маршрутизатор с диалоговым движком на Python. Модель разбирает речь и выбирает намерения; движок уточняет данные, проверяет полис, ведёт очередь вопросов и запрашивает подтверждение перед действием. Основное демо — микрофон и голосовой ответ в браузере, рядом панель супервизора. Также доступны Telegram-бот и текстовый чат в терминале.
| Языки | Каталог | Демо | Проверки |
|---|---|---|---|
| Русский, казахский, смешанная речь | 40 бизнес-сценариев + 3 системных | Браузер и Telegram | 126 автоматических тестов |
Статус: хакатонный прототип. Клиенты, полисы и операции учебные. Результат маршрутизации на dev-наборе — 100%; свободный диалог ещё требует доработки.
За минуту для жюри
|
01 · ПОПРОБОВАТЬ Начните разговор Откройте веб-демо, включите микрофон и задайте вопрос о страховке. Выбранный сценарий появится рядом с ответом. Перейти к запуску → |
02 · РАЗОБРАТЬСЯ Посмотрите на решение В панели супервизора — транскрипт, сценарии, объяснение, альтернативы, поля и длительность этапов. Открыть архитектуру → |
03 · ПРОВЕРИТЬ Повторите эксперимент В репозитории есть оценщик, тесты и отчёты замеров. Результаты открытого набора и ограничения описаны отдельно. Посмотреть проверки → |
Показ на 3–4 минуты: приветствие → запись к врачу → смена темы → возврат к задаче → подтверждение. Реплики и пояснения для выступления уже подготовлены; для оценки можно задавать и свои вопросы.
Что можно попробовать
| Реплика клиента | Что демонстрирует |
|---|---|
| «Проверьте, действует ли мой полис ОГПО» | Поиск клиента, выбор полиса и проверку срока. |
| «Хочу записаться к лору завтра в Астане по ДМС» | Сбор данных и запись после подтверждения. |
| «Проверьте полис и измените почту на [email protected]» | Несколько просьб в одном сообщении. |
| «А сначала скажите адрес офиса в Алматы» | Смену темы с сохранением незавершённой задачи. |
| «ДМС полисімнің мерзімін тексеріңізші» | Обращение на казахском языке. |
Одна реплика — несколько задач
Иллюстрация работы с несколькими намерениями, а не запись конкретного прогона.
SC21 отвечает за запись к врачу, SC22 — за проверку покрытия.
Вторая просьба остаётся в очереди; перед выполнением записи движок запрашивает согласие.
Для клиента это обычный разговор. Для разработчика — проверяемая последовательность: что выбрано, каких данных не хватает и какое действие разрешено следующим.
Выберите удобный вход
Один движок диалога, три способа поговорить с ним. Команды выполняются после подготовки окружения; данные для первого разговора — ниже.
| 🎙️ В браузере | 💬 В Telegram | ⌨️ В терминале |
|---|---|---|
| Для основного показа жюри | Для проверки с телефона | Для разбора логики |
| Микрофон, голосовой ответ и панель супервизора рядом с чатом. | Голосовые сообщения, текст и QR текущего бота при запуске. | Реплики с клавиатуры или из файла, подробная трассировка. |
python src/web_demo.py | python src/telegram_bot.py | python 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.
После нового прогона метрики нужно пересчитать.
Задержка: что измерено
Нажмите на карточку, чтобы открыть методику. Значения взяты из сохранённых отчётов; условия двух измерений различаются.
На пяти запросах, повторённых дважды в обоих режимах, медиана обработки диалога снизилась с 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
↑ Вернуться к началу
Авторы коммитов
История коммитов
- 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 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.