Привет! Я Артём Юрченко — DS-инженер в команде Недвижимости Авито. Наши кол-центры совершают до 30 000 звонков в день, и вручную можно проверить лишь небольшую часть из них. Расскажу, как мы начали строить систему речевой аналитики и разработали первую модель, которая автоматически находит в звонках возражения клиентов и анализирует, как операторы их отрабатывают.
Статья будет полезна DS-инженерам, аналитикам и продакт-менеджерам, которые работают над продуктами построения речевой аналитики.
В этой статье:
• Зачем понадобился сервис речевой аналитики
• Как собирали модель для поиска возражений
• Как выбирали и обучали модель
• Как выглядит архитектура сервиса

Зачем понадобился сервис речевой аналитики
Эта идея пришла сразу из трёх продуктовых направлений недвижимости:
Комфортная сделка — программа, в которой мы помогаем собственникам продавать недвижимость. Сотрудники кол-центра помогают людям присоединиться к программе и объясняют, как ей пользоваться. Качество работы сотрудников показывает метрика conversion rate (CR).
Новостройки — сервис, в котором мы подбираем подходящую новостройку заинтересованным покупателям, а затем передаём застройщику. Оплату получаем от застройщиков за каждого заинтересованного клиента, поэтому кол-центры работают на увеличение целевых лидов.
Ипотека и страхование — на этом направлении мы приводим в банк целевых лидов по ипотеке и страховкам. Задача кол-центра — увеличивать CR в оформление страховок и ипотек.
У всех есть свои кол-центры, которые взаимодействуют с пользователями, и во всех направлениях одинаковые проблемы:
🔻 В сутки кол-центры совершают до 30 000 звонков, но вручную можно проанализировать только 3% от них. Нет возможности собрать, обобщить и проанализировать обратную связь от клиентов.
🔻 Сложно оценить работу каждого оператора и понять, что именно происходит во время разговоров.
🔻 Возникает риск мошеннических действий — как со стороны операторов, так и со стороны пользователей. Например, пользователь предлагает сотрудничество в обход нашего сервиса.
Исходя из этих проблем мы определили общую цель — извлекать из звонков полезную информацию, чтобы повышать эффективность работы операторов.
Для этого нам нужно:
Суммаризировать диалоги. Менеджерам, которые следят за работой операторов, нужна возможность быстро прочитать краткое содержание разговора, чтобы не прослушивать полную запись.
Лучше понимать желания и ожидания клиентов. В разговорах пользователи рассказывают о себе — ответы можно использовать, чтобы автоматически формировать портрет клиента.
Оценивать качество работы операторов. Речевая аналитика должна помогать операторам соблюдать скрипты и качественно реагировать на возражения клиентов. Также нужно избегать стоп-слов — формулировок, которые нельзя использовать или, наоборот, обязательно нужно произнести.
Чтобы система оценки была объективной, мы проверяем, какие именно критерии влияют на итоговый показатель качества — CR. Это позволяет руководителям контакт-центра точно понимать, на чём следует фокусировать внимание.
Одна из ключевых задач операторов — обработка возражений. Успех сделки часто зависит от того, насколько качественно оператор отработает аргументы клиента. Поэтому мы начали работу с модели поиска возражений.
Обычно, когда оператор предлагает клиенту вступить в программу, пользователь почти всегда отказывается.
Всего сформулировано 8 типов возражений:
• Не готов участвовать в программе
• Хочу продавать сам
• Не хочу работать по договору
• Не хочу работать с агентом
• Неинтересно
• Не хочу платить комиссию / слишком большая комиссия / дорого
• Надо подумать или надо посоветоваться
С точки зрения ML — это задача извлечения структурированной информации из диалога — текст возражения, его тип и ответ оператора. Кроме того, модель должна определять, получилось ли успешно отработать возражения клиента.
Ответ модели — это JSON-структура, где для каждого возражения указывается его тип, текст из транскрипции и соответствующая реплика оператора.
В select_objection добавляем тип возражения, в input_obj — текст возражения из транскрибации. Поле answered_objection показывает один из трёх ответов:
была отработка;
не было отработки;
не было возможности отработать, в том числе если звонок оборвался.
Поле input_answer_obj — текст обработки возражения.


