Поддерживается 2 основных источника данных для телефонной книги:
Используется как основной корпоративный справочник.
Clerk обращается к GraphQL‑API AddressBook с запросом contactsFind, получая постранично (по 1000 записей) контакты.
Для каждого контакта запрашиваются поля:
id — UID;
firstName, middleName, lastName — Имя, Отчество, Фамилия (маппинг: lastName → SecondName, firstName → FirstName, middleName → ThirdName);
org — Department (используется, если не удалось определить по иерархии);
parents — список родительских групп (kind и position) для определения Department, Group, SubGroup по маппингу уровней;
phones — массив номеров; приоритет у номера с типом work, иначе берётся первый непустой.
Авторизация выполняется через Keycloak (JWT) или по API‑ключу (зависит от AUTH_TYPE).
Используется как альтернативный или дополнительный источник (задаётся через PB_URL);
Поддерживается версия VERSION:4.0;
Обязательные поля для каждой карточки:
FN — полное имя. Разбивается по пробелам на слова (см. шаблоны выше). Если количество слов не равно 1, 2 или 3 – контакт пропускается.
TEL — номер телефона (берётся первое встреченное значение, нормализуется — удаляются все нецифровые символы).
UID — уникальный идентификатор. При отсутствии UID контакт обрабатывается, но не участвует в механизме диффа, и для него не сохраняются пользовательские настройки (например, множитель).
Необязательное поле:
CATEGORIES — содержит от 0 до 3 наименований, разделённых точкой с запятой (;). Первое → Department, второе → Group, третье → SubGroup. Если значений меньше, недостающие поля остаются пустыми. Использование запятой (,) в качестве разделителя не поддерживается — значения «слипнутся».
Все остальные поля vCard (N, EMAIL, ORG, TITLE, REV и др.) игнорируются.
Телефонная книга в приложении заполняется из заранее подготовленной адресной книги с контактами в формате vcard.
Пример контакта в vcard:
BEGIN:VCARD VERSION:4.0 UID:2368919030008402998 CATEGORIES:Отдел разработки;Космические аппараты;Микропроцессоры FN:Петрова Маргарита Дмитриевна REV:2023-09-12 09:06:38 TEL;TYPE=WORK:112 TITLE:Инженер-программист END:VCARD |
Формирование контактов из vcard во внутреннее представление автосекретаря происходит следующим образом:
Если полученных значений получается меньше трех, то недостающие поля заполняются пустой строкой.
Пример сформированного контакта в телефонной книге секретаря:
{
"UID": "2368919030008402998",
"FirstName": "маргарита",
"SecondName": "петрова",
"ThirdName": "дмитриевна",
"Department": "отдел разработки",
"Group": "космические аппараты",
"SubGroup": "микропроцессоры",
"Number": "112",
}
|
Для организации логики поиска с использованием уточнений создается словарь на основе телефонной книги, содержащий слова и фразы из телефонной книги со специальными тегами.
Специальные теги могут принимать следующие значения:
Контакты, не прошедшие валидацию (например, с повреждёнными словами, невалидным номером, неправильным форматом ФИО), не попадают в основную телефонную книгу и недоступны для поиска.
Такие записи помещаются в отдельный список повреждённых контактов, который можно просмотреть через эндпоинт /pb_corrupted (и в web‑интерфейсе). Это позволяет администратору вручную исправить данные и повторно загрузить книгу.
В логах Clerk фиксируются предупреждения о пропущенных контактах с указанием причины (например, «mixed alphabets in word», «invalid phone number», «invalid FN format»).
Некоторые контакты могут плохо распознаваться системой, в силу особенностей работы модели:
Такие контакты в дальнейшем будут называться «проблемными».
Механизм множителей улучшает распознавание таких контактов. Множитель корректирует вес в языковой модели. На примере фамилии Купп — увеличение множителя позволяет системе ASR при обработке созвучных фонем отдавать приоритет гипотезе «купп», снижая вероятность ошибочного распознавания слова «куб».
Для каждого контакта можно задать числовой множитель (по умолчанию 1), который влияет на вероятность выбора этого контакта при распознавании.
Множитель не улучшает качество распознавания речи, а только изменяет относительный вес контакта в модели: контакт с множителем 10 будет представлен в тренировочном словаре в 10 раз чаще, чем с множителем 1.
Оптимальный диапазон — от 1 до 30; значения выше 100 не рекомендуются, так как могут привести к перекосу модели в пользу одного контакта.
Изменение множителя вступает в силу только после инициации обновления телефонной книги и успешной перекомпиляции модели. Изменения сохраняются в резервной копии ( |
Для настройки множителей для проблемных контактов (рисунок 1):

Рисунок 1
Если после первого повышения множителя проблема осталась:
При необходимости можно повышать множитель ещё, но:
Множитель влияет только на вероятность выбора конкретного контакта, а не на базовое качество распознавания речи. |
После изменения множителей обязательно нужно инициировать обновление телефонной книги и дождаться завершения компиляции — без этого изменения не попадут в модель. |
На входе поиск получает текст с ASR в виде строки, и осуществляется поиск, который содержит следующие шаги:
Далее разберем шаги подробнее.
На данном этапе полученный от ASR текст очищается от лишних слов (которых нет в словаре), и к оставшимся словам добавляются соответствующие теги.
Полученный от ASR текст: иванова оля возьмите потом
Результат препроцесcинга: {слово:"иванова", тег:"secondname"}, {слово:"оля", тег:"firstname"}
Полученный от ASR текст: направление разработки медиа цэпэе
Результат препроцесcинга: {слово:"направление", тег:"notag"}, {слово:"разработки", тег:"notag"}, {слово:"медиа", тег:"notag"}, {слово:"цэпэе", тег:"notag"} |
Поиск разделен на следующие этапы:
Если в результате поиска обнаружено несколько абонентов, то запрашиваются уточнения.
Ниже представлена вводная информация о контексте.
Контекст содержит следующие поля:
Если результат поиска содержит больше одного контакта, то полученный результат записывается в OldResult.
Для составления, уточнения и изменения NextTag происходит сравнение полей полученных контактов в следующем порядке:
Сравнение полей происходит до того момента, пока все значения полей не станут равны.
Первое «неравное поле» записывается в NextTag, и все уникальные значения для текущего поля используются в строке для уточнения (если их меньше 6).
Телефонная книга, используемая в приложении, должна удовлетворять ряду обязательных условий, чтобы обеспечивать корректный поиск, распознавание и обновление данных. Эти требования едины для всех источников (Address Book и VCF) и делятся на несколько категорий.
Каждый контакт в телефонной книге должен содержать:
Уникальный идентификатор (UID) — строка, однозначно идентифицирующая запись. Используется для отслеживания изменений (добавление, обновление, удаление) при синхронизации.
ФИО — минимум одно слово (имя), максимум три (фамилия, имя, отчество). Допустимые шаблоны:
<фамилия> <имя> <отчество>
<фамилия> <имя>
<имя>
Номер телефона — строка, содержащая только цифры (0–9). Все прочие символы (скобки, тире, буквы) при загрузке игнорируются и удаляются.
Структурные поля (необязательные):
Department — подразделение (отдел, департамент).
Group — группа внутри подразделения.
SubGroup — подгруппа (если требуется более глубокая иерархия).
Все текстовые поля (ФИО, Department, Group, SubGroup) после загрузки проходят нормализацию:
приводятся к нижнему регистру;
буква ё заменяется на е;
удаляются все символы, кроме букв латиницы (a–z) и кириллицы (а–я), пробела и дефиса (-);
множественные пробелы схлопываются в один;
строка обрезается по краям.
Важно: в пределах одного слова запрещено смешивать кириллицу и латиницу. Например, «Pеtрова» — третяя буква латинская, остальные кириллические). Такие слова считаются «повреждёнными», а весь контакт исключается из основной книги и помещается в список повреждённых ( |
Телефонная книга загружается при старте Clerk и далее обновляется автоматически каждые 12 часов (по расписанию) или вручную через кнопку «Обновить телефонную книгу» в web‑интерфейсе (или POST /pb_update).
При обновлении:
Полученные контакты валидируются (проверка структуры ФИО, номера, допустимых символов);
Валидные записи проходят нормализацию и маппинг во внутренний формат;
Вычисляется хэш (Hash) каждого контакта для сравнения с текущей книгой;
Применяется дифф — добавляются новые, обновляются изменённые (по UID и Hash), удаляются отсутствующие;
Пользовательские настройки (множители) сохраняются по UID и переносятся на обновлённые записи.
После обновления книги автоматически запускается перекомпиляция голосовой модели ASR:
Clerk отправляет подготовленный словарь (с учётом множителей) в asr-server;
asr-server транслитерирует и фонетизирует контакты, пересобирает граф распознавания и перезапускает Vosk.
Компиляция может занимать от нескольких минут до 30 минут (в зависимости от размера книги и мощности хоста).
Во время компиляции модель недоступна для новых запросов (возвращается статус «компиляция»). После успешного завершения статус меняется на «готово».
В случае ошибки на любом этапе статус становится «ошибка», а предыдущая рабочая модель остаётся активной до устранения проблемы.