Молчаливый переход на запасную модель стоил нам месяца

Бот отвечал — просто хуже, чем должен. Снаружи это не выглядело как поломка, и в этом была вся проблема.

У ИИ-слоя Kontext два провайдера моделей: основной и запасной. Логика простая и, казалось бы, заботливая: если основная модель недоступна — кончились деньги, упала сеть, ошибка у провайдера, — запрос уходит к запасной. Бот не молчит, человек получает ответ.

Эта забота стоила нам месяца тихой деградации.

Что произошло

Бот работает через SDK, который сам тянет за собой библиотеку протокола MCP. Версия SDK была закреплена, а версия этой библиотеки — нет. Однажды при сборке приехала новая мажорная версия библиотеки, несовместимая со старым SDK. Встроенный сервер инструментов бота начал падать на старте.

Исключение ловилось — и уводило запрос на запасную модель. Запасная работала. Бот отвечал.

Снаружи это выглядело не как «бот сломался», а как «Claude почему-то стал отвечать хуже». Хуже понимает вопрос, хуже пользуется инструментами, чаще промахивается. Ни одной красной строки, ни одного письма от сторожа. Такие жалобы списывают на модель, а не ищут в коде.

Почему это опаснее падения

Упавший сервис чинят через полчаса: его видно. Сервис, который работает на 70%, живёт так месяцами. Запасной путь превратил явную поломку в незаметную, и чем лучше он работал, тем дольше мы ничего не замечали.

Как починили

  • Закрепили SDK на версии, которая сама несёт совместимую библиотеку. Транзитивная зависимость, которую никто не закреплял, — самая частая причина «вчера работало».
  • Переход на запасную модель стал виден. В журнале пишется, какая модель ответила и почему основная не смогла. Молча деградировать хуже, чем честно ответить худшей моделью.
  • Общие инструменты и промпт для обоих путей. У запасного пути свой цикл «запрос — инструменты — ответ», но тела инструментов и системный промпт общие. Расходиться должно качество модели, а не набор умений, иначе бот ведёт себя по-разному в зависимости от того, чей ключ сегодня работает.

Вторая грабля, найденная по дороге

Когда SDK заработал, выяснилось, что у движка бота по умолчанию есть доступ к файлам, командной строке и вебу. А в рабочий каталог контейнера был примонтирован каталог проекта. На вопрос «что у нас по задачам» бот прочитал документ с планами разработки вместо задач пространства и уверенно его пересказал.

Закрыли двумя замками: рабочий каталог заменён пустым — движку он нужен, но читать там нечего, — а встроенные инструменты движка убраны явно. Одного списка «что разрешено без спроса» мало: он отвечает за разрешения, а не за то, что вообще существует.

Вывод

Запасной путь — удобство, но у него обязан быть свидетель. Если система умеет незаметно работать хуже, однажды она так и будет работать, и никто не узнает. Теперь в журнале всегда видно, кто отвечал, — и туда смотрят не только когда всё легло.

Как устроен ИИ-слой сейчас — на странице ИИ и MCP-коннектора.