Краткий обзор архитектуры

Приложение секретаря организовано в виде композиции docker-контейнеров, взаимодействующих через HTTP/HTTPS и WebSocket-соединения, которые устанавливаются на отдельном хосте (рисунок 1).

Рисунок 1

Компоненты системы

Docker-контейнеры

КонтейнерОписаниеПорт(ы)Технологии
clerkHTTP-сервер для приёма аудио, поиска контактов и управления телефонной книгой8000/tcpGo
asr-serverРаспознавание речи и компиляция моделей8003/tcpPython
vosk-serverWebSocket-сервер для распознавания аудио2700/tcpPython, Vosk
mongoХранилище истории вызовов и статистики27017/tcpMongoDB
keycloakСервис авторизации и управления учётными записями8085/tcpJava, Keycloak
keycloak-dbБаза данных для Keycloak5432/tcpPostgreSQL
nginxПрокси-сервер для веб-интерфейса8080/tcpNginx
webbackendБэкенд для веб-интерфейса8091/tcp

ECSS-10 SSW

СервисОписание
RestFSHTTP интерфейс с помощью которого взаимодействует MSR и IVR script взаимодействуют с clerk
MSR

Медиа сервер. Отправляет аудио поток от абонента через restfs в clerk

IVR Script

Скрипт реализующий основную логику работы с clerk

Структура docker compose

Проект построен на модульном принципе, что позволяет гибко комбинировать сервисы:

МодульФайлНазначение
Базовое ядроcompose.yamlОсновные сервисы: Clerk, ASR-Server, Vosk-Server, Mongo, Nginx, WebBackend. Обязателен для запуска
Модуль авторизацииcompose.keycloak.yamlИнтеграция Keycloak + Keycloak-DB + Keycloak-Importer в общую сеть
Модуль мониторингаcompose.peeper.yamlСтек для сбора метрик и логов (опционально)

Варианты запуска

КонфигурацияСоставИспользование
Встроенный KeycloakЯдро + KeycloakПолноценная автономная система с авторизацией
Внешний KeycloakТолько ядроИнтеграция с существующим Keycloak-сервером. Параметры задаются через .env или переменные окружения
Встроенный Keycloak + МониторингЯдро + Keycloak + PeeperПолный стек с мониторингом
Внешний Keycloak + МониторингЯдро + PeeperМониторинг с внешней авторизацией

Детальное описание сервисов

Clerk (Go-сервер)

Назначение: Основной сервис, реализующий логику голосового помощника.

Функции:

ASR-Server (Python-сервер)

Назначение: Обработка аудио, распознавание речи и управление голосовой моделью.

Функции:

Vosk-Server (Python-сервер)

Назначение: Непосредственное распознавание речи на основе модели Vosk.

Функции:

Mongo (MongoDB)

Назначение: Хранение истории и статистики.

Коллекции:

WebBackend

Назначение: Бэкенд для веб-интерфейса.

Функции:

Nginx/Frontend

Назначение: Веб-интерфейс и проксирование.

Функции:

Keycloak + Keycloak-DB + Keycloak-Importer

Назначение: Авторизация и управление пользователями.

Компоненты:

Процесс загрузки телефонной книги и компиляции модели

Источники телефонной книги

Система поддерживает два источника, настраиваемых через переменную PB_SOURCES:

AddressBook (GraphQL-сервис)

VCF-файл (HTTP-источник)

Комбинированный режим

Процесс загрузки и подготовки

  1. Инициализация (при старте):

  2. Периодическое обновление (каждые 12 часов или по запросу /pb_update):

Компиляция голосовой модели

  1. Подготовка словаря:

  2. Запуск компиляции:

  3. Ожидание завершения:

  4. Перезапуск Vosk-Server:

  5. Публикация статусов:

Механизм «тюнинга» модели

В веб-интерфейсе для контакта можно задать значение «Множитель». Значение сохраняется в оперативной памяти и в backup.pb.

При обновлении телефонной книги:

  1. Загружается актуальный список контактов из источника;
  2. Сохранённые значения множителей переносятся по UID контактов;
  3. Контакт с множителем N фигурирует в тренировочном словаре N раз;
  4. Запускается перекомпиляция модели.

Множитель меняет относительный вес контакта, повышая вероятность его выбора при распознавании.


Обработка вызова

Приём аудио от MSR/Softswitch

Процесс:

  1. Clerk извлекает домен, имя файла, call-ref;

  2. По имени файла определяет номера звонящего и автосекретаря;

  3. Создаёт контекст обработки;

  4. Запускает потоковую отправку аудио в ASR-Server по WebSocket.

Запись истории и аудио

Передача аудио в ASR по WebSocket

VAD и сегментация речи (в ASR-Server)


Клиент шлёт аудио-чанки


   [Буфер VAD]


  Анализ (200 мс)

        ├─ Тишина → ожидание
        ├─ Начало речи → старт сегмента
        └─ Конец речи → завершение сегмента


  Накопление секундных порций


  Отправка в Vosk (порциями по 1 секунде)


  Получение partial-результатов → отправка в Clerk


  Завершение сегмента → отправка целого отрезка в Vosk


  Получение final-результата → отправка в Clerk

Диалоговый поиск контакта

Алгоритм для каждого текстового сегмента:

  1. Добавить сегмент к общему накопленному тексту;

  2. Нормализовать текст (регистр, лишние символы);

  3. Выполнить поиск в телефонной книге:

  4. Возможные исходы:

Контекст диалога:

Итоговый ответ и взаимодействие с MSR

Ничего не распознано

HTTP/1.1 206 Partial Content
{
  "done": false,
  "recognized": "",
  "negative_url": "negative/<callRef>"
}

Уточнение / Нет контакта

HTTP/1.1 206 Partial Content
{
  "done": true,
  "recognized": "<текст>",
  "answer": "<фраза для TTS>",
  "negative_url": "negative/<callRef>"
}

Успешный поиск

HTTP/1.1 200 OK
{
  "done": true,
  "recognized": "<текст>",
  "number": "<найденный номер>",
  "positive_url": "positive/<callRef>",
  "negative_url": "negative/<callRef>"
}

История и статистика

Статусы истории:

История вызовов

Эндпоинты Clerk:

Структура записи:

{
  "_id": "ObjectId(...)",
  "call_ref": "3095-6666",
  "req_source": "ivr",
  "detection_attr": "fio",
  "status": "unknown",
  "date": "2026-03-20T11:17:57.709Z",
  "files": {
    "2026-03-20_11-17-54-519208_asr_3095-6666.wav": "ковалев"
  },
  "additional": {
    "source": "msr",
    "sample_rate": 48000
  },
  "source": "3095",
  "clerk_num": "6666",
  "number": null
}

Статистика

Мониторинг (опционально)

Модуль мониторинга (compose.peeper.yaml) включает стек для сбора метрик и логов:

Порты и сетевые взаимодействия

СервисПортПротоколНазначение
Clerk8000/tcpHTTP/WSОсновное API, WebSocket статусов
ASR-Server8003/tcpHTTP/WSРаспознавание, компиляция
Vosk-Server2700/tcpWebSocketРаспознавание аудио
Mongo27017/tcpTCPБаза данных
Keycloak8085/tcpHTTPАвторизация
Keycloak-DB5432/tcpTCPPostgreSQL
Nginx8080/tcpHTTPFrontend, прокси
WebBackend8091/tcpHTTP/WSBackend для UI