Новая языковая модель может появиться утром, к вечеру оказаться в топе нескольких лидербордов, а через пару недель уступить место следующей версии. Для команды, которая использует LLM в продукте, это создаёт вопрос: когда обновляться и как делать это без лишнего риска для пользователей и разработки.
В «Первой Форме» ИИ-агент помогает в контуре разработки: работает с кодом, инструментами и ревью. Состав моделей в этом контуре мы регулярно пересматриваем. За последние недели мы обновили Muse Spark с версии 1.2 до 1.3, добавили Gemini 3.8 Flash и подготовили для него быстрый откат на предыдущую модель. Расскажем, как устроен этот процесс.
Почему публичных оценок новой модели недостаточно
Публичные бенчмарки позволяют заметить новую модель, понять её позиционирование, цену, размер контекстного окна и заявленные возможности. На этом их роль в нашем процессе заканчивается.
Лидерборд отвечает на усреднённый вопрос: как модель справилась с определённым набором общих задач и методикой конкретного рейтинга. В продукте же вопрос звучит так: «Сможет ли эта модель выполнять наши задачи не хуже текущей, работать с нашими инструментами и не создавать дополнительных проблем в эксплуатации?»
В нашем понимании агент-разработчик должен уметь разбирать репозиторий, пользоваться инструментами, вносить аккуратные изменения, замечать регрессии и сохранять устойчивость в длинной сессии. Модель может выглядеть сильной в открытом бенчмарке и при этом хуже справляться с одним из критичных для нас сценариев.
Есть и более общий риск: публичные тесты со временем становятся известны лабораториям-разработчикам и они переобучают свои модели, чтобы они лучше справлялись. Кроме того, поведение модели зависит от промпта, провайдера, режима вызова и обвязки вокруг неё. Поэтому публичный результат мы воспринимаем только как сигнал для отбора кандидатов. А дальше начинается процесс отбора.
Сначала — пул моделей и возможность отката
Теперь расскажем, как устроен ИИ-ассистент в «Первой Форме». Он не привязан к одной модели. В контуре есть пул провайдеров, из которого модель выбирается с учётом заданных весов. Для отдельных случаев можно вручную запросить конкретную модель.
Такой подход решает несколько задач одновременно:
-
позволяет постепенно вводить новые модели;
-
не делает продукт зависимым от одного провайдера;
-
даёт возможность сравнивать модели на одинаковых сценариях;
-
упрощает откат, если после включения обнаружится проблема;
-
помогает учитывать качество, скорость, стоимость и доступность в связке.
Когда новая модель проходит проверку, мы не удаляем старую версию из конфигурации. Она переводится в состояние dormant: не участвует в обычном выборе, но остаётся готовой к возврату. В результате откат — это изменение состава пула в конфигурации, которое проходит значительно проще.
Эта деталь кажется небольшой, пока не возникает инцидент. В момент, когда нужно быстро вернуть предыдущее состояние, наличие уже подготовленной модели заметно снижает цену ошибки.
Как мы проверяли Muse Spark 1.3
2 сентября мы сравнили Muse Spark 1.3 с использовавшейся версией 1.2. Обе модели запускались через один endpoint и получали одинаковые промпты. Это важно: если одновременно меняются модель, провайдер, системные инструкции и режим вызова, понять причину различий уже сложно.
Проверка состояла из пяти групп внутренних сценариев:
-
ревью изменений относительно эталона;
-
регрессии по заранее внесённым дефектам;
-
работа с инструментами и репозиторием;
-
точность редактирования;
-
базовые smoke-проверки.
Результат прогона выглядел так:
|
Группа проверок |
Результат Muse Spark 1.3 |
|
Ревью с эталоном |
12 из 12 |
|
Приёмочные регрессии |
8 из 8 |
|
Работа с инструментами |
4 из 4 |
|
Точность правок |
4 из 4 |
|
Smoke-проверки |
Пройдены |
В этих сценариях версия 1.3 не показала ухудшений относительно 1.2. На части задач средней сложности, связанных с подготовкой текстового ответа, она работала примерно в 1,5 раза быстрее. На основании этого Muse Spark 1.3 вошла в рабочий пул вместо 1.2.
Важно уточнить границы результата — мы не заявляем, что Muse Spark 1.3 «лучше всех», и не публикуем состав сценариев и способ их оценки. Формулировка «не хуже и быстрее» относится к нашему конкретному прогону и нашему набору задач, ваше мнение может отличаться.
Деплой не заканчивается сменой конфигурации
Включить новую модель в пул недостаточно. После деплоя нужно проверить, что агент действительно использует именно её, а система не перешла на fallback и не оставила в логах скрытых ошибок.
После обновления Muse мы сделали отдельный живой probe:
-
отправили запрос через нужный маршрут;
-
подтвердили по техническим данным, что ответ пришёл от Muse Spark 1.3;
-
проверили отсутствие признаков fallback;
-
убедились, что в журналах исключений нет новых ошибок.
Такой probe занимает немного времени и защищает от распространённой ситуации: конфигурация выглядит верной, а фактический запрос по другой причине обслуживает предыдущая модель или резервный провайдер.
Для нас это обязательная часть смены модели. Ответ от агента сам по себе ещё не означает, что ротация прошла корректно.
Кейс Gemini 3.8 Flash: откат готовят заранее
В тот же период мы добавили в каталог Gemini 3.8 Flash. У модели контекстное окно в 1 млн токенов, лимит ответа до 32 768 токенов. Её включили в пул с заданным весом. Gemini 3.7 при этом оставили в состоянии dormant, чтобы при необходимости быстро вернуть через смену состава пула.
После деплоя мы выполнили probe с явным запросом Gemini 3.8 Flash и проверили три вещи:
-
агент получил ответ именно от новой модели;
-
fallback не сработал;
-
технические журналы остались чистыми.
Тут важен порядок действий. Откат должен быть готов до того, как новая версия начнёт обслуживать рабочие запросы. Если держать прежнюю модель в подготовленном состоянии, замена перестаёт быть необратимым событием.
Что на самом деле ломается при ротации
Смена модели часто выглядит как простая правка конфигурации. На практике качество ротации определяет также инфраструктура вокруг модели: правила выбора провайдера, хранение состояния сессии, классификация ошибок, блокировки и наблюдаемость.
За неделю разбора в нашем контуре проявилось несколько характерных проблем.
Ручной список провайдеров отстал от реальной конфигурации
В одном из механизмов использовался вручную поддерживаемый список облачных провайдеров. Когда состав пула изменился, этот список не включал часть актуальных поставщиков: 5 из 10 провайдеров фронтир-пула не попадали в нужную категорию.
Из-за этого нездоровый провайдер мог возвращаться в выбор вместо того, чтобы временно исключаться. В разборе 19 из 28 трасс с отказами были связаны с повторным возвращением такого провайдера в пул.
Мы изменили подход: характеристики провайдера теперь определяются по живой конфигурации. Общее правило здесь такое: Логика выбора и защиты от сбоев должна опираться на тот же источник данных, который задаёт состав рабочего пула.
Иначе конфигурация и защитные механизмы со временем неизбежно начинают жить раздельно.
Неизвестная ошибка не блокировала проблемный маршрут
В другом случае один из типов ошибок попадал в класс unknown. Система не считала его достаточным основанием временно исключить провайдера и выбирала его снова на следующем шаге той же задачи.
В замере это привело к 29 отказам на 15 вызовах. Обработка сценария занимала около 6,5 минуты вместо примерно одной минуты.
После разбора этот тип ошибки стали относить к классу, при котором провайдер блокируется на 15 минут. Это не означает, что ошибка исчезает сама по себе. Зато система перестаёт повторять один и тот же неуспешный маршрут и получает время на восстановление или переключение.
Сессия запоминала не того провайдера
Ещё одна проблема связана с состоянием сессии. Система сохраняла провайдера из конфигурации на старте хода, а не того, кто фактически сформировал ответ. После неуспешного запроса следующий ход мог снова вернуться к уже отказавшему маршруту.
В одном из разборов это вызвало три последовательных обрыва в рамках одной задачи. Исправили концептуально так: сессия должна закрепляться за провайдером, который действительно ответил. Но обнаружить такую проблему можно только тогда, когда в логах видно и ожидаемую конфигурацию, и фактический маршрут запроса.
Модель может молча не участвовать в выборе
Бывает и более тихий сбой. Новый провайдер добавлен в конфигурацию, но для него отсутствует необходимый параметр на нужном контуре. В итоге он не выбирается, при этом явной ошибки может не быть.
Это причина, по которой мы не считаем документацию и конфигурационный diff достаточным подтверждением готовности. Каждый новый провайдер проходит живую пробу после включения.
Процесс, который можно повторить
За несколько ротаций у нас сложился практический процесс из семи шагов.
|
Шаг |
Что делаем |
Зачем |
|
1 |
Собираем внутренние сценарии в группы проверок |
Сравнивать модели исключительно по задачам продукта |
|
2 |
Прогоняем кандидата против текущей модели на одном endpoint и одинаковых промптах |
Снижаем влияние сторонних различий |
|
3 |
Принимаем модель, если она не хуже в критичных группах и даёт выигрыш по скорости или цене |
Выявляем модели, подходящие для нашего контура |
|
4 |
Включаем новую модель через пул, а старую оставляем dormant |
Упрощаем процесс, если нужно откатить модель |
|
5 |
После деплоя запускаем живой probe |
Подтверждаем фактическую модель, отсутствие fallback и чистые логи |
|
6 |
Разбираем отказы по классам и проверяем правила блокировки |
Исключаем ситуации, когда проблемный провайдер выбирается повторно |
|
7 |
Оставляем финальное решение владельцу пула |
Состав моделей меняется управляемо, с учётом продукта и инфраструктуры |
Есть ещё одна важная деталь. Не каждого нового кандидата нужно немедленно включать в рабочий набор. Например, одна из недавних моделей-кандидатов ждёт решения владельца пула. Это нормальное состояние процесса: модель может быть технически доступной и интересной по характеристикам, но решение о её роли в продукте всё равно принимает человек.
Что в итоге
LLM обновляются быстрее, чем команда может безопасно менять инфраструктуру вокруг них. Поэтому полезно относиться к новым моделям как к кандидатам в управляемом процессе и не бежать обновляться по первым новостям.
Мы используем для этого небольшой набор собственных сценариев, сравнение с текущей моделью, пул с подготовленным откатом и техническую проверку после деплоя. Отдельно следим за тем, чтобы роутинг, fallback, состояние сессий и классификация ошибок не отставали от реальной конфигурации.
Такой подход не обещает, что каждая новая модель будет лучше, но даёт гарантию, что смена модели остаётся проверяемым и обратимым изменением.
Оговорка: результаты Muse Spark 1.3 приведены по внутреннему приёмочному прогону от 2 сентября 2026 года. Стоимость моделей указана на момент проведения работ.
ссылка на оригинал статьи https://habr.com/ru/articles/1082776/