Неделя 162. Успех, которого не было

Неделя 162. Успех, которого не было

Разбор этой статьи

AI-подкаст BotsellerПочему ложное «готово» дороже честного отказа
0:00 / 0:00

Эту тему разобрали в подкасте. Слушай параллельно с чтением.

Это сто шестьдесят вторая неделя с момента, как мы запустили Botseller в августе 2023 года. Период: с 31 августа 00:00 до 7 сентября 00:00 по Москве.

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

Сорок три дня. Столько наш бот отвечал клиентам «записал вас», не создавая записи.

Пятьдесят три попытки записаться, ноль записей, сорок четыре человека, четыре бизнеса. Ни одного сообщения об ошибке. Ни одного алерта. Последняя настоящая запись через этот путь была сделана 19 июля, и до 1 сентября никто из нас этого не знал.

Если прошлая неделя была про молчание, то эта про ложное «готово». Молчание хотя бы настораживает. Бодрое «всё получилось» не настораживает никого.

Сырой счётчик недели: 225 записей разработки в 10 рабочих контурах, из них 83 объединённые задачи и 142 прямые правки. По объёму 28,7 тысячи добавленных строк.

Меня зовут Дмитрий Дьяконов, я основатель и CEO Botseller AI. Мы делаем платформу с AI-продавцом, CRM, мессенджерами, автоматизациями, рассылками, календарём и звонками. Каждую неделю я разбираю, что реально сдвинулось в продукте и зачем это нужно бизнесу. Поехали по 162-й.

Пульс недели

Пульс недели: 225 записей разработки в 10 рабочих контурах, 28,7 тысячи добавленных строк кода. Три круговых индикатора с разбивкой: 85 задач «Механика: WhatsApp и записи» с подписью «подключение без лотереи, остановка фантомных записей», 45 задач «Деньги: сверки и биллинг» с подписью «точные прайсы, очередь списаний без заторов», 35 задач «AI-Рой: промпты и логика» с подписью «фильтрация ответов, контроль статусов».

НаправлениеЗаписей разработкиЧто это значит простыми словами
Официальный канал WhatsApp: подключение, шаблоны, приём сообщений70подключение номера перестало быть лотереей, причина отказа шаблона видна на экране
Деньги: цена рассылки, сверка с провайдером, очередь списаний45цена сообщения считается по тому же прайсу, что опубликован, платежи не теряются молча
Рой: членство помощников, отказы Telegram, служебный текст35помощник не выпадает из чата навсегда, служебная строка не уходит в рабочий чат
Автоматизации и мелочи CRM, которые видит клиент30владельца можно назначить ответственным, голосовые снова проигрываются
Запись на услуги и сторож падений инструментов бота15бот больше не подтверждает запись, которой нет, а падение инструмента видно за минуты
Заявки из рекламы: фундамент под приём лидов10готовится путь «заявка из рекламы сразу в CRM», клиенту пока не видно

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

Ложное подтверждение дороже честного отказа. Слева «Честный отказ»: переписка, где бот пишет «Ошибка записи» и предлагает «Давайте на завтра?», подпись «ситуация под контролем, возможность исправления». Справа «Ложное готово»: зелёное сообщение «Вы записаны!», под ним закрытая дверь салона с табличкой «Закрыто» и предупреждение «Клиент приходит. Записи нет. Ущерб репутации». Внизу строка состояния: скрытая ошибка, ущерб репутации высокий, уровень доверия ноль.

Сорок три дня, когда бот записывал в пустоту

Инцидент первый: записи в пустоту. В плашке цифры: 53 попытки, 44 человека, 4 бизнеса, 0 реальных записей. Ниже цепочка из четырёх шагов под заголовком «Пустота как триггер успеха»: инструмент падает из-за лишней точки с запятой, движок выдаёт вместо ошибки пустую строку, AI видит пустоту и считает, что ошибки нет, клиенту уходит сообщение «Записал вас!».

Начну с главного.

У AI-продавца есть инструменты: посмотреть свободное время, записать клиента, перевести его по воронке. Инструмент записи на услугу правился вручную 20 июля. В код попала лишняя точка с запятой. Одна. С этого дня инструмент перестал запускаться вообще.

Дальше начинается интересное. Движок, в котором эти инструменты живут, ловит ровно один класс ошибок. Всё остальное он проглатывает и отдаёт модели пустую строку. Не отказ, не исключение, а пустоту.

