Маршрутизация моделей: правила или выбор на лету
Маршрутизация моделей не сводится к одной настройке: правила дают контроль, выбор на лету снижает расходы. Разберём цену, задержку, качество и риски.

Почему схема ломается под нагрузкой
На тестовых 20 запросах почти любой маршрут выглядит разумно. Ответы приходят быстро, бюджет держится, запасной путь кажется надежной страховкой. Но когда трафик вырастает в 10 раз, схема начинает вести себя совсем иначе.
Главная причина проста: запросы не одинаковые. Один и тот же шаблон сегодня дает короткий вопрос на 200 токенов, а через минуту - длинный диалог с вложенными документами. Легкий запрос проходит через дешевую модель за секунды. Тяжелый уходит в более дорогую, потому что прежняя не держит контекст, формат ответа или сложность задачи. Если правило этого не учитывает, расходы начинают расти рывками, и команда видит проблему уже после ответа, когда менять что-то поздно.
Под нагрузкой всплывает и другая поломка: запасной маршрут начинает гонять запрос по кругу. Первая модель не уложилась в таймаут, роутер отправил запрос второй. Вторая вернула ошибку по лимиту. После этого логика снова вернула запрос в первый маршрут, но уже с другим флагом. На графике это выглядит как несколько неудачных попыток по одному запросу. На счете все хуже: лишние токены, занятые воркеры и очередь, которая растет без пользы.
Чаще всего схема ломается в четырех местах:
- сложные запросы слишком часто уходят в дорогие модели;
- таймауты запускают повторные попытки без жесткого лимита;
- стоимость считают после ответа, а не до маршрутизации;
- ограничения по данным проверяют слишком поздно.
С данными проблем обычно больше всего. Пока команда тестирует на обезличенных примерах, почти любой провайдер кажется подходящим. В проде появляются ФИО, номера договоров, обращения клиентов и внутренние документы. После этого часть провайдеров отпадает из-за требований к логам, data residency и правилам 152-ФЗ. Если такие ограничения не встроены в маршрут заранее, система в обычный рабочий день внезапно теряет половину доступных путей.
Для российских команд это частая история. Сначала маршрут строят по цене и качеству, а потом выясняется, что часть трафика нельзя отправлять за пределы РФ. В такой ситуации нужен не просто fallback, а порядок выбора, в котором допустимые провайдеры отсеиваются еще до первого запроса. Иначе нагрузка быстро превращает аккуратную схему в дорогую и нестабильную.
Чем отличаются два подхода
Статические правила работают просто: команда заранее решает, какой тип запроса куда отправлять. Короткие FAQ идут в дешевую модель, длинные договоры - в более сильную, а запросы с персональными данными - только в контур с хранением в РФ. Такую логику легко проверить до запуска и показать юристам, безопасникам и владельцу продукта.
Выбор на лету устроен иначе. Маршрутизатор смотрит на сам запрос, длину контекста, текущую цену токена, лимиты провайдера, задержку и доступность модели прямо в момент обращения. Один и тот же вопрос утром и в час пик может уйти в разные модели, если так дешевле или быстрее.
Разница между подходами обычно проявляется в нескольких вещах.
Статические правила проще проверить до релиза. Их можно прогнать на исторических запросах и заранее увидеть странные ветки. Под нагрузкой они ведут себя предсказуемее, а бюджет обычно держат ровнее, потому что пороги заданы заранее.
Выбор на лету лучше переживает всплески, когда одна модель замедлилась или временно недоступна. Он чаще выигрывает там, где запросы сильно отличаются по сложности. Но за это приходится платить более сложной телеметрией и более трудной отладкой.
На практике все выглядит очень приземленно. Банк может отправлять стандартный вопрос про лимит карты в одну модель, а спорную претензию с длинной перепиской - в другую. Сама по себе возможность быстро переключать модели не решает задачу. Политику маршрутизации все равно нужно спроектировать отдельно.
У статических правил есть сильный плюс: они предсказуемы. Если у вас жесткие требования по 152-ФЗ и понятный набор сценариев, такой подход обычно дает меньше сюрпризов. Вы заранее знаете, какие классы запросов не должны выходить за заданный контур.
Выбор на лету полезен там, где поток запросов неровный, модели часто меняются, а цена и задержка плавают в течение дня. Но он требует больше данных: историю ошибок, телеметрию по задержке, лимиты, стоимость и понятные сигналы качества.
Еще один момент, который часто путают: маршрутизация, повтор и fallback - это разные слои. Сначала вы выбираете, куда отправить запрос. Потом отдельно решаете, что делать при таймауте, отказе провайдера или плохом ответе. Если смешать все это в одну цепочку, почти неизбежны циклы, лишние переходы и рост задержки.
Когда правила работают лучше
Статическая маршрутизация моделей иногда выглядит слишком простой. Но во многих задачах именно это и нужно. Если у команды есть один-два повторяющихся сценария, например классификация обращений и короткие ответы по базе знаний, фиксированное правило часто работает лучше, чем "умный" выбор на лету. Его легче проверить, поддерживать и объяснить коллегам.
Самый частый случай - жесткие ограничения по данным. Если запросы содержат персональные данные, банковскую тайну или внутренние документы, список допустимых моделей быстро сужается. Тогда динамический выбор нередко теряет смысл: выбирать почти не из чего. Для команд с требованиями 152-ФЗ это обычная картина. Сначала вы отсекаете модели по размещению логов, аудиту и маскированию PII, а уже потом смотрите на качество.
Статические правила удобны и там, где нужен ровный счет за месяц. Финансистам и владельцам продукта проще жить с понятной схемой: этот тип запроса всегда идет в одну модель, другой - в другую. Без сюрпризов в конце месяца и без скачков из-за того, что роутер вдруг начал чаще выбирать дорогой вариант.
Есть и более практичная причина. Ошибка маршрута иногда дороже лишних 200-300 мс. Если система отправила чувствительный запрос не туда, выбрала слабую модель для важного шага или запустила цепочку fallback, команда потом тратит часы на разбор. В таких процессах предсказуемость обычно полезнее, чем попытка выжать еще несколько процентов качества.
Статические правила чаще выигрывают в четырех случаях:
- сценарии повторяются каждый день и почти не меняются;
- допустимых моделей мало из-за требований к данным;
- бюджет нужно планировать помесячно, без заметных колебаний;
- цена ошибки выше, чем небольшая потеря в скорости.
На практике это часто выглядит скучно: простая таблица маршрутов, один запасной путь и ручной пересмотр раз в месяц. Но скучная схема нередко оказывается самой надежной.
Когда выбор на лету окупается
Выбор модели на лету хорошо работает там, где поток запросов неровный. Утром в системе могут идти короткие вопросы на 2-3 сообщения, а вечером приходят длинные диалоги с вложенным контекстом, проверками и уточнениями. Если в такой смеси всем запросам дать одну и ту же модель, вы почти всегда либо переплатите, либо потеряете качество.
Обычный выигрыш появляется, когда дешевая модель закрывает большую часть трафика без заметной просадки по ответам. Это частый случай для типовых задач: классификация, короткие ответы, перефразирование, простое извлечение данных. Сильную модель имеет смысл подключать только там, где запрос уже вышел за рамки простого сценария: длинная история диалога, неоднозначная формулировка, высокий риск ошибки или строгий формат ответа.
Такой подход особенно полезен, когда меняется не только объем нагрузки, но и сложность запросов. В одном потоке могут идти совсем простые обращения и тяжелые случаи на много токенов. Статические правила в такой ситуации быстро грубеют: они либо слишком часто отправляют запросы в дорогую модель, либо режут качество на сложных эпизодах.
Где эффект заметнее
Выбор на лету обычно окупается, если:
- провайдеры периодически дают сбои, и нужно удержать SLA без ручного переключения;
- большая доля запросов решается дешевой моделью с приемлемым качеством;
- сложные запросы можно распознать по длине контекста, типу задачи или ранним сигналам качества;
- короткие и длинные диалоги идут в одном канале и сильно отличаются по цене обработки.
Еще один плюс виден на отказах. Если часть провайдеров недоступна или задержка растет, маршрутизация может увести только чувствительный трафик на запасной маршрут, а не перестраивать всю систему целиком. Это обычно дешевле и спокойнее для эксплуатации.
На практике схема часто выглядит просто. Первый проход делает недорогая модель. Если ответ не проходит проверку по формату, уверенности или времени, запрос уходит в более сильную модель.
Если у вас стабильный поток одинаковых задач, выбор на лету может не окупиться. Но когда трафик живой, провайдеры ведут себя по-разному, а цена ошибки ощутима, такой режим быстро начинает экономить и деньги, и время команды.
Какие данные собрать до решения
Выбирать схему маршрутизации по ощущениям - плохая идея. Сначала соберите цифры по каждому сценарию: короткий вопрос в чат, длинный документ, извлечение данных, суммаризация, генерация письма. Для каждого сценария нужны не только средние значения, но и p95 по задержке. Средняя цифра успокаивает, а p95 показывает, что увидят люди в плохие минуты.
Стоимость тоже часто считают слишком грубо. Смотрите отдельно цену входных и выходных токенов. У двух моделей итоговая стоимость может отличаться в разы даже при похожем качестве. Если ваш поток состоит из длинных промптов и коротких ответов, экономика будет одной. Если запрос короткий, а ответ растягивается на тысячу токенов - совсем другой.
Нужен и собственный набор проверочных запросов, на которых качество действительно проседает. Не общий бенчмарк из интернета, а ваши реальные случаи: сложная классификация, спорные формулировки, длинный контекст, запросы с таблицами, редкие термины. Обычно хватает 50-100 примеров, если они подобраны хорошо. По ним быстро видно, где статические правила держатся, а где выбор на лету реально спасает ответ.
Отдельно разделите поток с персональными данными и общий поток. Это не формальность. Если часть запросов содержит ФИО, телефоны, номера договоров или внутренние идентификаторы, для них могут действовать другие ограничения по провайдеру, логированию и хранению. Для команд с требованиями 152-ФЗ это часто меняет саму схему маршрута, а не только выбор модели.
Полезно собрать и таблицу причин fallback. Записывайте их явно, а не прячьте в поле "ошибка":
- таймаут;
- лимит провайдера или квота;
- срабатывание фильтра;
- пустой или оборванный ответ;
- ошибка формата.
Когда причины смешаны, команда лечит не ту проблему. Иногда кажется, что модели не хватает качества, а на деле p95 просто уходит в таймаут, и запрос перескакивает на запасной маршрут.
Как собрать маршрут без fallback-циклов
Если маршрут растет без правил, он быстро превращается в автомат, который гоняет один и тот же запрос по кругу. Обычно проблема не в модели, а в слишком сложной логике выбора. Начните с 3-5 классов трафика, которые легко различить по типу задачи, длине контекста, допустимой задержке и правилам по данным.
Обычно хватает таких классов: короткие FAQ, длинные ответы с большим контекстом, вызовы с инструментами, пакетные задачи и запросы с персональными данными. Для класса с ПДн правило должно быть жестким: если запрос обязан оставаться в российском контуре, маршрут не должен даже пытаться уйти в другой вариант. Это сразу убирает часть случайных fallback-цепочек.
Простая схема маршрута
Для каждого класса задайте одну основную модель и одну резервную. Иногда можно добавить второй резерв, но третий переход почти всегда приносит больше вреда, чем пользы. Цена растет, задержка расползается, а причина сбоя размывается. Хорошая маршрутизация любит короткие ветки.
Резерв выбирайте не по принципу "что угодно подешевле", а по другой причине отказа. Если основная модель часто упирается в лимит запросов, резерв должен жить у другого провайдера или в другом пуле мощностей. Если основная модель плохо держит длинный контекст, резерв должен закрывать именно эту проблему, а не повторять ее.
Ограничьте число переходов одним или двумя шагами. Простая логика выглядит так: основная модель отвечает с первой попытки; при сетевой ошибке или 429 запрос уходит в резерв; если резерв возвращает ту же ошибку того же класса, система ставит жесткий стоп. Повторять один и тот же ход бессмысленно.
Такой стоп лучше задавать явно. Если две модели подряд вернули таймаут, 429 или ошибку политики доступа, оркестратор завершает запрос и отдает понятный статус наверх. Иначе команда неделями ловит циклы, где один и тот же промпт ездит между маршрутами с одинаковым поведением.
Логи здесь нужны не для галочки. По каждому переходу сохраняйте:
- класс запроса;
- выбранную модель и резерв;
- причину перехода;
- код ошибки или признак деградации;
- итоговую цену и полную задержку.
Через неделю таких логов обычно становится видно, где маршрут ломается на самом деле. Часто оказывается, что у одного класса просто неверно выбрана основная модель, а не то, что "вся система нестабильна". Если у класса нет четкого резерва, стоп-условия и понятной причины перехода в логах, такой маршрут лучше не выпускать в прод.
Пример: чат поддержки банка
У банка в чате обычно смешиваются два разных потока. Первый - короткие запросы вроде "какой у меня баланс" или "когда спишется комиссия". Второй - спорные диалоги, где клиент не согласен с операцией, спрашивает про блокировку карты или пишет слишком расплывчато.
Если пустить все сообщения в одну модель и к одному провайдеру, цена растет, а задержка скачет. Для банка это плохой обмен: простые FAQ становятся слишком дорогими, а чувствительные запросы теряют предсказуемость.
Вопросы про баланс, операции и остатки по счету лучше сразу направлять в контур с хранением в РФ. Причина простая: такие диалоги легко содержат персональные данные, и маршрут должен учитывать 152-ФЗ с первого шага, а не после ошибки или позднего fallback.
Одна из рабочих схем может выглядеть так:
- FAQ по тарифам, срокам зачисления и лимитам закрывает недорогая модель;
- диалоги с данными по счету идут через провайдера с логами и хранением в РФ;
- спорные ответы на малой доле трафика проверяет вторая модель;
- при таймауте система меняет провайдера, но не перескакивает в другой класс задачи.
Последний пункт важнее, чем кажется. Если маршрут для запросов по операциям уперся в таймаут, банку не нужна дешевая FAQ-модель в роли запасного варианта. Она ответит быстрее, но начнет угадывать там, где нужен доступ к точному банковскому контексту.
Вторая проверка тоже не должна работать на всем потоке. Банк может отправлять на нее только 5-10% спорных диалогов: жалобы на списания, неясные формулировки, вопросы с низкой уверенностью первой модели. Так команда видит реальные ошибки и не платит вдвое за каждый чат.
Смотреть лучше не на среднюю задержку, а на p95 по каждому типу диалога. У простого FAQ один бюджет по времени и цене. У запросов по карте, остаткам и спорным операциям - другой. Если смешать их в один отчет, проблема потеряется: средняя метрика выглядит нормально, а клиенты со сложными вопросами ждут на 2-3 секунды дольше.
Такая маршрутизация редко выглядит эффектно, зато работает спокойно. Банк заранее решает, какие темы остаются в российском контуре, где можно экономить, а где нужна вторая проверка.
Где команды чаще ошибаются
Первая поломка обычно начинается не с модели, а с логики маршрута. Команда пишет одно правило на все случаи: если ответ плохой, если таймаут, если 429, если пустой вывод - сразу идти в другую модель. Так повтор и fallback сливаются в один механизм, и маршрут начинает дергаться без причины.
Разница простая. Повтор нужен, когда та же модель, скорее всего, нормально ответит со второй попытки: например, при кратком сетевом сбое или временном лимите у провайдера. Fallback нужен, когда продолжать с той же моделью уже бессмысленно: она не проходит по задержке, не держит нужный формат или недоступна дольше порога. Если это не разделить, система легко уходит в цикл: модель A отвечает медленно, запрос уходит в B, B ловит таймаут, а потом правило возвращает его в A.
Вторая частая ошибка - маршрут обрастает ветками до состояния, которое уже никто не может объяснить без схемы на полэкрана. Сначала добавляют одно условие на цену, потом на длину контекста, потом на тип клиента, потом на регион хранения данных. Через месяц любое изменение ломает соседнюю ветку.
Обычно это видно по таким признакам:
- никто не может за 2 минуты объяснить путь одного запроса;
- у одной и той же задачи разные модели выбираются без понятной причины;
- после инцидента команда спорит, какое правило сработало первым;
- тесты покрывают только "счастливый" путь.
Еще одна ловушка - смотреть только на среднюю задержку. Среднее число почти всегда выглядит прилично, даже когда пользователи уже жалуются. Для чата поддержки или банковского сценария важнее p95: именно там видно длинные подвисания, из-за которых оператор ждет ответ 8-10 секунд вместо 2.
Резервную модель тоже часто ставят "на всякий случай" и не гоняют на своих данных. Это дорого обходится. На общих бенчмарках модель может выглядеть нормально, а на ваших запросах - терять поля в JSON, путать статусы заявки или хуже маскировать ПДн.
И самая неприятная ошибка для российских команд - не отделять поток с персональными данными от общего трафика. Если запросы с ПДн идут по тем же правилам, что и обычные, их легко случайно отправить в неподходящий контур. Для 152-ФЗ это уже не мелкая недоработка, а архитектурная проблема. Сначала разделите трафик по требованиям к данным, и только потом сравнивайте цену, качество и задержку внутри каждого контура.
Короткая проверка перед запуском
Перед запуском маршрута команде нужен не большой дизайн-док, а короткий список проверок. Если пройти его честно, можно поймать две самые дорогие ошибки: лишние fallback-переходы и резерв, который падает вместе с основной веткой.
У каждого маршрута должен быть владелец. Не абстрактная "платформа", а конкретный человек или команда, которая отвечает за лимит цены, задержку и поведение при сбоях. Если стоимость запроса внезапно выросла в 3 раза, кто-то должен увидеть это в тот же день и решить, что менять: правило, модель или порог переключения.
Резервная модель не должна жить в той же точке отказа, что и основная. Если обе ветки идут через одного провайдера, один регион или один тип квоты, это не резерв, а дубликат риска. Для команд с требованиями 152-ФЗ это особенно важно: проверьте не только модель, но и место хранения логов, бэкапов и маршрут данных при переключении.
Перед релизом стоит пройти пять проверок:
- назначен владелец маршрута, и у него есть лимит цены на запрос и на день;
- основная и резервная ветки не делят одного провайдера, один регион или один пул квоты;
- логи пишут причину перехода: таймаут, пустой ответ, превышение цены, ошибка формата;
- тестовый набор включает короткие запросы, длинные диалоги и случаи с пустым или обрезанным ответом;
- дежурная команда знает, кто и как вручную отключает ветку без долгих согласований.
Логи часто портят всю картину. Команда видит только итоговый ответ и не понимает, почему система перескочила на резерв. Потом кажется, что маршрутизация работает нормально, хотя половина трафика уходит в fallback из-за слишком строгого таймаута или неудачной проверки JSON.
Проверьте это на простом примере. Один и тот же запрос прогоняют через маршрут десять раз. Если в двух случаях система молча уходит на запасную модель, лог должен сразу показать причину. Иначе вы начнете лечить качество, хотя проблема сидит в правилах перехода.
Последняя проверка совсем практическая: дайте дежурным короткую инструкцию на случай инцидента. Когда ветку можно отключить вручную, кто принимает решение и какой маршрут остается после этого. В аварии никто не хочет вспоминать схему по памяти.
Что делать дальше
Не пытайтесь перестроить всю маршрутизацию сразу. Сначала возьмите один сценарий, где ошибка стоит дороже всего: длинные диалоги поддержки, разбор документов или ответы с персональными данными. На нем быстрее видно, какая схема держит цену и не ломается на пике.
Хороший первый шаг - зафиксировать один маршрут для этого сценария на неделю. Не меняйте пороги каждый день, иначе вы сравните не подходы, а шум. Если трафик небольшой, просто дайте тесту больше времени, но метрики оставьте одни и те же.
Смотрите не на абстрактное "качество", а на несколько чисел:
- цена на запрос или на 1000 запросов;
- p95 задержки;
- доля эскалаций на человека или на более дорогую модель;
- доля пустых fallback и повторных прогонов.
Если один вариант дешевле на 8%, но эскалаций стало вдвое больше, такая экономия обычно мнимая. А если p95 вырос с 4 до 9 секунд, это бизнес заметит сразу, даже когда средняя задержка выглядит терпимо.
Когда в данных есть ПДн, юридические требования лучше вшить в тест сразу. Иначе команда сначала выберет удобный маршрут, а потом начнет вычеркивать из него половину провайдеров из-за 152-ФЗ, хранения логов и аудита. После этого вся математика по цене и качеству меняется.
Если нужен единый OpenAI-совместимый эндпоинт внутри российского контура, можно отдельно проверить RU LLM. В таком случае достаточно сменить base_url на api.rullm.com и дальше сравнивать маршруты, не меняя SDK, код и промпты. Это удобно, когда нужно быстро проверить разные модели и провайдеров, но при этом держать логи, бэкапы и биллинг внутри РФ.
Двигайтесь по одному маршруту за раз. Перевели поддержку, собрали неделю цифр, оставили или откатили. Потом берите следующий сценарий. Такой темп кажется скучным, но именно он спасает от ситуации, когда сразу десять команд меняют маршрутизацию, а через две недели никто не может объяснить, почему выросли счета и пошли случайные fallback-циклы.
Простой ориентир такой: сначала самый дорогой сценарий, потом неделя замеров, потом решение по одному маршруту. Обычно этого хватает, чтобы убрать догадки и перейти к цифрам.
Часто задаваемые вопросы
Что лучше выбрать для первого запуска: правила или выбор на лету?
Для первого запуска обычно берут статические правила. Их проще проверить на своих запросах, проще показать юристам и безопасникам, и они реже дают сюрпризы по счету и задержке.
Выбор на лету имеет смысл позже, когда у вас уже есть логи, p95, причины ошибок и понятный набор сигналов для переключения.
Когда статическая маршрутизация дает лучший результат?
Такой подход лучше работает там, где сценарии почти не меняются. Например, короткие FAQ, простая классификация и ответы по базе знаний.
Он также удобнее, когда часть трафика нельзя выводить за пределы российского контура и вам нужен ровный бюджет на месяц.
В каких случаях выбор модели на лету правда экономит?
Она окупается, если в одном потоке смешаны простые и тяжелые запросы. Тогда дешевая модель закрывает обычные случаи, а более сильная включается только там, где правда нужна.
Особенно заметен эффект, когда провайдеры временами тормозят или отдают ошибки, и система может быстро увести только проблемный трафик.
Почему смотреть нужно на p95, а не только на среднюю задержку?
Средняя задержка часто скрывает проблему. Пользователь чувствует не среднее число, а плохие минуты, когда ответ внезапно идет 8–10 секунд.
Поэтому p95 полезнее для чатов, поддержки и банковских сценариев. Он быстро показывает, где маршрут начинает сыпаться под нагрузкой.
Сколько fallback-переходов стоит разрешать?
Обычно хватает одного резерва. Иногда добавляют второй, но дальше задержка растет, цена тоже, а причину сбоя уже трудно понять.
Если основная и резервная ветки вернули одну и ту же ошибку одного класса, лучше остановить запрос и вернуть понятный статус наверх.
Чем retry отличается от fallback?
Retry — это повтор той же модели, когда вы ждете, что вторая попытка пройдет нормально. Например, при кратком сетевом сбое или временном лимите.
Fallback — это переход на другой маршрут, когда продолжать с той же моделью уже нет смысла. Если смешать эти два шага, легко получить цикл между моделями.
Какие метрики нужно собрать до выбора схемы?
Соберите цену входных и выходных токенов, p95 по задержке и свой набор проверочных запросов. Лучше брать не общий бенчмарк, а реальные случаи: длинный контекст, спорные формулировки, таблицы, строгий JSON.
Еще полезно отдельно записывать причины переходов: таймаут, 429, пустой ответ, ошибка формата, срабатывание фильтра. Тогда вы увидите, где проблема в качестве, а где в логике маршрута.
Как учесть 152-ФЗ и ПДн в маршрутизации?
Сначала отделите поток с персональными данными от обычного трафика. Только после этого выбирайте модели и провайдеров внутри допустимого контура.
Проверку на хранение логов, бэкапов, маскирование PII и маршрут данных нужно делать до первого запроса, а не после сбоя или позднего переключения.
Как понять, что резервная модель выбрана неудачно?
Плохой резерв легко узнать по логам. Он падает по той же причине, что и основная ветка, живет у того же провайдера или не держит ваш формат ответа.
Проверьте его на своих данных заранее. На общих тестах модель может выглядеть нормально, а в проде терять поля, путать статусы или ломать JSON.
Можно ли проверить разные маршруты без переделки всего приложения?
Да, если вы используете OpenAI-совместимый шлюз. В случае RU LLM обычно хватает сменить base_url и дальше гонять те же SDK, код и промпты.
Это удобно для сравнения разных маршрутов, когда нужно держать логи, биллинг и хранение данных внутри РФ.