Как собирали модель для поиска возражений
Разработка шла по следующему пайплайну:
1️⃣ Подготовка данных
2️⃣ Создание первого проекта разметки — приземление критериев
3️⃣ Написание промпта для авторазметки
4️⃣ Создание второго проекта разметки — оценка авторазметки
5️⃣ Обучение LoRA-адаптера
6️⃣ Создание третьего проекта разметки — оценка адаптера
На первом шаге убедились, что транскрипции звонков доступны и их можно корректно извлекать. В процессе очистили данные от мусора: среди записей встречались пустые транскрипции или звонки, где автоответчик говорил, что абонент недоступен. Разметку проводили через внутренний инструмент Dataset Collector.
В роли разметчиков выступили руководители кол-центров: это заинтересованные лица, которые уже знакомы с бизнес-процессами. Так сэкономили время на обучение и сделали работу с персональными данными безопаснее.
Разметка проходила в три этапа:
Утверждение формата выдачи модели
Оценка качества авторазметки
Оценка качества итоговой модели
Для первой итерации взяли несколько десятков наблюдений, для последующих — выборки по несколько сотен. Каждое наблюдение оценивали три асессора. Полное совпадение мнений позволяло использовать пример в качестве эталона для оценки модели.
При расхождении в оценках мы проводили сессии обсуждения: анализировали спорные моменты и уточняли правила разметки. Интересно, что в ряде случаев асессоры признавали ответы LLM более корректными, чем изначальная ручная разметка.
Объём выборки для разметки определялся двумя факторами:
загрузкой руководителей кол-центров;
необходимостью получить достаточное количество наблюдений по каждому типу возражений и флагов отработки.
В идеале мы хотели бы разметить десятки тысяч звонков для обучения LoRA-адаптера, но это физически невозможно сделать вручную. Поэтому мы выбрали авторазметку с последующей проверкой качества на небольшой подвыборке.
На первой итерации утвердили формат выдачи модели. Чтобы корректно сравнивать текстовые поля, решили копировать реплики целиком, а несколько реплик разделять символом «\n».
На следующих этапах мы оптимизировали процесс: вместо разметки с нуля асессоры корректировали результаты авторазметки. Это не только сократило число расхождений, но и позволило сразу фиксировать ситуации, когда LLM размечала наблюдение удачнее человека.
Асессор видел более качественный вариант и просто засчитывал его без исправлений.
Написали промпт для LLM, чтобы провести авторазметку. Модель обрабатывала звонки по тем же правилам, которые использовали асессоры. Мы сверили полученные результаты с данными второй разметки и сопоставили ответы модели с оценками асессоров.
В ходе оценки типов возражений показатели weighted avg precision, recall и F1-меры достигли 0,75, 0,68 и 0,70 соответственно. Сравнение реплик возражений и их отработок проводилось по мере Жаккара, которая дала значения 0,75 и 0,66.
Основную долю ошибок составили случаи, когда модель путала рекламу других продуктов и отработку возражений. Поскольку такая реклама носила временный характер, к моменту внедрения сервиса баг поправили. Значимые ошибки возникали редко.
Защита от ошибок модели
Руководители кол-центра периодически слушают часть звонков, на которые указала наша модель. Параллельно они выписывают в отчёт ошибки, и, если какое-то изменение скрипта существенно влияет на качество авторазметки, обращают на это внимание ds-команды, которая запланирует улучшение модели.
Как выбирали и обучали модель
Мы рассматривали разные подходы: от простых регулярных выражений до классических NLP-моделей (tf-idf + logreg, BERT-like модели для классификации и NER). Однако быстро поняли, что такие методы плохо подходят для нашей задачи. Основные причины: необходимость формировать связанные поля в JSON и недостаточная универсальность таких решений для задач речевой аналитики.
В итоге выбрали LLM-подход и протестировали несколько моделей: Mistral, Qwen и нашу A-vibe.
Отдельно экспериментировали с промптами. Мы пробовали короткие и длинные инструкции. В коротких модель просто получала транскрипцию и схему ответа, а в длинных — подробное описание критериев и формата результата.
Оказалось, что длинные инструкции не улучшают качество. В итоге лучше всего работал короткий промпт, в котором мы задавали формат JSON и кратко описывали необходимые поля.
Модель обучали с помощью LoRA-адаптера на авторазмеченном датасете. По итогам экспериментов наилучшее качество, сопоставимое с результатами авторазметки, показала A-vibe 7B. Её ответы оказались наиболее близкими к автоматической и экспертной разметке. Также у этой модели было важное преимущество: внутренний сервис для внедрения и инференса LoRA-адаптеров.
Благодаря этому не пришлось поднимать отдельный GPU-сервис, что существенно упростило внедрение.

