Кейс

Самодиагностика по данным: как B2B-лидогенерация теряла 475 закупок

4 мин чтения
889 слов

Для отдела продаж маркетингового агентства я с февраля 2026 года веду B2B-платформу лидогенерации. Она ищет компании, которые прямо сейчас выбирают CDP или CRM: собирает сигналы из закупок, вакансий, Telegram-каналов и отраслевых новостей, считает общий балл, а лучшие компании разбирает ИИ — в чём потребность, насколько горячий лид, с чего начать первый контакт.

Сейчас в базе 16 968 компаний, 4 693 из них разобраны ИИ: 593 «горячих» и 1 799 «тёплых». Платформа в работе у отдела продаж.

Этот кейс о трёх вещах, которые сделали её надёжнее: самодиагностика по данным вместо логов, калибровка балла под оценку ИИ и уход с Supabase без переписывания кода.

Коротко

Задача и ограничения

Сигналы приходят из нескольких источников с разной надёжностью: 43 684 вакансии с HH.ru, 600 закупок, 833 сигнала из Telegram, отраслевые RSS. Каждый источник может сломаться по-своему: поменять API, начать отдавать пустые страницы, снять модель с поддержки.

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

Решение 1. Проверять данные, а не процессы

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

Так нашлись две поломки, которые логи не показывали.

475 потерянных закупок. Поиск закупок отдаёт результаты постранично. Коллектор начинал страницы с 1, а нумерация в API начиналась с 0, так что первая страница выдачи пропускалась молча: запрос успешный, ответ корректный, ошибок нет. Поломку нашла самодиагностика, и после исправления в систему вернулись 475 закупок.

Разбор, который стоял 13 дней. Поставщик снял с поддержки AI-модель, на которой работал разбор компаний. Новые компании переставали разбираться, но система в целом жила. Теперь модель задаётся одной настройкой, и её доступность проверяется каждую ночь.

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

Решение 2. Свести две формулы балла в одну

Общий балл компании — это правила: сила сигнала, число источников, свежесть. ИИ разбирает только верх списка, поэтому балл решает, до каких компаний ИИ вообще дойдёт.

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

Замер на 3 835 компаниях, уже разобранных ИИ:

Показатель До После
Spearman между баллом и оценкой ИИ 0,33 0,48
Точность при пороге балла 60 69% 78%

Калибровка не делает балл умнее модели. Она экономит разбор: ИИ тратит вызовы на компании, которые ближе к покупке, а не на случайный хвост базы.

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

Решение 3. Уйти с Supabase, не трогая код

Сначала платформа жила на Supabase: база, авторизация, хранилище файлов. В июле 2026 года её нужно было перенести на собственный PostgreSQL 17 внутри контура агентства.

Переписывать все обращения к базе не хотелось: их было 235, и каждое — место для новой ошибки. Поэтому я сделал совместимую прослойку над node-postgres, которая принимает те же вызовы, что и клиент Supabase. Код приложения почти не заметил переезда.

Авторизацию заменил своей (bcrypt и JWT в httpOnly-cookie), файлы переехали на том. Данные переносились со сверкой по таблицам — расхождений ноль.

Что ещё помогает базе не зарастать мусором

Что не сработало и чего не утверждаю

Что стоит забрать

  1. Мониторьте данные, а не только процессы. Самые дорогие поломки — те, после которых всё «работает».
  2. Держите одну формулу. Две копии одного правила обязательно разойдутся.
  3. Переезд через прослойку. Совместимый слой дешевле и безопаснее, чем переписать сотни обращений.
  4. Перемеряйте красивые цифры. В отчёт идёт то, что воспроизводится.

Платформу я спроектировал и довожу через Claude Code.

Стек: Next.js 16, React 19, TypeScript, PostgreSQL 17, node-postgres, Python + Telethon, Node.js + node-cron, Natasha, pymorphy3; AI-разбор — Claude через OpenRouter; Docker Compose.