Модель получает пустоту в ответ на команду «запиши клиента» и делает единственный доступный ей вывод: раз ошибки нет, значит получилось. И пишет человеку: записал вас, ждём.

Наружу уходит успешный ответ. В журналах ровно ничего. Единственный след остался в системе трассировки, куда мы в тот момент не смотрели.

Автоответчик, который на любой запрос отвечает «столик забронирован». Журнал брони при этом пустой, и узнаёшь ты об этом от гостя, который пришёл к восьми.

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

Починили 1 сентября, выкатили 2-го. Первые настоящие записи после сорока трёх дней простоя прошли в ночь на среду, одна за другой.

Правок было три. Убрали синтаксическую ошибку. Переписали тексты отказов так, чтобы их понимала модель: раньше при неудаче возвращалась строка с опечаткой в слове, а при ненайденной услуге пустота. Теперь возвращается внятное «запись НЕ создана, не подтверждай её клиенту». Третье: перевод клиента по воронке вынесли отдельно. Раньше он стоял внутри общей обработки после создания записи, и любая ошибка на этом шаге превращала уже созданную запись в отказ. Клиенту говорили «не получилось», а слот в календаре был занят. Зеркальная ошибка к основной, и обе в одном месте.

Но главное не это. Главное, что мы не узнали об этом сами.

Поэтому вместе с починкой появился сторож. Раз в пятнадцать минут он спрашивает у системы трассировки, падали ли инструменты, пишет каждое падение в лог и шлёт сводку в рабочий чат. Падение инструмента считается критическим уровнем: это именно тот случай, когда клиенту уже пообещали несделанное.

Лечение слепоты: архитектура сторожа. Радар опрашивает движок инструментов каждые 15 минут. Критическое падение инструмента уходит в проверку подтверждения доставки, рутинные отказы внешних сервисов троттлятся до одного сообщения в час. Врезка сверху: алерт считается решённым только при подтверждённой доставке, а не просто при отправке.

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

Второе уточнение пришло уже из боевой работы. Сторож слал алерт на любую ошибку подряд, включая рутинные отказы внешних сервисов: за три дня августа таких набралось 72. Ещё немного, и чат с алертами залило бы шумом, а вместе с ним перестали бы читать и сообщения о настоящих падениях. Такие ошибки теперь уходят в чат не чаще раза в час, а в лог по-прежнему все.

Что я забираю отсюда. Пустой ответ нельзя считать успехом. Про то, что «сделал» и «ничего не сделал» обязаны выглядеть по-разному, я писал ещё в начале августа, и вот тот же класс поломки, только дороже. Если ваша система где-то получает «ничего» и идёт дальше как ни в чём не бывало, найдите это место и заставьте его различать «сделал» и «промолчал». У нас на это ушло сорок три дня и репутация перед четырьмя клиентами.

И вторая мысль, неприятная. Эти инструменты жили в стороне от основного кода: правки в них не проходили ревью и не сохраняли историю. Та правка была единственной за два месяца, и восстанавливать её обстоятельства оказалось не по чему. Теперь есть снимок всех инструментов и отдельная проверка, которая пытается запустить каждый из них. Раньше не было и этого.

Диагностика сбоев: слепые зоны на стыке систем. Таблица из четырёх строк сравнивает сломанный код и логический провал на стыке. Реакция клиента: видит ошибку против получает ложное обещание. След в логах: красный алерт против абсолютной тишины. Ущерб: низкий и быстро исправимый против высокого репутационного. Скорость обнаружения: минуты против 43 дней. Внизу вывод: система не должна трактовать неожиданный ответ как норму.

Рассылка шла двое суток и не отправила ни одного сообщения

Инцидент второй: рассылка-призрак, счётчик на стоящей машине. Слева автомобиль на подставках, колёса крутятся, одометр показывает почти десять миллионов километров, подпись «блокировка аккаунта». Справа график: красная линия попыток отправки уходит круто вверх, серая линия реально отправленных сообщений лежит на нуле. В плашке: 1400 циклов в сутки, двое суток статуса «идёт», ноль отправок.

Второй обещанный разбор. Клиент запустил рассылку в Telegram, и она двое суток показывала «идёт». Отправок ноль. Написал нам сам, потому что из кабинета всё выглядело как работа.

Разобрал в среду по логам. За двое суток: 886 записей «все аккаунты заняты», 15 записей «Telegram придержал проверку», ноль отправок.

