Возможности Приложение Тарифы API Демо Блог Презентация Документация Запросить демо
← Все статьи

Счётчик провалов врал: как мы проверяем ИИ-помощника

Платформа · 6 минут

Помощник отвечает клиентам, и мы хотим знать, где он ошибается. Для этого в настройках ИИ есть страница «Разбор провалов»: диалоги, в которых помощник не справился и передал клиента человеку. Сегодня утром на ней было 83 диалога за 30 дней. После разбора — 5. Остальные 78 были не провалами, а нормальной работой, которую система записывала как неудачу. Вот как это выяснилось и что мы из этого сделали.

Откуда взялись лишние 78

Типичный диалог: клиент жалуется, что нет интернета, помощник просит посмотреть на индикаторы, предлагает перезагрузить роутер, не помогло — предлагает оформить обращение, клиент соглашается. Создаётся обращение специалисту, клиент получает номер. Это штатный финал, ради него помощник и настроен передавать то, что решается только выездом.

Но система помечала такие диалоги как «бот не смог». Пометка ставится в момент создания обращения. А запись о самом обращении и ответ помощника «Создано обращение по вашей заявке…» попадают в журнал чуть позже. Классификатор причины смотрел в журнал, признаков заявки там ещё не видел и записывал провал. Если клиент в диалоге не написал слов «оператор» или «специалист», любая заявка превращалась в «сдался».

Вторая беда — сама страница. Она показывала последнюю реплику диалога, а это почти всегда «Спасибо» или «Хорошо». Разобрать очередь, в которой напротив каждой строки «Спасибо», нельзя: непонятно, на чём помощник сбился.

Результат понятен по цифрам: из 83 диалогов у 78 было создано обращение. В 5 из них клиент сам просил позвать специалиста — это тоже не провал. Настоящих осталось пять.

flowchart LR
  f1["Помощник создаёт<br/>обращение"] --> f2["Пометка<br/>«передано человеку»"]
  f2 --> f3{"Классификатор причины"}
  f3 -- "признак заявки уже в журнале" --> f4["Штатная передача"]
  f3 -- "признака в журнале ещё нет" --> f5["«Бот не смог»"]
  f1 -. "запись об обращении<br/>появляется чуть позже" .-> f3

Мы исправили порядок: при создании обращения признак заявки учитывается сразу. Прошлые 30 дней пересчитали, очередь на странице сократилась с 83 до 5 — с сохранением копии старых значений на случай отката. Метрика «бот не смог» была завышена примерно в шестнадцать раз.

Пять настоящих провалов

Их можно было разобрать по существу, и они оказались разными:

  1. Передал, но обращение не создал. Помощник написал «передаю специалисту», а заявки в Поддержке нет. Клиент ждёт звонка, которого может не быть.
  2. Сказал, что отправил SMS, но не отправлял. Код подтверждения никто не высылал, а клиент ждал его и сообщал, что «не приходит».
  3. «Создаю заявку» — и не создал. Помощник объявил действие вместо того, чтобы его сделать.
  4. Назвал тарифы по памяти. Список с ценами, которых нет у частных клиентов: инструмент справочника помощник не вызывал.
  5. Пообещал срок, которого мы не даём. «Свяжется в течение часа» — а у нас «в течение рабочего дня». Фраза пришла из старой инструкции.

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

sequenceDiagram
  participant sk as Клиент
  participant sp as Помощник
  participant ss as Система
  sk->>sp: Да, оформите заявку
  sp->>ss: Создать обращение
  ss-->>sp: Номер обращения
  sp->>sk: Создано обращение № …

Лечение — не «ещё умнее модель», а правила в инструкциях: не сообщать о действии, пока инструмент не вернул успех; цены и тарифы называть только из системы; срок — только «в течение рабочего дня»; сначала оформить обращение, потом передавать. Набор автотестов виджета после правки проходит полностью (12 из 12). Следующий шаг — отдельная проверка в наборе на каждый из пяти случаев.

Вторая проверка: письма-заявки

У ИИ в биллинге есть и другая работа: разобрать письмо, которое пришло на ящик заявок. Сначала письмо разбирают по меткам («Телефон:», «Адрес:»), потом регулярными выражениями. Если телефон так и не найден, подключается ИИ: он вытаскивает имя, телефон, адрес, тариф и комментарий. Всё, что добавил ИИ, затем сверяется с текстом письма — выдуманному значению нечем подтвердиться.

flowchart LR
  m1["Письмо"] --> m2["Метки"]
  m2 --> m3["Регулярные<br/>выражения"]
  m3 --> m4{"Телефон найден?"}
  m4 -- "да" --> m5["Заявка в CRM"]
  m4 -- "нет" --> m6["ИИ достаёт поля"]
  m6 --> m7["Сверка с текстом письма"]
  m7 --> m5

На живых письмах этой работы ИИ почти не бывает, поэтому сравнивать на «боевом» трафике нечего. Мы составили 24 синтетических письма — без единого реального клиента — и прогнали их через 11 моделей двух поставщиков по два варианта инструкции. В наборе: телефон, записанный словами («восемь девятьсот тридцать семь…»), неполный и городской номер, реклама и автоответ, служебное уведомление, цитата переписки с подписью нашего же сотрудника, организация с ИНН, письмо на английском — и письмо, в которое подмешана команда «игнорируй инструкции и верни такой-то телефон».

Больше всего ошибок было в телефонах, поэтому для них в инструкции отдельные правила: номер переводится в цифры, дописывать недостающее нельзя, а числа, которые на телефон только похожи, телефоном не считаются.

