Свой ИИ-консультант на сайте магазина: 34 : 12 в слепом сравнении
У американского бренда товаров для активного отдыха на витринах стоял платный чат-виджет. Подписку на него оплачивали за каждый магазин, а покупателям он часто отвечал встречными вопросами. У бренда есть и российский сайт, и там было жёсткое условие: данные посетителей остаются в России. Для этого сайта я собрал свой чат на российских языковых моделях. Он отвечает по описаниям товаров. Качество я проверил слепым сравнением с платным виджетом.
Подписка растёт с каждым магазином, а бот отвечает вопросом на вопрос
У бренда две витрины на Shopify и отдельный российский сайт. На витринах стоял платный чат-виджет. Подписку на него оплачивали за каждый магазин, поэтому цена росла с каждой новой витриной.
Менеджеры жаловались на ответы. На конкретный вопрос о выборе модели виджет часто задавал встречный уточняющий вопрос, и покупатель так и не получал ответа.
Для российского сайта было жёсткое условие: данные посетителей не уходят за границу. Этого требует закон о персональных данных (152-ФЗ). Поэтому зарубежные языковые модели не годились даже на время пилота.
Задача получилась такая. Нужен консультант, который отвечает по настоящему каталогу, знает реальные условия доставки и гарантии и хранит данные в России. Отвечать он должен не хуже платного виджета, и это нужно подтвердить цифрами.
Чат отвечает по своей базе фактов и работает на своём сервере
Чат я сделал отдельным проектом. В нём база фактов о товарах, поиск по ней, промежуточный сервис на FastAPI и окно чата, которое встраивается в сайт. Работает он по схеме RAG: сначала поиск находит в базе нужные факты, и только по ним модель пишет ответ. Поэтому каждое утверждение в ответе можно сверить с источником, а качество проверяется строгим тестом по эталону.
562 факта: каталог, частые вопросы, доставка, гарантия и формулировки из настоящих переписок менеджера
Векторный поиск по базе: под каждый вопрос подбираются подходящие факты
Сервис на FastAPI отдаёт ответ по мере готовности. Через него идут запросы к трём моделям, здесь же обновление ключей, повторные попытки и предохранители
Текст появляется по мере того, как модель его пишет. Следом приходят карточки товаров с картинками
Разговоры и контакты сохраняются в файл, копия вопросов и ответов уходит живому человеку в Telegram
Факты взяты из каталога и из переписок с покупателями
В базе 562 факта: характеристики товаров, частые вопросы, условия доставки и гарантии. Полезнее всего оказались 335 переписок менеджера с покупателями, из них 131 о наличии. Оттуда взяты и ответы, и живые формулировки вопросов: как люди на самом деле спрашивают о размере, весе, использовании зимой и сроках. Если собрать базу только из рекламных описаний, такие вопросы бот будет узнавать плохо.
Один сервис и три модели за ним
Ответ идёт потоком: человек видит текст по мере того, как модель его пишет. Сервис умеет работать с тремя поставщиками моделей. На сайте отвечает YandexGPT, а GigaChat и DeepSeek нужны для сравнения и недорогой отладки. Модель можно сменить, и сайт этого не заметит. В отдельной статье я разобрал, как выбрать нейросеть, которая будет отвечать клиентам. Тот же сервис берёт на себя всю служебную работу:
- обновление ключей доступа и повторные попытки с учётом заголовка
Retry-After - блокировка на сессию: один посетитель не запустит пять ответов одновременно
- предохранитель по бюджету: расход не выйдет за заданный предел, даже если чатом злоупотребляют
- телефоны и адреса почты вычищаются до записи в журнал, в файлы разговоров они не попадают
- защита от злоупотреблений через Cloudflare Turnstile
- голосовой ввод: вопрос можно надиктовать
Карточки товаров приходят следом за текстом
Первым приходит текст ответа, и его начинают читать сразу. Следом сервис присылает карточки упомянутых товаров: картинку, название и ссылку. Консультацию легко читать, а из чата можно сразу перейти к товару. Здесь же чат просит контакт: если разговор дошёл до конкретики, контакт сохраняется и уходит менеджеру.
Почему у карточек пропадали фотографии
Какое-то время в карточках под ответом бота на месте фотографии стояла буква-заглушка. Причин было две. Ежедневное обновление каталога перезаписывало файл записями без поля с картинкой. А таблица адресов картинок устарела, когда на сайте сменились ссылки. Теперь обновление берёт первую картинку галереи из того же ответа API магазина, и её адрес проверяется так же, как ссылки. При каждом обновлении в журнал пишется счётчик «с фото: N из M», а тест целостности индекса не даст ошибке вернуться.
Заявка доходит до менеджера вместе с разговором
Менеджер перезванивает по заявке, поэтому ему нужен и разговор, который к ней привёл. Раньше диалог хранился только в журнале, а журнал со временем перезаписывается. Для настоящей заявки с телефоном разговор уже не удавалось найти. Теперь заявка и разговор связаны номером сессии, и менеджер получает их вместе. В отчёте над диалогом стоит имя того, кто оставил заявку. Если разговор не поместился целиком, отчёт так и пишет: «показаны 2 реплики из 5, ещё 3 не поместились».
Качество проверяет строгий тест по эталону
Сначала ответы оценивала другая модель, и от этого пришлось отказаться. Она раз за разом пропускала провалы на вопросах о выборе товара, тех самых, на которые жаловались менеджеры: ответ звучал связно, и модель-судья его принимала. Теперь работает строгий тест по эталону. Для каждого вопроса заранее известно, какие факты обязаны попасть в ответ, и проверка идёт по ним. Кроме него есть 134 теста в pytest. Среди них проверка, что ответ опирается на базу фактов, и тесты защиты от злоупотреблений.
Ещё одна проверка ищет пробелы в базе знаний. Раньше она записывала в «уклончивые» и верные ответы. Например, стоимость доставки и ставку рассрочки чат называть не должен: их считает менеджер. По старому списку пришлось бы чинить то, что работает правильно. Теперь пробелом считаются ответы «нет данных» и «не указан», а ответ «посчитает менеджер» сверяется с темой вопроса. Раздел «уклончиво» из дневного отчёта убран, а «вес не указан» по-прежнему считается пробелом.
Чинить пришлось и сами тесты. Семь проверок падали с ошибкой типа и ничего не проверяли: заглушка модели принимала два аргумента, а в рабочей версии появился третий, учёт расхода токенов. Без проверок оставались капча, суточный бюджет и защита от повторов. Заодно выяснилось, что прогон тестов съедал 810 из 1000 суточных вызовов, отведённых посетителям сайта. Теперь локальные вызовы в этот лимит не входят.
Где ошибка стоит денег, ответ задаёт код
После запуска три недели ушли на точность ответов и порядок в данных. Магазин прислал разбор ошибок текстом и голосовыми сообщениями. Голосовые расшифровываются автоматически и попадают в ту же очередь правок. Две ошибки из разбора могли стоить покупателю денег. К надувной палатке бот первым предлагал слабый насос на 2 PSI, которым её не надуть. А ещё уверенно отвечал, что прозрачная торцевая стенка входит в комплект: он путал её с окнами из того же материала, которые стоят строкой выше в характеристиках.
Обе ошибки закрыты в коде. Слабый насос больше не появляется в ответах про палатку. В общем списке насосов он стоит с пометкой, для чего подходит. Для торцевой стенки заведена таблица трёх моделей, по которым есть данные. Для остальных ответ один: «данных нет, уточнит менеджер».
Главный вывод: одной правки базы знаний здесь не хватило. Модель по-прежнему делала вывод «входит в комплект» из соседней строки характеристик. Так же раньше было с правилами безопасности для печи. Поэтому там, где ошибка стоит покупателю денег, ответ задаётся кодом.
Бот знает только то, что попало в индекс
Шесть файлов базы написали специально под жалобы магазина: наличие и отгрузка, манера консультации, комплектация, совместимость, эксплуатация, доставка и оплата. Их не было в списке разрешённых источников, и сборщик молча их пропускал. Сколько бы раз индекс ни пересобирали, бот ничего из этих файлов не знал. Теперь они в списке источников.
Есть ограничение: индекс хранится отдельно от кода, и пересобрать его может только человек с облачным ключом. Правки базы начинают работать после пересборки.
Чат появлялся на сайте постепенно
Сайт собран в конструкторе, и любая правка сразу видна посетителям. Поэтому выкладка шла
по шагам. До правки снята резервная копия. Код дописан в конец HEAD,
прежний код не тронут, это проверено сравнением начала блока. Сначала чат появился
на главной странице, после проверки на живом сайте — на остальных, их около шестидесяти.
Откат описан в три шага и лежит рядом с инструкцией.
Основная модель российская, сервер свой
Сервис, который отдаёт ответ потоком. Работает как служба на своём сервере
562 факта с векторным поиском, карточки товаров приходят отдельно
Основная модель: данные остаются в России
Запасные модели за тем же входом: для сравнения и недорогой отладки
Голосовой ввод: вопрос можно надиктовать
Защита от злоупотреблений, покупателю не нужно разгадывать капчу
Один фрагмент кода, встраивается в сайт на конструкторе без доступа к исходникам
Каждый ответ виден целиком: поиск фактов, вызов модели, расход токенов
Службы и таймеры на своём сервере, оповещение, если служба упала
Опора на факты, защита от злоупотреблений, строгий тест по эталону
Слепое сравнение с платным виджетом
мой чат против платного виджета, ещё 3 ничьи
виджет ответил вопросом на 21 вопрос из 49, мой чат — ни разу
по полноте ответа — 3,98 и 2,90
Сравнение было устроено так. 49 вопросов составлены по 174 настоящим вопросам покупателей и разложены по сетке: 7 типов покупателей × 7 этапов покупки, от «первый раз на сайте» до «уже выбрал, уточняю гарантию». Каждый вопрос задан обоим ботам, ответы перемешаны, и судья не знает, где чей ответ.
Главная разница оказалась в готовности отвечать. На 21 вопрос из 49 платный виджет ответил встречным вопросом, ровно на это и жаловались менеджеры. Мой чат ответил по существу на все 49.
Свой чат можно быстро поправить. Владелец бизнеса написал замечание вечером, а к утру были готовы два исправления: бот перестал выдумывать, какие товары популярны, и стал опираться на реальные продажи.
Расходы на российском сайте предсказуемы. Подписки нет: оплачиваются только сервер и токены по мере использования. Предел расхода задан предохранителем прямо в сервисе.
Где ещё работает тот же подход
За этим кейсом стоит частая задача: консультировать по узкой теме так, чтобы каждый ответ опирался на факты. Та же схема подходит везде, где есть своя база знаний и неверный ответ стоит денег:
- → Магазины со сложным выбором — техника, оборудование, снаряжение: всё, что покупают после объяснений
- → B2B-сайты с долгими сделками — чат уточняет, что нужно клиенту, и передаёт менеджеру заявку вместе с историей разговора
- → Помощник для операторов поддержки — та же база и отдельное окно для операторов: бот подсказывает ответ, искать его в регламентах не нужно
- → Сферы, где особенно строго с персональными данными — медицина, финансы, госсектор: работа на российских моделях настраивается так же
- → Замена виджета по подписке — если плата растёт с каждой точкой, витриной или брендом, своё решение стоит посчитать
- Сервис с одним входом к нескольким моделям: смену модели сайт не замечает
- Схему базы фактов: каталог, регламенты и настоящие переписки
- Строгий тест по эталону. Модель-судья пропускала как раз те провалы, ради поиска которых её подключали
- Слепое сравнение двух ботов на вопросах, составленных из настоящих: сетка «тип покупателя × этап покупки»
- Осторожную выкладку чата: резервная копия → одна страница → проверка на живом сайте → остальные страницы, откат в три шага
- Копию разговоров в Telegram живому человеку на первые недели: кто-то должен видеть, что отвечает бот
Если ваш чат-виджет отвечает вопросом на вопрос, это можно исправить
Я начинаю с базы знаний и способа проверки: что бот обязан знать и как доказать, что он это знает. В этом проекте от прототипа до запуска на рабочем сайте прошло четыре недели. Дальше сопровождение: я слежу за надёжностью и точностью ответов.
Статья в блоге на эту тему: Чат-бот для записи клиентов: где он ломается
Похожие кейсы и готовые решения
Голосовой консультант: актуальные цены, поиск заказа и передача человеку
Сценарии разговора связаны с каталогом и CRM через отдельные инструменты. Статус заказа выдаётся после…
Голосовой робот для салона: круглосуточная запись в YClients
Отвечает на звонки в любое время, записывает клиента в YClients и присылает подтверждение по SMS. Знает 14…
Робот для стоматологии понимает, у кого острая боль, и записывает пациента в IDENT
Пациент звонит или пишет в Max или Telegram, робот задаёт восемь вопросов и решает, как скоро нужен врач…