Всё началось с простого вопроса: почему малый бизнес теряет клиентов ночью?
Клиент заходит на сайт в 23:00, пишет в чат — и уходит. Потому что менеджер спит. Утром менеджер видит сообщение, перезванивает — а клиент уже купил у конкурента.
Стандартное решение — чат-бот. Но обычный чат-бот либо ограничен заранее заданными сценариями, либо требует интеграции с крупными облачными LLM. (отвечает по скриптам), либо слишком дорогой (GPT-4 за десятки тысяч в месяц), либо хранит данные за рубежом, что не всегда удобно для российского бизнеса.
Я решил сделать иначе.
Проблема переключения между ИИ и оператором
Главная сложность оказалась не в интеграции с моделью, а в сохранении непрерывности диалога. После передачи клиента оператору необходимо было сохранить единый контекст разговора, не меняя интерфейс для пользователя. Для этого relay-сервер хранит состояние сессии и динамически маршрутизирует сообщения либо в vLLM, либо в MAX, в зависимости от текущего режима обработки.
Что в итоге получилось
ИИ-консультант на базе Qwen3 30B отвечает клиентам на сайте. Когда клиент хочет поговорить с живым человеком — оператор получает уведомление в MAX с кратким резюме всего диалога. Отвечает прямо из мессенджера. Клиент видит один непрерывный разговор и не знает что канал переключился.
Вся установка — один тег перед </body>:
<script src="https://llmcod.ru/widget/ВАШ_ID.js"></script>
Как это работает технически
Архитектура состоит из трёх частей:
1. Виджет на сайте — обычный JS чат, подключается через WebSocket к relay-серверу. Никаких iframe, никаких внешних зависимостей.
2. Relay-сервер (FastAPI + WebSocket) — центральный компонент. Держит сессию пользователя, проксирует сообщения в vLLM или в MAX в зависимости от режима. Хранит историю диалога и маппинг session_id ↔ MAX chat_id.
Ещё одна проблема возникла при переключении между режимами. Если оператор подключается слишком рано, ИИ не успевает собрать достаточный контекст. Если слишком поздно — клиент может уйти. Поэтому порог эскалации сделан настраиваемым и определяется количеством сообщений в диалоге.
3. MAX бот — получает уведомления об эскалации. Оператор видит резюме диалога и отвечает прямо в мессенджере.
Схема передачи сообщений:
Клиент → WebSocket → Relay → vLLM (AI режим) ↓ (при эскалации) MAX webhook ← MAX бот ← Оператор
При эскалации relay вызывает vLLM для суммаризации истории диалога и отправляет оператору готовое резюме. Оператор не читает весь чат — видит только суть.
Почему MAX, а не Telegram
Несколько причин:
MAX — российский мессенджер, данные хранятся в РФ
API MAX позволяет получать webhook и отвечать от имени бота
MAX предоставляет API для ботов и webhook-механизм, достаточный для реализации сценария передачи диалога оператору.
Ключевой момент — резюме диалога
Это главное отличие от обычного "перевода на оператора". Когда клиент нажимает кнопку — оператор получает не просто уведомление, а готовый контекст:
? Клиент просит оператора Сайт: ООО Ромашка ? Резюме: Клиент интересуется доставкой в регионы. Уточнял сроки и стоимость. Хочет заказать на следующей неделе. ? Последнее сообщение: А скидки на первый заказ есть? ✏️ Ваш ответ → придёт клиенту как сообщение оператора.
Оператор сразу в контексте. Не нужно читать историю, не нужно переспрашивать клиента "а что вы хотели?".
Мультитенантность
Система изначально спроектирована для нескольких клиентов. Каждый клиент получает:
Свой MAX бот с отдельным токеном
Свой webhook endpoint:
/relay/{client_id}/webhookСвой виджет:
/widget/{client_id}.jsСвой системный промпт с описанием бизнеса
Добавить нового клиента — один API вызов:
curl -X POST "https://llmcod.ru/admin/clients" \ -H "X-Admin-Token: ..." \ -d '{ "name": "ООО Ромашка", "bot_token": "...", "operator_user_id": 12345678, "system_prompt": "Ты ассистент магазина цветов..." }'
В ответ приходит готовый <script> тег для вставки на сайт.
Как формируется контекст модели
При подключении клиент описывает свой бизнес в свободной форме — прайс, режим работы, частые вопросы, тон общения. Это становится системным промптом модели.
Дополнительно модель знает текущее время (московское) — может сообщить клиенту рабочее ли сейчас время, когда будет доступен оператор.
Контекст диалога — последние 6 сообщений. Этого достаточно для большинства сценариев поддержки.
Инфраструктура
Модель: Qwen3 30B A3B Instruct (Q4_K_M GGUF)
Инференс: vLLM с GGUF квантизацией
GPU: NVIDIA Tesla V100 32 ГБ
CPU: 2 х Intel Xeon Gold 6244
RAM: 128 ГБ
сервер Dell T440
В зависимости от длины контекста скорость генерации составляет до ~98 токенов/с.
Контекст: 32K токенов
Инференс модели и хранение диалогов выполняются на сервере, расположенном в России.

Модель запущена через OpenAI-совместимый API — тот же chat/completions endpoint. Это важно для интеграции с любым кодом который уже работает с OpenAI SDK.
Что можно настроить
Через личный кабинет клиент управляет:
Цветом виджета
Системным промптом (до 10 000 символов)
Порогом эскалации (после скольких сообщений предлагать оператора)
Подпиской и продлением
Демонстрационный стенд
Для тестирования системы был развёрнут демонстрационный стенд, на котором можно проверить работу виджета, генерацию ответов и переключение между ИИ и оператором.
Если интересно как устроен relay-сервер или вопросы по интеграции MAX API — отвечу в комментариях.
Комментарии (7)

pewpew
09.06.2026 10:20Почему MAX, а не Telegram
MAX — российский мессенджер, данные хранятся в РФ
А если я например живу и работаю в Казахстане или Республике Беларусь. Почему мне важно, чтобы данные хранились именно в РФ? Хочу понять вашу логику.

llmcod Автор
09.06.2026 10:20Здравствуйте. Сервис пока расчинан на Россию и телеграм не работает в РФ по крайней мере у меня совсем. Из за этого выбран МАХ.

kalapanga
09.06.2026 10:20Клиент заходит на сайт в 23:00, пишет в чат — и уходит. Потому что менеджер спит.
А вот если менеджеру придёт сообщение в МАХ, то он, забыв про сон, вскочит и, не одевая штанов, бросится отвечать клиенту!

diomas
09.06.2026 10:20API MAX позволяет получать webhook и отвечать от имени бота
Вот этот момент непонятен: макс как-то сам хостит вебхуки ботов или что это имеется в виду? В чем отличие от вебхуков для ботов в телеграме?

llmcod Автор
09.06.2026 10:20MAX работает так же как Telegram — вы регистрируете свой URL, и MAX присылает туда POST-запросы при каждом новом сообщении боту. Хостить нужно самостоятельно.
# Регистрация webhook в MAX curl -X POST "https://botapi.max.ru/subscriptions" \ -H "Authorization: ВАШ_ТОКЕН" \ -d '{"url": "https://ваш-сервер.ru/webhook"}'Отличие от Telegram практически одно — авторизация без
Bearer(токен передаётся напрямую в заголовке), иuser_id/chat_idпри отправке сообщений идут как query-параметры, а не в теле запроса. В остальном — та же схема webhook → обработчик → ответ через API.
netricks
Уууу... ИИ и MAX в одной статье... А вы смелый.