Корень оказался в одной строчке логики. Счётчик отправленных сообщений увеличивался в момент, когда система выбирала аккаунт для отправки. До самой отправки. То есть каждая неудачная попытка съедала суточный лимит так же, как успешная. Проверки шли по кругу, лимит выгорал, отправок не было, а счётчик уверенно рос.

Дальше цепочка. Пауза после отказа Telegram ставится на аккаунт, а не на номер получателя, поэтому один придержанный аккаунт останавливал всю кампанию целиком. Между попытками система примерно шестьдесят раз вхолостую занимала и отпускала очередь, и так около тысячи четырёхсот циклов в сутки, включая ночь.

А сторож рассылок этого не видел по построению. Он проверяет две вещи: статус «идёт» и наличие прогресса в кэше. Обе были на месте.

Счётчик пробега на машине, которая стоит в гараже. Крутится, потому что считает обороты двигателя, а не пройденные километры.

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

Шесть подключений подряд, и каждое «успешное»

Инцидент третий: иллюзия подключения WhatsApp. Подзаголовок: клиент видит «успех» шесть раз, система видит «успех» шесть раз, реальность ноль подключений. Внутри зелёного контура «Интерфейс: успешное завершение» стопка из четырёх слоёв: режим совместной работы отклоняет номер, отсутствие подписки на события даёт тихий отказ, обрезка списка на десяти записях создаёт слепоту поиска, выдача старой ссылки заканчивается отказом окна.

Клиент шесть раз подряд прошёл подключение официального канала WhatsApp. Ни одно не завершилось. Мы узнали об этом, когда он написал сам.

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

Первый. Новым приложениям у провайдера по умолчанию включён режим совместной работы с мобильным WhatsApp Business. В этом режиме площадка ведёт человека по другому сценарию и требует номер, уже заведённый в мобильном приложении. Любой другой номер отлетает.

Второй. Подписка на события не создавалась ни разу. За всё время. Имена полей, которые мы отправляли, живой сервис просто отвергает, а мы этого не проверяли, потому что писали их по документации. Даже идеально пройденное подключение не привело бы к тому, что сообщения начали до нас доходить.

Третий, и он мог стоить денег. Список приложений у провайдера молча обрезается на десяти записях. Поиск уже созданного приложения его не находил, и следующая попытка могла завести второе платное приложение поверх первого. Мы платили бы дважды за один номер и узнали бы об этом из счёта.

Четвёртый, самый обидный. Ссылка на окно подключения выдавалась ранее выпущенная, а не свежая. Страница отвечала на неё отказом. Клиент видел нерабочее окно, а у нас в этот момент всё выглядело успехом.

Шесть раз подал заявление, шесть раз в окне сказали «принято». Принимает окно, а заводит запись соседний отдел, и он в отпуске с июля.

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

Но важнее другое, и это про управление, а не про код. Тогда же мы завели метрику застрявших подключений и алерт на неё. Он сработал бы на первой попытке клиента, а не на шестой.

С алертом пришлось повозиться дольше, чем с самим дефектом. Считаем застрявшими те подключения, которым от получаса до суток. Нижняя граница потому, что проверка номера на стороне площадки штатно идёт минуты, и шуметь раньше не о чем. Верхняя важнее: без неё в метрику попадали бы брошенные попытки, а такие у нас есть возрастом 170 дней, неделю и сутки. Алерт горел бы непрерывно с первого дня, а вечно горящий алерт перестают читать. Он был бы хуже отсутствующего.

И отдельная мина, которую нашли тестом: счётчик надо выставлять до раннего выхода из проверки. Иначе в тот день, когда застрявшие исчезнут, он навсегда сохранит последнее ненулевое значение, и алерт не погаснет уже никогда.

Отсюда вещь, которую я теперь считаю отдельно: не поломки, а незавершённые пути клиента. Поломки мы видим и так. А шесть попыток подключиться, каждая из которых закончилась успехом по всем нашим приборам, не видел никто.

Цена, которой не было в прайсе

Инцидент четвёртый: цена ошибки в тарификации. Подзаголовок: разрыв в 150 из 174 ячеек тарификации на дешёвых направлениях. Сверху две полосы, фактическая цена провайдера и списание с клиента, между ними скобкой выделен разрыв. Внизу схема ежедневной автоматической сверки: данные ходят по кругу между провайдером и платформой, ретроспектива три дня.

Теперь про деньги, и здесь мне сказать нечего в своё оправдание.

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

Разрыв на дешёвых направлениях был кратным: клиент платил за сообщение заметно больше, чем оно стоило нам. Из 174 ячеек справочника, а это 58 направлений на три категории сообщений, фактическая цена расходилась с расчётом по прайсу в 150.

