Введение
Мы устали слушать звонки.
Не из-за любопытства — просто это занимало слишком много времени.
Из 5 минут разговора рождались 20 минут отчёта в Excel, где человек вручную отмечал:
«вежлив ли оператор», «упомянул ли цену», «отработал ли возражение».
Мы построили систему, которая делает это автоматически:
Whisper → QLoRA → отчёт → BI.
Она оценивает звонки, считает метрики и не жалуется на переработки.
Анализ стоит $0.0003 за звонок, и работает это лучше, чем ожидалось.
Но не идеально.
вот обновлённый фрагмент раздела 1. «От Excel к первому прототипу» — с твоей логикой, цепочкой инженерных и управленческих рассуждений: как команда шаг за шагом пришла к тому, что не всё нужно обучать, и где провести границу между здравым смыслом и GPU.
стиль остался естественный, сдержанно ироничный, как будто вы действительно сидели вечером в переговорке и писали архитектуру на доске, а не пыжились быть «инновационными».
От Excel к первому прототипу
Когда таблица становится длиннее человеческой жизни, приходит время автоматизации.
Сначала всё выглядело безобидно: аналитики слушали звонки, ставили оценки, заносили всё в Excel.
Критериев было много, и со временем таблица стала напоминать отчёт NASA: десятки колонок, ручные комментарии, проценты, флаги, эмоции, и одна неизменная графа «Примечание: не уверен, но вроде нормально».
Критерий |
Тип |
Вероятность продажи % |
Регрессия |
Отработка возражений % |
Регрессия |
Вежливость % |
Регрессия |
Примеры кейсов |
Да / Нет |
Количество цен |
Счёт |
Этап завершён |
Категория |
План изначально казался простым:
«Обучим модель на всём и забудем о ручной работе.»
Мы уже почти начали собирать датасет, но здравый смысл вмешался.
Первое наблюдение:
не все колонки в Excel требовали понимания смысла.
Например, «Количество цен» можно посчитать регуляркой.
А «Примеры кейсов» — определить по наличию пары ключевых слов.
Обучать на это языковую модель — всё равно что вызывать хирурга, чтобы открыть бутылку воды.
Второе наблюдение:
GPU — штука дорогая.
Если обучать на каждом критерии, бюджет кончится быстрее, чем первая итерация обучения.
Мы решили разделить задачи по степени «интеллектуальности»:
то, где нужна интерпретация контекста (вежливость, продажи, возражения) — отправляем в LLM;
то, что можно посчитать алгоритмом, решаем кодом;
то, что является метаданными (дата, язык, длина звонка) — вообще не трогаем.
Третье наблюдение:
люди тоже ошибаются.
Если аналитики ставят оценки по-разному, обучение на таких данных лишь закрепит хаос.
Поэтому мы сначала очистили отчёты, выровняли критерии, уточнили формулировки и только потом пошли в fine-tuning.
Так появилась структура:
LLM занимается смыслом, Python фактами, Excel историей.
Итог:
мы не «передали всё модели»,
а оставили ей только те задачи, где действительно нужно понимать человека.
Это позволило снизить объём данных для обучения в три раза и бюджет — примерно в четыре.
А главное — мы сохранили контроль над системой, не превращая её в чёрный ящик, который «сам что‑то решает».
Какие данные мы анализировали
Основой стали реальные аудиозвонки колл-центра:
в продажах, поддержке и сервисных обращениях.
Каждый разговор длился от 3 до 10 минут и имел стандартную структуру: приветствие, уточнение потребностей, аргументация, возражения и завершение сделки.
Для пилота мы взяли около 5000 звонков, где люди уже вручную выставили оценки по десяткам критериев.
Так выглядел фрагмент исходного отчёта (тот самый Excel):
ID звонка |
Вежливость (0–100) |
Вероятность продажи (%) |
Возражения (0–100) |
Цены упомянуты |
Этап сделки |
Комментарий |
84213 |
78 |
64 |
72 |
Да |
Закрытие |
Много «воды», мало конкретики |
84214 |
95 |
90 |
88 |
Да |
Презентация |
Отличный тон, но затянуто |
84215 |
62 |
40 |
51 |
Нет |
Начало |
Сразу упёрся в цену |
Аналитики слушали разговор, писали комментарий, выставляли цифры.
Теперь это делает модель.
Она генерирует тот же отчёт — только без комментария «я устал слушать это».
GPT как старт и как разочарование
Начали мы, как и многие, с очевидного - использовать готовые API крупной модели.
Быстро собрали прототип: транскрипция → промпт → JSON → таблица.
Результаты выглядели прилично: модель уверенно определяла вежливость, отработку возражений и вероятность продажи.
Проблема нашлась там, где её и ожидали — в экономике.
Средняя стоимость запроса получалась около $0.04 за звонок.
Для 10 000 звонков в месяц — $400 ежедневно, не считая хранения и предобработки.
На уровне пилота — допустимо. На уровне продакшна — бессмысленно.
После анализа стало ясно:
90 % запросов — однотипные и не требуют больших моделей;
большая часть токенов тратится на «шумовые» фразы;
latency и стоимость API не позволяют интегрировать систему в потоковую аналитику.
Решение оказалось очевидным:
мы не хотели просто «умный прототип», нам нужна была производственная система,
которая работает быстро, стабильно и предсказуемо по бюджету.
Так мы пришли к идее — собрать свою модель: компактную, дообученную под домен,
которая выполняет задачу точно, но без необходимости оплачивать мегамозг ради простого «спасибо, до свидания».
Отбор кандидатов
Когда стало ясно, что API — не вариант, мы решили протестировать открытые модели.
Критерии отбора были простые:
поддержка русского языка;
устойчивость к длинным транскриптам (до 6–8k токенов);
адекватный JSON-вывод;
приемлемая стоимость инференса.
Мы проверяли Mistral 7B, Llama 2 7B, и Qwen 2.5 7B, используя по 200 звонков из реального датасета.
Вот результаты (всё замеряли при одинаковом промпте и одинаковом объёме текста):
Модель |
Язык (качество) |
MAE ↓ |
F1 ↑ |
Среднее время ответа |
Стоимость / 1000 звонков |
Комментарий |
Mistral 7B |
слабый |
10.8 |
0.74 |
2.1 c |
~$0.70 |
Быстрая, но путает смысл. «Хорошо поговорили» — всегда 100 %. |
Llama 2 7B |
средний |
7.2 |
0.81 |
4.3 c |
~$1.20 |
Понимает контекст, но «задумчивая». Тяжело масштабируется. |
Qwen 2.5 7B |
сильный |
4.1 |
0.88 |
2.9 c |
~$0.35 |
Оптимальный баланс: понимает, не галлюцинирует, не ломает JSON. |
Qwen уверенно справилась с длинными звонками и лучше других обрабатывала смешанную речь (русский + английские фразы).
Кроме того, она давала на 30 % меньше «творческих» ответов, чем Llama, и стабильно держала формат вывода.
На графике ниже видно, как менялись качество и стоимость:
Модель |
Качество (F1) |
Стоимость ($/1000 calls) |
GPT-4 (baseline) |
0.91 |
40.0 |
Llama 2 7B |
0.81 |
1.2 |
Qwen 2.5 7B |
0.88 |
0.35 |
Mistral 7B |
0.74 |
0.7 |
Разрыв между GPT и Qwen по качеству оказался всего 3 пункта,
зато по цене — в 100 раз.
Qwen мы выбрали как основу и провели дообучение LoRA на собственных данных,
чтобы она понимала тонкости речевых шаблонов: «вежливо, но настойчиво», «возражение смягчено», «продажа закрыта, но клиент недоволен».
После обучения Qwen не только перестала «переобучаться на доброте»,
но и начала выставлять оценки, практически совпадающие с человеческими метками.
Когда модель начала понимать людей
До обучения модель выглядела как вежливый студент-практикант: старается, но не вникает.
Она выдавала аккуратные JSON-ответы вроде
{"вежливость": 95, "продажа": 100},
даже если клиент в конце сказал: «Спасибо, больше не звоните.»
После LoRA-дообучения всё изменилось.
Мы обучали Qwen на 5000 размеченных звонках, где были не только оценки, но и текст комментариев аналитиков.
Модель впервые получила контекст почему оценка именно такая — и начала рассуждать.
Обучающих звонков |
MAE ↓ |
F1 ↑ |
Пример понимания контекста |
300 |
14.2 |
0.65 |
«Оператор вежлив, но не предложил решение.» → всё равно ставит 90 % |
1000 |
8.1 |
0.78 |
«Оператор перебил клиента.» → снижает вежливость до 60 % |
5000 |
4.0 |
0.88 |
«Оператор предложил скидку, клиент согласился.» → 92% вероятность продажи |
Это был первый момент, когда ответы перестали быть механическими.
Модель начала понимать структуру разговора:
где клиент колеблется, где оператор уходит в скрипт, где диалог превращается в взаимное раздражение.
Мы добавили промежуточный слой интерпретации — промпт, который заставляет модель сначала объяснить ход рассуждений, а уже потом выдать JSON.
Выглядит это так:
{
"reasoning": "Оператор предложил вариант, клиент согласился, возражений не было.",
"вежливость": 92,
"отработка_возражений": 88,
"вероятность_продажи": 94
}
После этого качество выросло не только по цифрам, но и по восприятию.
Когда мы сравнивали с человеческими метками, 83 % расхождений объяснялись субъективностью, а не ошибкой модели.
Иногда машина даже попадала точнее.
Например, оператор сказал с усталым тоном:
«Я не могу вам помочь, но спасибо, что обратились.»
Человек поставил «вежливость 90».
Модель — 55, объяснив:
«Формально вежливо, но клиенту не предложено решение.»
И да, она была права.
С этого момента мы начали относиться к ней как к коллеге,
а не как к инструменту.
Она не просто считала слова — она понимала, когда разговор был хорошим, а когда просто звучал прилично.
Компрессия: меньше слов, больше смысла
Проблема пришла не с моделью — с людьми.
Оказалось, что средний звонок длиной 5 минут содержит менее 20% полезного текста.
Остальное — эхо, паузы, «ммм», «да‑да‑да, секундочку, я уточню».
Whisper транскрибировал всё это честно, но модель потом тонула в мусоре.
Наивный подход — просто «давайте отправим всё в LLM» — быстро разбился о реальность токенов.
Каждый звонок превращался в 6–8 тысяч токенов,
и модель тратила треть вычислений на «угу».
Пришлось действовать хирургически.
Первый этап: структурная фильтрация
Мы разработали простой, но эффективный фильтр:
Разбиваем транскрипт на фразы по паузам.
Удаляем короткие реплики (<3 слова), если они не содержат действий («да», «угу», «сейчас», «секунду»).
Сжимаем последовательные повторы («да‑да‑да‑да» → «да»).
Оставляем только смысловые куски, где есть глаголы или цифры.
Это дало — 60% токенов сразу, без потери информативности.
Мы протестировали: F1 упал на 1,8 %, но расходы — на 68 %.
Прекрасный обмен.
Второй этап: смысловая компрессия
Следом мы научили модель резюмировать диалоговые блоки.
Например, если оператор три раза объясняет условия рассрочки,
мы оставляем только одну реплику с агрегированным смыслом:
«Оператор трижды объяснил условия рассрочки, клиент уточнил детали, возражений нет.»
Это не просто сокращает размер — это делает контекст чище для анализа.
Вместо сотни «угу» и «хорошо» остаётся настоящая структура диалога: инициатива → возражение → реакция → закрытие.
В среднем одна транскрипция сжимается с 1500 слов до 400–500.
После этого модель не только работает быстрее, но и «думает» лучше: меньше отвлекается, не теряет логику.
Третий этап: динамическая компрессия
Мы добавили автооценку плотности смысла.
Модель сама решает, насколько звонок насыщен информацией, и применяет разную глубину фильтрации.
Простой диалог («спросил цену — купил») режется на 70 %.
Эмоциональный или спорный звонок («возражения, конфликты, скидки») сохраняется почти полностью.
Так мы получили гибкость без лишнего кода.
Что это дало
Метрика |
До компрессии |
После |
Средний объём токенов |
7800 |
2100 |
Стоимость анализа / звонок |
$0.002 |
$0.0003 |
Потеря точности |
— |
~1.8 % |
Время обработки |
4.2 c |
1.1 c |
Компрессия стала главным фактором, который сделал проект экономически осмысленным.
Без неё модель работала бы красиво — и убыточно.
Теперь каждый звонок проходит через каскад:
Whisper → Фильтр → Компрессор → LoRA → Отчёт.
Самое забавное — когда мы показали людям «до» и «после»,
аналитики сказали, что сжатая версия читабельнее, чем оригинал.
Машина не просто экономила токены — она ещё и избавила всех от фраз «секунду, я уточню у коллеги».
Что обучаем, а что нет
Когда базовая архитектура заработала, возник естественный вопрос:
а надо ли вообще обучать модель на всём?
Интуиция подсказывала, что нет.
Каждая колонка в нашем отчёте требовала разного уровня «интеллекта».
Некоторые критерии — чистая логика, другие — контекст, а третьи — субъективные нюансы, которые без понимания смысла не определить.
Чтобы не тратить GPU там, где достаточно if, мы разделили всё на три слоя:
интеллектуальные, алгоритмические и метаданные.
1. Интеллектуальные критерии (требуют смысла и контекста)
Эти признаки нельзя вычислить простыми правилами.
Нужно понимать, что именно происходит в разговоре, почему оператор выбрал такую формулировку и какотреагировал клиент.
Критерий |
Пример фразы |
Что анализирует модель |
Почему нужен fine-tune |
Вежливость |
«Будьте добры, уточните, пожалуйста» vs «Я же уже сказал» |
Тональность, эмпатия, структура речи |
зависит от контекста, не от словаря |
Отработка возражений |
«Мне не нужно» → «А можно уточнить, почему?» |
Понимание причин и реакции |
требует анализа связки фраз |
Вероятность продажи |
«Хорошо, я подумаю» → «Когда вам перезвонить?» |
Намерения клиента и уверенность оператора |
логическая последовательность |
Завершение этапа |
«Договорились, я вышлю КП» |
Сигналы финализации сделки |
нужна логика диалога |
Для этих критериев модель обучалась через LoRA на 5000 примеров.
Мы использовали промпты, где описывался контекст разговора, структура диалога и требовался числовой вывод.
Результат — F1 ~0.88, что примерно соответствует точности человека-аналитика.
Интересно, что «вежливость» оказалась самой трудной метрикой:
модель понимала, что «спасибо» — это хорошо, но не улавливала усталость в ответах вроде:
«Спасибо, но не интересует.»
Только после дообучения на примерах из реальных звонков она начала различать формальную и реальную вежливость.
2. Алгоритмические критерии (определяются правилами)
Некоторые признаки не требуют искусственного интеллекта.
Зачем грузить GPU вопросами, на которые можно ответить регуляркой?
Критерий |
Метод |
Пример логики |
Количество упоминаний цены |
Regex + счётчик |
`r’\d+ ?(руб |
Наличие ключевых фраз |
Keyword match |
«доставка», «скидка», «гарантия» |
Длительность звонка |
Метаданные |
len(transcript)/WPM |
Язык общения |
Lang detect |
ru/en mix detection |
Мы не стали обучать модель искать слово «цена» — она и без того знала это слово.
Проще подсчитать, сколько раз оператор произнёс «рублей» и вывести долю упоминаний.
Бонус: такие вычисления выполняются в 50–100 раз быстрее, чем LLM-инференс,
и позволяют фокусировать вычислительные ресурсы там, где действительно нужен смысл.
3. Метаданные и вспомогательные признаки
Часть информации вообще не требует анализа речи.
Например:
Время звонка,
Продолжительность разговора,
Номер клиента,
Канал коммуникации (входящий / исходящий).
Эти данные просто передаются из CRM или телефонной системы,
и потом используются в аналитике для сегментации.
Почему это решение оказалось стратегическим
Сократило затраты на обучение примерно в 4 раза. Вместо 12 GPU-часов на эпоху мы уложились в 3.
Снизило риски деградации модели — LoRA трогает только нужные слои.
Обеспечило прозрачность: мы знаем, какие решения принимает ИИ, а какие — просто логика.
Упростило масштабирование: можно добавлять новые правила, не переписывая промпты и не трогая веса модели.
Инфраструктура, которая спит и просыпается
Всё развернули в Amazon EKS:
vLLM — быстрая подача запросов,
Karpenter — поднимает GPU только при нагрузке,
KEDA — масштабирует воркеры автоматически.
В простое — 0 GPU.
При пике — кластер.
Система живёт своей жизнью: мы просто наблюдаем.

Экономика
Показатель |
До |
После |
Стоимость звонка |
$0.03 |
$0.0003 |
Время анализа |
20 мин |
10 сек |
Аналитики / 1000 звонков |
80 ч |
10 мин GPU |
Точность |
0.88 |
0.88 |
Экономия - x100 по стоимости,
и главное — время: теперь отчёт готов в тот же день, а не через неделю.


Что дальше
Детекция эмоций и интонаций — чтобы понять, доволен ли клиент на самом деле.
Intent‑детектор — чтобы определить цель звонка без человека.
Самообучение на обратной связи от операторов.
Расширение на другие языки (и культурные паттерны).
Выводы
GPT-API красиво, но дорого.
LoRA — компромисс между качеством и бюджетом.
Компрессия текста спасает бюджет лучше, чем CFO.
Kubernetes можно заставить работать, если его не трогать.
Совершенства нет: модель ошибается, но уже делает жизнь людей проще.
Мы продолжаем развивать систему речевой аналитики и помогаем компаниям выстроить свои пайплайны под задачи — от транскрипции до оценки качества диалогов.
Если вы работаете с большими объёмами звонков и хотите понять, как снизить затраты или повысить точность, можем обсудить архитектуру и подходы на короткой консультации.