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

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

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

Из-за этой заботы бот целый месяц незаметно работал хуже, чем мог.

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

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

Ошибка перехватывалась — и запрос уходил к запасной модели. Запасная работала. Бот отвечал.

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

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

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

Как починили

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

Вторая ошибка, найденная по дороге

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

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

Вывод

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

Как устроен ИИ в Kontext сейчас — на странице «ИИ и MCP-коннектор».