То есть платформа списывала не то, что написано на нашем же сайте.

В четверг базовые тарифы убрали. Цена теперь выводится из стоимости направления по той же формуле, что лежит в основе опубликованного прайса. Проверили на восьми направлениях в семи странах: Россия в двух категориях сообщений, Индия, Турция, Нидерланды, Германия, ОАЭ, Бразилия. Совпало с прайсом до копейки.

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

Первый же живой прогон нашёл расхождение. Наш расчёт вышел на 14,5 процента выше факта провайдера. При этом счётчики сообщений сошлись идеально, разошлись только деньги.

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

Направление ошибки скажу прямо, потому что оно против клиента: мы посчитали ему дороже, чем стоило нам. Не катастрофа по сумме, но принцип неприятный. Справочник дополняется данными, а не кодом, это в работе.

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

Если у вас есть биллинг, вот что я бы проверил первым. Сверка нужна в обе стороны. Проверять «не забыли ли мы списать» интуитивно. Проверять «не взяли ли мы лишнего» никто не заводит, пока не придёт клиент с калькулятором. Лучше найти самому.

Платёж на 1300 рублей, который пропал молча

В среду клиент оплатил 1300 рублей, и деньги не попали на баланс.

Цепочка получилась поучительная. Платёж пришёл по ручной ссылке, где номер заказа задаётся произвольно, а у обычных платежей он собирается по формуле. Ядро честно достало из номера то, что считало идентификатором, клиента с таким номером не нашлось, запись не создалась.

Дальше сработала бытовая ошибка. Обработчик отменил транзакцию, которой владел не он, а вызывающий код. Следующий же запрос упал уже не из-за платежа, а из-за порванной транзакции, и наружу ушла общая ошибка без всякого упоминания платежа. Настоящая причина потерялась по дороге.

Починили в тот же день: вставка идёт под точкой сохранения, откатывается только она, конфликт разбирается отдельно, и на выходе понятный отказ вместо невнятного сбоя.

Одна деталь мне нравится отдельно. Для случая «такого клиента нет» выбрали не тот код ответа, который напрашивается. Напрашивался «конфликт», но ядро считает конфликт нормальным делом и пишет о нём тихо. Потерянный платёж стал бы ещё тише. Взяли код ошибки данных, который ядро пишет громко.

Вот это, пожалуй, главное про деньги. Громкость сообщения об ошибке надо выбирать не по формальной точности, а по цене молчания.

Очередь списаний, которая заросла с головы

Инцидент пятый: тромб в очереди списаний. Очередь нарисована прозрачной трубой вместимостью 200 слотов: голова забита красными шарами «мёртвые циклы, безнадёжные должники», а зелёные шары «живые списания, клиенты с деньгами» остаются снаружи и внутрь не попадают. Новый фильтр поставлен до входа в очередь. Подпись: очередь простояла четверо суток, 147 безнадёжных записей заблокировали все 200 слотов.

31 августа очередь списаний за диалоги встала полностью и простояла так четверо суток. Всё это время живые списания в неё просто не попадали.

Механика простая и очень общая. У неудачной попытки списания нет памяти: диалог возвращается в очередь и выбирается снова через пять минут. Выборка идёт от самых старых записей, а безнадёжные как раз самые старые. Сто сорок семь таких записей заняли все двести мест в очереди, и живые списания просто перестали в неё попадать.

Побочно всплыло второе, и оно мне не нравится больше первого: почти у трети клиентов вообще не было строки баланса. Все пути в системе, от пополнения до подписки, эту строку создают сами, и только списание за диалог вместо этого писало ошибку и уходило. Один и тот же вопрос «а есть ли кошелёк» все места в системе решают одинаково, и только одно по-своему. Именно оно стоит в самом узком месте.

Отдельно словили неприятное следствие: четыре платящих клиента получили отказ при заведении нового диалога, потому что старый висел в очереди и держал место.

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

Очередь в поликлинике, где первые сто человек ждут врача, который сегодня не принимает, и не уходят. Талон у каждого на руках, приём идёт, а живая очередь стоит.

Переносится куда угодно, где есть очередь и повтор. Если неудачная попытка возвращается в начало, а берут по старшинству, очередь рано или поздно зарастает с головы. Безнадёжное надо уметь откладывать, а не перекладывать.

Рой чуть не заговорил служебным языком

