Кейс 06 · производство мебели · производственно-розничная компания · кухни и мебель на заказ
Директор спрашивает обычными словами — CRM отвечает цифрами
Контекст
Производственно-розничная компания — кухни и корпусная мебель на заказ, два салона, город-миллионник. 50 сотрудников в CRM, ~10 продающих менеджеров. Заказчик и основной пользователь — генеральный директор. Это третья система, построенная для этого клиента.
Руководство видело бизнес «в среднем по больнице»: в CRM накоплено 2470 лидов и 1815 сделок, но любой управленческий вопрос — кто из менеджеров тормозит, какой канал приносит деньги, что зависло — требовал ручной выгрузки и сборки отчёта. Часть срезов не собиралась вообще: разбивка «какой менеджер из какого источника получил лидов» существовала только по отдельности.
Второй пласт потерь — скорость реакции. В мебели на заказ клиент оставляет заявку в нескольких компаниях сразу, и сделку ведёт тот, кто ответил первым. Никто не отслеживал в реальном времени, что новый лид висит без ответа час или полдня — такие лиды тихо утекали.
Ограничения
- Метки кастомных полей Bitrix24 не отдаются через REST. Портал сильно кастомизирован — 30+ воронок и смарт-процессов, сотни служебных полей, API возвращает коды вместо названий. Ключевые поля пришлось находить по данным: выгружать значения и сверять с отчётом заказчика — поле дизайнера подтвердилось совпадением сумм до рубля
- Права выдавались поэтапно. Стартовый доступ включал только CRM — имена сотрудников и постановка задач были недоступны. Система должна была честно деградировать, а не падать
- Ноль внешних зависимостей. Требование эксплуатации: никакого pip install, только стандартная библиотека. Генератор XLSX написан вручную поверх zipfile и XML
- Локали Excel. Первая выгрузка в CSV «рассыпалась» у заказчика — разделитель и десятичная запятая зависят от локали. Переписано на настоящий XLSX
- Качество данных клиента как ограничение продукта. «Дата предполагаемой сделки» заполнена у 2% лидов, стадия «Замер проведён» отмечается примерно у 15% сделок. Систему нужно было спроектировать так, чтобы она честно показывала неполноту, а не выдавала красивые, но ложные цифры
Находки аудита
Это состояние данных клиента до внедрения — то, что система вскрыла, а не результат её работы.
- 119 сделок, застрявших на продажных стадиях, висели в работе на момент запуска — у одного менеджера 27 сделок на 13 млн ₽. Системно их никто не подсвечивал
- 93% суммы ключевого партнёрского канала — обезличены. Дизайнеры-партнёры приводят крупные заказы, но у сделок канала конкретный дизайнер в карточке не указан (9,5 из 10,2 млн ₽ у одного менеджера). Вопрос «кому платить вознаграждение и с кем усиливать работу» решался вслепую
- Методика измерения цикла сделки занижала его на месяц. Первая версия расчёта показывала медиану «договор → успех» 86 дней; после исправления методики — 116. Директор обещала бы клиентам сроки на месяц короче реальных
Решение
Что это даёт
Руководитель общается с отделом продаж через Telegram обычным языком: «что горит?», «сколько заключим в этом месяце?», «какие дизайнеры принесли сделки этого менеджера?», «поставь задачу перезвонить по сделке». Система понимает вопрос, считает по CRM и отвечает готовым отчётом плюс коротким выводом «что делать первым». Никаких выгрузок и сводных таблиц.
Без запроса система следит за потоком круглосуточно: новый лид без первого ответа дольше норматива — пинг с именем менеджера, источником и временем ожидания; повторно — эскалация. Каждое утро в 10:00 приходит сводка: новые лиды за вчера по источникам и менеджерам, кто сейчас не принят, зависшие сделки, выручка и оплаты, строка «что горит первым».
Аналитика: воронка и конверсия по этапам, источники по деньгам, KPI менеджеров, рейтинг дизайнеров-партнёров, реанимация базы, прогноз заключений, длительность этапов сделки с медианами и выгрузкой в Excel, дашборд с графиками одним файлом. Всего — 8 инструментов, 13 отчётов, 15 команд меню.
Как устроено
Та же двухслойность, что во всех моих системах: цифры считает код, LLM понимает вопрос. Вся арифметика — детерминированный Python поверх Bitrix24 REST: суммы, конверсии и медианы считает код, а не языковая модель. Модель разбирает произвольную фразу («за 3 недели», «за июнь», «с 1 по 15 июля»), сама вычисляет даты и вызывает нужный инструмент через function calling. Готовый отчёт отправляется пользователю напрямую из кода, минуя пересказ моделью — иначе терялись детали, и это ошибка, пойманная в бою.
В CRM ничего не пишется без явного «да» человека. Система показывает карточку задачи и ждёт подтверждения. Для этого разведены два режима — просмотр и предложение с фиксацией: смешение этих режимов было реальной уязвимостью, найденной на ревью. Поведение настраивается заказчиком прямо из чата — норматив ответа, время дайджеста, пороги «зависания» — без участия разработчика и без перезапуска.
Тяжёлый расчёт — разбор истории стадий — занимает ~38 секунд, поэтому снимок CRM кэшируется на 5 минут, а тяжёлые расчёты — на 30: без этого чат «залипал» бы.
Результат
Система в проде, используется генеральным директором ежедневно. Разработка от первого коммита до передачи — 23 дня, 24 коммита, 4606 строк в 18 модулях.
| Показатель | Было | Стало |
|---|---|---|
| Объём под контролем | видно «в среднем по больнице» | 2470 лидов · 1815 сделок |
| Зависшие сделки | 256 с шумом производства | 119 после калибровки фильтра |
| Медиана цикла «договор → успех» | 86 дней (ошибочная методика) | 116 дней — честная |
| Управленческие срезы | часть не собиралась вообще | 8 инструментов · 13 отчётов · 15 команд |
| Тяжёлый расчёт истории стадий | — | ~38 сек + кэш 30 минут |
| Срок разработки | — | 23 дня · 4606 строк |
Что бы сделал иначе
- Сначала методика измерения, потом код. Первая версия расчёта длительности этапов занижала цикл: считала только сделки, у которых начало и конец попали в окно выборки, и игнорировала незавершённые. «Договор → успех» показывал 86 дней вместо 116. Для метрик длительности сразу закладывать усечение выборки и цензурирование
- Инструменты для LLM — read-only по умолчанию. Свободная фраза «какие задачи поставить?» перезаписывала список, к которому относилось пользовательское «да» — в худшем сценарии в CRM ушли бы не те задачи и не тем людям. Запись — отдельным путём, с фиксацией того, что подтверждается
- Проверять оба пути, а не один. Отчёт работал правильно по команде, но при вопросе словами модель пересказывала данные и теряла разбивку. Проверен был только командный путь. Если у функции два входа — тестировать оба
- Не считать «нет данных» за «невозможно». Бот отказал в разрезе «менеджер × источник», объяснив это ограничением интеграции. На деле оба поля приходили в одной выгрузке — не хватало 15 строк кода. Различать «данных физически нет» и «срез не написан»
Стек
Роль
Реализация — в паре с AI-ассистентом (Claude Code); архитектура, ключевые решения, ревью и приёмка — мои.
Ваша CRM тоже отвечает только выгрузками?
Напишите — разберём, что можно автоматизировать в вашем случае.