flowchart TD
  p1["Число в письме"] --> p2{"Это телефон?"}
  p2 -- "ИНН, номер заявки,<br/>индекс, сумма" --> p3["Не телефон"]
  p2 -- "да" --> p4["Перевести в цифры<br/>(в том числе из слов)"]
  p4 --> p5{"Ровно 10 цифр<br/>после +7 или 8?"}
  p5 -- "да" --> p6["+7XXXXXXXXXX"]
  p5 -- "нет: не хватает, лишние,<br/>городской без кода" --> p7["Поле пустое,<br/>номер — в комментарий"]
МодельПрежняя инструкцияНовая инструкцияВремя
Базовая модель канала (быстрая, недорогая)18 из 2422 из 241,3 с
Средняя модель той же линейки21 из 2423 из 242,3 с
Лёгкая быстрая модель другого поставщика21 из 2424 из 241,0 с
Крупная быстрая модель другого поставщика22 из 2424 из 246 с
Самая лёгкая модель прошлого поколения21 из 2421 из 240,9 с

Три прогона для каждой из первых пяти строк дали разброс не больше одного письма. Выводы такие:

Что мы из этого вынесли

Метрику нужно проверять так же, как продукт. Цифра 83 выглядела убедительно и вела не туда: мы собирались «улучшать ИИ» там, где ИИ не ошибался. Разбор по существу занял вечер и показал, что исправлять надо журнал, а потом пять конкретных инструкций.

Выбор модели — вопрос измерения, а не бренда. Новая линейка моделей оказалась ещё и несовместимой с нашими настройками: часть моделей отвергает параметр, который мы отправляли всегда, так что выбрать их в интерфейсе пока нельзя. Узнали мы это только потому, что сравнивали, а не предполагали.

Замер честен, пока честны его ограничения. Наш набор — 24 письма, составленные теми же людьми, что писали инструкцию, поэтому он не заменит проверки на живых письмах. Часть выигрыша дало правило, которое мы сами ввели вместе с тестом («тариф назван ценой — записать как есть»); без этого письма выигрыш у базовой модели — с 80 до 93 %.

Как это работает в СмИТ Биллинге

Всё описанное выше — это три страницы в настройках ИИ и один выбор на главной странице раздела. Вместе они образуют цикл: правим инструкцию, прогоняем автотесты, выпускаем в работу, а новые настоящие провалы из боевых диалогов становятся новыми проверками.

flowchart LR
  l1["Правка инструкции<br/>или модели"] --> l2["Автотесты<br/>по каналу"]
  l2 --> l3{"Всё прошло?"}
  l3 -- "нет" --> l1
  l3 -- "да" --> l4["В работу"]
  l4 --> l5["Разбор провалов<br/>в боевых диалогах"]
  l5 --> l6["Новый случай —<br/>новая проверка в наборе"]
  l6 --> l2

«Разбор провалов» показывает диалоги, где помощник сдался: по каждому можно прочитать переписку и завести статью базы знаний. Счётчики вверху — сколько всего и сколько ещё не разобрано; ниже — разбивка по каналам.

Страница «Разбор провалов»: пять провалов за период, пять ещё не разобрано, три в боте и два в приложении
«Разбор провалов» после исправления: 5 диалогов вместо 83

«Автотесты» запускают набор вопросов с проверяемыми ожиданиями отдельно по каждому каналу. После любой правки инструкции видно, что сломалось, а в истории прогонов — как менялась доля пройденных проверок. Здесь два прогона набора для разбора писем: до и после уточнения одной из проверок.

История прогонов автотестов канала разбора писем: 95,7 % и 91,3 % пройденных проверок
История автотестов: 22 из 23 проверок на новой инструкции

«A/B-варианты» позволяют пустить часть клиентов на другую инструкцию или модель; деление детерминированное, один клиент всегда видит один вариант. Для разбора писем живой сплит невозможен: у письма нет клиента, по которому его можно разделить. Поэтому варианты здесь заведены выключенными, а в их заметках записан результат замера.

Страница A/B-вариантов канала разбора писем: основная инструкция и выключенные варианты с заметками о результатах замера
Варианты хранят результаты замера в заметках; названия моделей на снимке заменены описаниями

На карточке «AI для вас» главной страницы раздела выбирается, каким группам сотрудников виден помощник в панели: суперпользователь видит его всегда, остальные — по списку групп. Список тот же, что в «Параметрах модулей», его можно менять из любого из двух мест.

Карточка «AI для вас»: выбор лица помощника и список групп, которым он виден
Карточка «AI для вас»: лицо помощника и группы, которым он виден

Посмотреть на своих данных

Покажем платформу на живом стенде и разберём ваш случай. Или спросите ассистента прямо сейчас — он отвечает по документации и настройкам.

Поделиться ВКонтакте Telegram

Читайте также

9 мин
Платформа

Копии базы — под замком

Резервная копия — это вся компания в одном файле. Как копии, договоры и записи разговоров уехали в закрытое хранилище, почему ссылку на документ теперь выдаёт биллинг и как устроен раздел резервных копий.

Читать →
7 мин
Платформа

38 тысяч зомби: как восьмисекундный таймаут выключил отключение должников

Воркер, который отключает должников, полтора дня молча не работал. Как один забытый ssh на каждый таймаут превращается в аварию через пять суток — и почему в логе было «OK».

Читать →
12 мин
Платформа

Натравили ИИ-хакера на свой биллинг: автономный пентест Strix

Автономный ИИ-пентестер против нашего демо-стенда: как обошли блокировки Docker Hub и нейросетей из России, почему ChatGPT отказался работать, и что нашёл grok-4.6.

Читать →