Проверка настроек: что означает каждый отказ
Кнопка «Проверить настройки» в разделе «Настройки бота» → вкладка «Для разработчиков» проходит по вашему серверу сверху вниз и на каждом шаге говорит, что именно случилось. Здесь - полный разбор исходов с командами, которые нужно выполнить на вашем сервере.
Протокол
«указан http» или «без схемы» - мы ходим только по https. Выпустите бесплатный сертификат и укажите адрес со схемой:
certbot --nginx -d kb.вашдомен.ru
Домен разрешается
Имя не превращается в адрес. Три причины по частоте: нет A-записи, опечатка в адресе, домен не делегирован на ваши серверы имён. Проверьте с любой машины:
dig +short kb.вашдомен.ru # ожидаем адрес вашего сервера nslookup kb.вашдомен.ru
Пусто - записи нет или она ещё не разошлась. Новая A-запись расходится до нескольких часов.
Порт доступен с нашего адреса
Это не то же самое, что «у меня открывается»: у вас может стоять фильтр по адресам, и с вашего рабочего места всё работает, а с нашего - нет. Причины: не запущен nginx, закрыт порт в брандмауэре, наш адрес не в белом списке, сервер за NAT без проброса.
systemctl status nginx ss -ltnp | grep :443 # кто слушает 443 ufw status # что разрешено ufw allow from 157.228.138.231 to any port 443 proto tcp
Запросы к вам приходят с адреса 157.228.138.231.
Сертификат
Отказ бывает четырёх видов, и лечатся они по-разному:
- самоподписанный - выпустите бесплатный через certbot;
- истёк -
certbot renew, и проверьте таймер:systemctl status certbot.timer; - выдан на другое имя - в сертификате не то доменное имя, которое вы вписали в кабинете. Частый случай: сертификат на
вашдомен.ru, а адресkb.вашдомен.ru; - нет цепочки - сервер отдаёт только свой сертификат, без промежуточного. В браузере такое иногда работает, у нас нет.
echo | openssl s_client -connect kb.вашдомен.ru:443 -servername kb.вашдомен.ru 2>/dev/null \ | openssl x509 -noout -subject -dates -issuer
Мы предупреждаем заранее: если до конца срока меньше двух недель, проверка попросит обновить сертификат, хотя он ещё годен.
Поиск отвечает: 401 или 403
Ваш сервер отверг нашу подпись. Причины по частоте:
- секрет в кабинете и в
kb.serviceразошлись; - в переменной окружения остался пробел или перевод строки - глазами не видно;
- службу не перезапустили после правки, и она работает со старым секретом.
systemctl show kb -p Environment # что реально видит служба systemctl restart kb
Сверяйте посимвольно. Если правили секрет и там, и там - меняйте сначала в кабинете, потом на сервере: в обратном порядке несколько минут ответы будут отказами.
Поиск отвечает: 404
Адреса нет на вашем сервере. Обычно в кабинете указан корень вместо полного пути - должно быть .../knowledge/search, а не .../.
curl -i -X POST https://kb.вашдомен.ru/knowledge/search
Ожидаем 401 - это значит, что адрес есть и подпись проверяется. Настоящий 404 - адреса нет.
Поиск отвечает: 405
Адрес есть, но метод не разрешён. Эндпоинт должен принимать POST. Частая причина - в nginx стоит правило, пропускающее только GET.
Поиск отвечает: 500, 502, 503
Упало внутри вашего сервиса. Смотрите журнал - там будет настоящая причина:
journalctl -u kb -n 50 --no-pager
Что встречается:
relation "kb_chunks" does not exist- не создана таблица;type "vector" does not exist- не создано расширение:CREATE EXTENSION vector;;ModuleNotFoundError- не установлен пакет в виртуальном окружении;connection refusedк базе - не поднят PostgreSQL;- 502 от nginx - служба не отвечает вовсе:
systemctl status kb.
Поиск отвечает: таймаут
Сервер не ответил за отведённое время. Первый запрос после простоя долгий - модель грузится в память, это 15-30 секунд. Дальше должно быть 50-150 мс.
- держите службу тёплой: запрос к
/knowledge/healthраз в минуту из своего мониторинга; - или поднимите таймаут до 5000 мс в кабинете;
- если медленно всегда - проверьте, что создан индекс: без него поиск идёт перебором и на большой базе занимает секунды.
sudo -u postgres psql -d kb -c "\di kb_*" sudo -u postgres psql -d kb -c "EXPLAIN ANALYZE SELECT id FROM kb_chunks ORDER BY embedding <=> (SELECT embedding FROM kb_chunks LIMIT 1) LIMIT 6"
В плане должно стоять Index Scan using kb_vec_idx, а не Seq Scan.
Поиск отвечает: пустой ответ
Связь есть, подпись принята, но фрагментов ноль. Проверка это не считает отказом - но бот в таком состоянии будет отвечать «не знаю» на всё.
sudo -u postgres psql -d kb -c "SELECT count(*) AS кусков, count(embedding) AS с_векторами FROM kb_chunks;"
- оба нуля - материалы не загружены, запустите индексатор;
- кусков много, векторов ноль - индексатор отработал без модели, векторы
NULL. При векторном режиме поиск не найдёт ничего; - всё на месте, а пусто - спросили словами не из материалов. Проверьте вопросом, который точно есть в тексте.
Поиск отвечает: ответ не в том формате
Ждём объект с полем chunks - списком из id, content и score. Массив верхним уровнем ([ ... ] вместо {"chunks": [ ... ]}) или другое имя поля не подойдут. Точный вид - в статье Материалы на своём сервере.
Запас по времени
Ответ пришёл, но занял больше семидесяти процентов таймаута. Это не отказ сегодня, а отказ завтра: под нагрузкой ответ станет медленнее, и бот начнёт отвечать «не знаю» покупателям. Ускорьте поиск или поднимите таймаут.
Закрыт без подписи
Мы отправляем запрос без заголовка X-CyberAI-Signature и смотрим, что будет. Ждём 401 или 403.
Если сервер ответил 200 - эндпоинт открыт, и ваши материалы может выкачать кто угодно. При том что режим вы выбрали ровно ради их сохранности. Добавьте проверку подписи - готовый пример в инструкции для администратора, функция checked.
Сравнивать подписи надо постоянным по времени сравнением (hmac.compare_digest), а не обычным ==.
Приём правок ответов
Проверка отправляет настоящую правку с пометкой «Проверка связи CyberAI». Если её не приняли - не поднят второй адрес, /knowledge/correction. Без него правки, которые вы делаете в «Диалогах», сохранять будет негде.
После успешной проверки тестовая правка остаётся в вашей базе - мы об этом говорим в отчёте. Удалите её, если мешает:
sudo -u postgres psql -d kb -c "DELETE FROM kb_chunks WHERE content LIKE '%Проверка связи CyberAI%';"
Если ничего не помогло
Соберите три вещи и напишите нам: отчёт проверки целиком, вывод journalctl -u kb -n 50 и ответ curl -s https://kb.вашдомен.ru/knowledge/health. По ним видно почти всё.