Инцидент шестой: когда AI говорит на языке машин. Фрагмент кода с проверкой «текст не пустой» и служебным объектом со значением «null», который эту проверку проходит. Ниже такой объект уходит в чат как обычное сообщение и перечёркнут красным крестом. Новое правило в рамке: объект незнакомой формы считается пустотой, лучше не отправить ничего, чем отправить системную структуру.

Рой, наш диспетчер Telegram-аккаунтов, на этой неделе дал самый неприятный инцидент из возможных: чуть не написал служебную строку в рабочий чат клиента.

3 сентября генератор текста вернул служебный объект с пустым значением внутри. Код прочитал значение, увидел пустоту, и сработал запасной путь: взять ответ целиком. В поле текста сообщения оказался сам служебный объект. Проверка «а не пустой ли текст» строку из двадцати одного символа честно пропустила.

Через минуту это ушло бы в чат от имени аккаунта клиента. Остановили вручную.

Разбор текста теперь жёсткий: если пришёл объект, берём только значение из него, каким бы оно ни было, а объект незнакомой формы считаем пустотой. Лучше не отправить ничего, чем отправить служебную структуру.

Три соседних исправления той же природы.

Telegram отвечает «подождите 2523 секунды», а система считала это отказом и повторяла через минуту. Гарантированно в тот же отказ, с тратой попытки и шагом предохранителя, который потом глушит аккаунт во всех чатах разом. Теперь срок берётся из ответа, действие откладывается ровно на него, попытка не тратится: аккаунт исправен, ему просто рано.

Второе. При финальном отказе отправки вызывался выход помощника из чата. Любая ошибка, в тексте которой попадалось слово о блокировке, выводила аккаунт из живого рабочего чата навсегда, и делала это молча. Теперь меняется только запись в базе, из чата никто не выходит.

Третье. Диспетчер выдал четыре решения с типом «ничего не делать», и они попали в очередь на отправку. Исполнитель на каждом отвечал «не знаю такого типа», повторял трижды и каждым отказом двигал предохранитель. Ещё один такой цикл, и аккаунт замолчал бы во всех чатах. На эти четыре пустышки ушло девятнадцать тысяч токенов.

Общее у всех четырёх: система получает нечто неожиданное и трактует его самым разрушительным из возможных способов. Это тот же вопрос, что и в истории с записями, только с другого конца: там пустоту приняли за успех, здесь служебную структуру приняли за текст для клиента. Если код на неожиданный ответ отправляет что-то человеку или выходит из чата, его надо переписать до выката.

Мелочи, которые видно клиенту

Видимая полировка: контроль хаоса. Четыре карточки «было и стало». Голосовые сообщения: повреждённый файл стал работающим плеером с дорожкой. Ответственные: пустой профиль с номером вместо имени стал карточкой владельца бизнеса с именем. Отказ WhatsApp: сбой без деталей стал точной причиной отказа с кодом. Подписи бота: общий ответ «Ответил AI» стал именованным «Робот и имя бота».

Короткий список того, что заметно без объяснений.

Голосовые сообщения снова проигрываются в чате. Причина была не в логике: в рабочем образе не оказалось описания формата голосовых, и файл приезжал в CRM как безымянный набор байтов, а плеер отказывался его открывать. Починка чинит и уже сохранённые вложения, а не только новые.

Владельца бизнеса теперь можно назначить ответственным за лид или задачу. Раньше списки строились по карточкам сотрудников, а владелец там не числится: он подставлялся костылём и подписывался почтой или номером вроде «#105». Заодно в профиле появились имя и фамилия, потому что подписывать владельца было просто нечем.

Сообщения автоматизаций подписываются «Робот · имя бота», а не «AI». Мелочь, но в переписке сразу видно, кто именно ответил: живой человек, AI-продавец или простой сценарий.

Причина отказа шаблона WhatsApp доехала до экрана. Раньше был красный бейдж «Ошибка» без единого слова о том, что случилось. Теперь видно, кто отказал, дословную причину и что делать дальше. Плюс мы проверяем правила площадки до отправки: эмодзи в заголовке, переносы строк, переменные в подвале. Цена отказа высокая, потому что имя отклонённого шаблона остаётся занятым навсегда.

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

И одна невидимая правка, которая мне нравится: ссылки в служебных письмах больше не заворачиваются через внешний трекер. Он был единой точкой отказа, и когда он лежал, не работали ссылки в приглашениях сотрудников и в письмах о сбросе пароля. Мы обменяли статистику переходов на то, чтобы человек мог войти в систему.