Мы планировали встроить аналитику в re-arm — нашем внутреннем сервисе, где операторы и руководители работают со звонками. В результате сделали дашборды в Redash, чтобы не блокироваться и запуститься быстрее. Следующим шагом планируем внедрение в re-arm.

Как выглядит архитектура сервиса
Параллельно с разработкой модели мы создали сервис для автоматического скоринга звонков.
Сервис запускается по крону и взаимодействует с нашим DWH-хранилищем, что позволяет гибко отбирать транскрибации разговоров по заданным критериям. Для каждого продукта настраивается отдельный конфигурационный YAML-файл, который определяет расписание обработки, откуда брать данные и какие LoRA-адаптеры применять к диалогу.
Помимо плановой обработки, предусмотрен механизм ручного запуска — ретро-скоринг. Это позволяет запустить обработку для указанной даты, например, чтобы пересчитать результаты после изменения модели или дообработать ранее пропущенные звонки.
При любом запуске (как плановом, так и ручном) сервис анализирует записи за последние два дня и автоматически определяет, какие звонки ещё не проходили скоринг. Для хранения состояния обработки используем Redis: туда записываются идентификаторы уже обработанных звонков. Это гарантирует, что каждый звонок обработан ровно один раз. Механизм автоматического удаления устаревших записей предотвращает неконтролируемый рост хранилища.
Архитектура обработки транскрибаций выстроена в виде пайплайна из трёх этапов:
1. Предобработка — подготовка текста диалога
2. Асинхронный скоринг — обращение к LoRA-адаптерам
3. Постобработка — приведение результатов к финальному формату
Важно, что для каждой модели можно гибко назначать собственные настройки предобработки и постобработки, что делает систему расширяемой. Все результаты попадают обратно в DWH-хранилище, откуда потом берутся данные для дашбордов в Redash.

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

Статистика подтвердила: полная отработка всех возражений повышает конверсию в согласие с 6.5% до 27.1%. Эффект сохраняется при любом количестве возражений.
Ключевой инсайт: клиенты реагируют практически бинарно. Если закрыты не все возражения, эффективность резко падает. При отработке 75% возражений конверсия опускается до 6–7%, а игнорирование большей части сомнений приводит к совсем низким цифрам. Только 100%-ая отработка даёт максимальный результат. Разница с почти полной отработкой составляет более 13 %.
Также мы провели интересный эксперимент, связанный с обучением операторов. Менеджеры разговаривали с сотрудниками, которые плохо обрабатывали возражения, после чего мы сравнили их результаты до и после диалога с руководителем.
Оказалось, что разговор не давал никакого эффекта. Некоторые операторы улучшили показатели, другие, наоборот, стали работать хуже. Мы пришли к выводу, что проблема может быть не столько в операторах, сколько в скриптах разговоров. Теперь у руководителей кол-центров появилась аналитика, которая помогает пересматривать эти сценарии.

Что дальше
Модель поиска возражений — это первая часть системы речевой аналитики. Сейчас команда работает над несколькими новыми задачами. Среди них — автоматическая проверка чек-листа операторов, поиск причин нецелевых лидов и суммаризация диалогов. Параллельно обсуждаем интеграцию аналитики непосредственно в интерфейс операторов re-arm.
Главное изменение уже произошло: звонки перестали быть чёрным ящиком. Теперь из тысяч разговоров можно извлекать конкретные триггеры и использовать их для улучшения продукта.
Краткие выводы
Речевая аналитика делает звонки источником продуктовых данных. Мы автоматически проверяем 100% диалогов и выявляем то, что невозможно отследить при ручной проверке, а также подсвечиваем проблемные звонки.
LLM хорошо подходят для анализа диалогов. Если нужно учесть контекст разговора и связать между собой разные реплики, большие языковые модели оказываются более гибким инструментом, чем классические NLP-модели.
Авторазметка с помощью LLM и последующая проверка экспертами ускоряют подготовку данных. Вместо полной ручной разметки большого массива звонков мы сначала автоматически разметили данные с помощью LLM, а затем попросили экспертов кол-центра проверить и исправить результаты. Такой подход позволил быстро собрать обучающую выборку и уточнить правила разметки.
Больше о работе c LLM в Авито, а также рекомендации полезных инструментов, вакансии и анонсы в Телеграм-канале DS-инженеров «Доска AI-объявлений»

