За квартал клиент Velmi терял около 150 горячих лидов — не из-за плохого продукта, а из-за скорости ответа. Четыре менеджера тратили 5–6 часов в день на ручной разбор всех входящих заявок, из которых 70% оказывались нецелевыми. Пока они разбирались с мусором, целевые клиенты ждали ответа по 2–3 часа и уходили к конкурентам. Harvard Business Review фиксирует: компании, отвечающие в первый час, квалифицируют лид в семь раз чаще, чем те, кто тянет дольше.

Готовые решения — Reisift и SalesAI — не подошли: они либо не интегрировались с Bitrix24 без серьёзной доработки, либо не давали нужной гибкости. Скриптовый бот на сценариях тоже отпал быстро: люди пишут «во сколько это выйдет» и «хотим запуститься в июле, но по бюджету непонятно» — жёсткие ветки диалога такое не обрабатывают. Команда выбрала собственную обвязку на FastAPI с GPT-5 в качестве языковой модели.

ФункцияКто выполняет
Диалог с пользователемLLM
Извлечение интента из свободного текстаLLM
Определение бюджета и сроковLLM
Резюме для менеджераLLM
Дедупликация событий по event_idКод
Нормализация телефонов и emailКод
Выбор CRM-статуса по whitelist'уКод
Дедлайн и приоритет задачиКод
Слияние дублей лидовКод

Архитектура построена на чётком разделении ответственности. LLM занимается только «человеческой» частью: понять сообщение, извлечь интент, задать следующий вопрос, написать резюме для менеджера. Всё, где нужна точность и предсказуемость — дедупликация событий, нормализация телефонов и email, выбор CRM-статуса, расстановка дедлайнов задач — остаётся в детерминированном коде. Любая попытка отдать эти функции модели заканчивалась непредсказуемым поведением.

Доля квалифицированных лидов выросла на 35%, менеджеры экономят около 50 часов в месяц.

Ключевая техническая проблема — временно́й лимит Bitrix24: платформа ждёт ответ на webhook ровно 3 секунды, иначе повторяет запрос. Один вызов GPT-5 занимает до 2 секунд, плюс обращения к Bitrix API — в синхронной архитектуре это не укладывается. Решение: FastAPI endpoint мгновенно подтверждает событие кодом 200 OK и кладёт его в Redis-очередь. Дальнейшая обработка идёт асинхронно: бэкенд собирает карточку лида, историю переписки и данные об источнике заявки, передаёт контекст модели, получает структурированный ответ и обновляет CRM. Для защиты от дублей используется debounce на 2–3 секунды и Redis lock на идентификатор лида.

Структура ответа модели жёстко типизирована через Pydantic. Поля intent, budget_range и urgency принимают только значения из заранее заданного списка — Literal-типы исключают около 90% мусорных интерпретаций. Модель физически не может вернуть budget_range со значением «примерно тысяч двести». Поле confidence отражает уверенность модели от 0 до 1; если данных не хватает, валидатор на уровне кода не даёт выставить высокое значение.

На доводку промптов ушло около двух недель итераций. Три характерных сбоя: модель игнорировала ценовой сигнал при упоминании конкурента со скидкой — добавили явное условие в промпт; фразу «срочно, вчера!» классифицировала как «в течение месяца» — добавили few-shot примеры срочности; при пустых данных выставляла confidence 0.9 — закрыли валидатором. Промпт запрещает модели называть себя ботом или ИИ, задавать больше одного вопроса за сообщение и переспрашивать уже полученные данные.

В продакшне обнаружилась ещё одна проблема — гонки вебхуков: пользователь отправил три сообщения за 1,5 секунды, и система получила три параллельных события по одному лиду. Именно для таких случаев в архитектуре предусмотрены debounce и Redis lock — они собирают пачку сообщений перед передачей контексту модели. Итоговый стек проекта: FastAPI, Redis, GPT-5, Bitrix24 webhooks.