Главный итог недели

Новая парадигма: метрики застрявших. Крупная врезка: перестаём считать только ошибки, начинаем считать незавершённые пути клиента. Внизу шкала времени: старт процесса в ноль минут, отметка ожидания на тридцати минутах, дальше красная зона алерта от получаса до суток, в которой статус так и не меняется.

Неделя вышла про один и тот же дефект в пяти обличьях.

Система сообщала об успехе там, где успеха не было. Записала, отправила, подключила, оплатила, посчитала. Ни одного падения, ни одного алерта, ни одной красной лампочки.

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

Отдельно про сорок три дня. Меня в этой истории добивает не точка с запятой, а то, что путь записи на услугу никто не проходил руками полтора месяца. Мы смотрели на графики, на количество диалогов, на выручку. Всё было в порядке. А клиент, которому бот сказал «записал вас», приходил в салон и его там не ждали.

Неделю назад я писал, что первый рабочий день на новой площадке надо провести самому, от двери до чека. Написал и не понял, что правило не про новую площадку, а про любой день. Включая меня, который про это правило и писал.

Теперь прохожу сам, раз в неделю. Не смотрю на приборы, а записываюсь на услугу и проверяю, что запись появилась. Дешевле любого мониторинга и ловит ровно тот класс поломок, который мониторинг не видит по определению.

Ручной протокол: главный итог недели. Подпись: графики, выручка и логи показывали идеальную норму 43 дня. Зелёная аналитическая панель отгибается, как страница календаря, а под ней рука с телефоном, на котором тот же путь проходится вручную. Врезка: раз в неделю основатель лично проходит путь клиента и записывается руками, без приборов мониторинга, потому что это единственный способ найти слепую зону.

Следующая неделя получилась самой объёмной за последние месяцы, и она про другое: заявки из рекламы Facebook начали падать в CRM сами, Instagram дорос до полноценного канала с комментариями и личными ответами, а у каждого обхода Роя появилась цена в деньгах. И там же я расскажу, как мы на ровном месте уронили бота клиента на три часа.

Приходите в Telegram-канал

Если этот формат отчётов вам полезен, подпишитесь на наш Telegram-канал @botseller_ai. Там я каждую неделю выкладываю бортовые журналы и короткие заметки про продуктовые решения, эксперименты и инциденты. Без рекламы, без воды, только то, что мы сами считаем важным.

Если хотите попробовать Botseller в своём бизнесе, используйте кнопку регистрации в шапке сайта. Я не вставляю отдельную ссылку в текст: платформа сама выберет правильный путь входа в зависимости от контура и настроек.

FAQ

Мой бот записывал клиентов на услуги. Как понять, пострадал ли я?

Затронуты были записи на индивидуальные услуги через AI-продавца в период с 20 июля по 1 сентября. Всего мы насчитали 53 попытки у четырёх бизнесов, и разбираемся с каждым из них отдельно: записи, которые должны были состояться, восстанавливаем вручную. Сейчас путь проверен, а падения инструментов бота отслеживаются автоматически.

Почему платформа вообще может подтвердить запись, которой нет?

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

У меня рассылка в Telegram висит со статусом «идёт», а отправок нет. Что это значит?

Скорее всего аккаунт-отправитель упёрся в ограничение Telegram и стоит на паузе, а кампания ждёт вместе с ним. Причину мы на этой неделе нашли и разобрали по логам, но исправление ещё не выкатили, и отдельного статуса «остановлена» в кабинете пока нет. Это честный открытый хвост: если рассылка стоит дольше нескольких часов, напишите в поддержку, мы посмотрим состояние отправителя.

Изменится ли для меня цена сообщений в WhatsApp?

Цена приведена к тому, что опубликовано в нашем прайсе: она считается от стоимости направления, без фиксированного пола. На дорогих странах ничего не меняется, на дешёвых направлениях цена стала ниже прежней. Дополнительно мы теперь ежедневно сверяем свой расчёт с отчётом провайдера и разбираем каждое расхождение.

Я подключал официальный канал WhatsApp несколько раз, и ничего не происходило. Что делать?

Пройти подключение ещё раз. Причина была в том, что повторная попытка не делала всю работу заново и могла выдать устаревшую ссылку, а неудачное подключение выглядело успешным. Теперь каждая попытка настраивает всё с нуля, а если подключение застрянет дольше получаса, мы увидим это сами по алерту.

Мой платёж не дошёл до баланса. Что делать?

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