Перейти к содержимому
25 нояб. 2024 г.·8 мин чтения

Маршрутизация моделей без лишних расходов в продакшене

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

Маршрутизация моделей без лишних расходов в продакшене

Почему бюджет уходит в простые запросы

Бюджет чаще съедают не сложные сценарии, а поток мелких и повторяющихся запросов. Если все задачи идут в одну и ту же модель, дорогой маршрут начинает обслуживать рутину, которую спокойно закрыла бы более дешевая модель или даже обычные правила.

Обычно это самые приземленные задачи:

  • классификация обращения по теме
  • извлечение номера заказа, даты или суммы
  • короткий пересказ письма или чата
  • проверка, есть ли в сообщении жалоба, возврат или просьба о звонке
  • ответ по шаблону, где меняются несколько полей

Когда такие запросы уходят в ту же модель, что и длинные разборы документов или агентные цепочки, счет растет каждый день. Причина простая: флагманская модель дороже за токены, чаще пишет длиннее и нередко получает большой контекст там, где он вообще не нужен.

Одна сильная модель на все случаи сначала выглядит удобно. Один endpoint, один набор промптов, меньше правил. Но это удобство быстро превращается в постоянную переплату. Если 70% потока составляют простые операции, вы платите за запас качества там, где бизнес его даже не замечает.

Деньги обычно утекают в четыре места: лишние токены, повторы, таймауты и ненужные вызовы. Длинный системный промпт делает дорогой даже простую задачу. Повторный запрос после переформулировки снова вызывает ту же модель. Медленный ответ приводит к ретраю или переключению на запасной маршрут. А иногда один и тот же текст проходит через две или три модели без понятной причины.

Смотреть только на качество ответа мало. Гораздо полезнее сравнивать цену запроса с ценой ошибки. Если модель определяет категорию тикета, редкая ошибка может стоить копейки по сравнению с постоянным вызовом дорогой модели. Если модель готовит ответ по спорному возврату, считает риск или работает с персональными данными, ошибка уже обходится дороже, и сильная модель там оправдана.

Хорошая схема начинается не с выбора самой умной модели. Она начинается с вопроса: где ошибка действительно дорога, а где нет. С этого момента бюджет перестает утекать в простые запросы.

Какие запросы стоит разделить сразу

Самое выгодное деление обычно самое простое: короткие и повторяющиеся запросы не стоит отправлять в дорогую модель. Если пользователь просит пересказать абзац, достать поле из текста или ответить по готовому шаблону, ему не нужна большая reasoning-модель. На таких задачах маршрутизация моделей дает заметную экономию уже в первую неделю.

Спорные случаи лучше отделить сразу. Если в запросе длинная переписка, несколько документов, противоречивые условия или высокая цена ошибки, дешевый маршрут начинает давать ложную экономию. Вызов стоит меньше, но потом команда тратит больше на fallback, повторы и ручную проверку.

Для старта обычно хватает четырех корзин:

  • короткие и шаблонные задачи
  • задачи с жесткими правилами
  • сложные запросы с длинным контекстом
  • случаи, которые лучше сразу передать человеку

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

Отдельный дешевый маршрут нужен и для задач с жесткими правилами. Если система должна проверять обязательные поля, маскировать персональные данные, искать запрещенные формулировки или сверять ответ с фиксированным регламентом, сначала используйте код, правила или маленькую модель. В таких местах "умнее" не всегда значит "лучше".

Сложный запрос обычно видно еще до вызова модели. Пользователь приложил несколько файлов. В диалоге уже двадцать сообщений. Нужно сверить версии документов, понять исключения из правил или объяснить расхождение. Еще один явный сигнал - риск неверного ответа: деньги, договоры, персональные данные, внутренние политики.

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

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

Как оценивать сложность до вызова модели

Сложность лучше считать до основного вызова. Иначе дорогая модель начнет решать все подряд, включая самую скучную рутину. Так бюджет уходит не на трудные случаи, а на самые частые.

На старте не нужна сложная система с десятком веток. Обычно хватает четырех сигналов: длины текста, числа вложений, языка запроса и типа задачи. Если пользователь прислал две короткие фразы без файлов и просит переписать текст вежливо, это почти всегда низкая сложность. Если в запросе длинная переписка, PDF, таблица и вопрос по договору на английском, уровень уже совсем другой.

Удобно оставить всего четыре уровня:

  • L1 - короткие шаблонные задачи без вложений
  • L2 - обычные рабочие запросы с небольшим контекстом
  • L3 - длинные тексты, несколько условий, редкий язык или файл
  • L4 - спорные случаи, где ошибка обходится дорого

Этого достаточно, чтобы разделить поток без лишней путаницы. Если уровней больше, команда быстро начинает спорить, чем L5 отличается от L6, а пользы почти нет.

Дальше добавьте легкий классификатор. Иногда хватает обычных правил и пары регулярных проверок. Если трафик сложнее, поставьте перед основной моделью дешевую модель-оценщик, которая возвращает только метку сложности: L1, L2, L3 или L4.

Промпт для такой оценки должен быть коротким и жестким. Без рассуждений и длинного вывода. Только класс и, если нужно, один-два признака вроде has_attachment=true. Тогда первый шаг стоит дешево и не тормозит ответ.

Потом проверьте схему на реальных запросах. Возьмите выборку из последних диалогов, разметьте ее руками и сравните с тем, как сработали правила. Ошибки обычно видны быстро: короткий запрос может оказаться сложным из-за вложения, а длинный текст - простым, если это обычный пересказ.

Самое важное здесь - опираться на свой трафик, а не на догадки команды. Хорошая маршрутизация строится на фактах из логов, а не на ощущении, что "вроде должно работать".

Как собрать маршруты для дешевых и дорогих моделей

Первый маршрут должен закрывать большую часть потока. Обычно это короткие диалоги, классификация, извлечение полей, перефразирование и ответы по понятному шаблону. Для них ставят базовую модель с низкой ценой и стабильной задержкой.

Если базовая модель держит нужное качество на ваших тестах, не надо заставлять ее соревноваться с дорогой на каждом запросе. Иначе маршрутизация моделей быстро превращается в лишние расходы.

Дорогую модель лучше держать в отдельном маршруте, а не включать "на всякий случай". Она нужна там, где ошибка действительно дорого стоит: при длинном контексте, неоднозначной формулировке, работе с финансовыми или юридическими текстами, а также в задачах с несколькими шагами рассуждения.

Сразу в сильную модель стоит отправлять запрос, если виден хотя бы один из таких признаков:

  • длинный ввод или несколько документов
  • высокий риск ошибки для бизнеса или комплаенса
  • неясная цель запроса
  • много условий в одном сообщении
  • повторный вопрос после слабого ответа

Запрос вроде "сделай краткое резюме письма" почти всегда тянет базовая модель. Договор на двадцать страниц с просьбой найти спорные пункты лучше сразу отправить в сильный маршрут.

У каждого маршрута должны быть свои рамки. Для дешевого маршрута задайте потолок на входные и выходные токены, короткий таймаут и не больше одного повтора. Для сильного маршрута лимиты можно поднять, но тоже заранее. Иначе один неудачный сценарий с ретраями съест бюджет быстрее, чем десятки простых запросов.

Правило лучше держать простым: дешевый маршрут отвечает быстро и закрывает массовый поток, сильный включается редко и по явным условиям. Чем меньше исключений в схеме, тем легче понять, почему запрос ушел в дорогую модель и сколько это реально стоило.

Как настроить fallback без двойной оплаты

Все модели в одном API
Маршрутизируйте запросы к 500+ моделям и 68+ провайдерам через единый эндпоинт.

Fallback помогает не терять ответ из-за сбоя, но именно он часто удваивает счет. Проблема обычно не в самой идее, а в том, что команда повторяет один и тот же запрос слишком много раз и слишком дорого.

В схеме, где работает маршрутизация моделей, fallback должен чинить редкие сбои, а не становиться вторым обычным маршрутом. Если половина запросов уходит на запасную ступень, значит основной путь настроен плохо или выбран не тот провайдер.

На запасной маршрут стоит переводить только случаи, где модель не успела нормально ответить:

  • при сетевой ошибке меняйте провайдера или регион исполнения
  • при rate limit меняйте провайдера, а не только модель
  • при пустом ответе повторяйте запрос один раз с короткой служебной инструкцией
  • при плохом качестве меняйте сам маршрут, а не запускайте слепой ретрай

Одинаковый промпт в той же модели редко спасает ситуацию. Лучше изменить хоть что-то: уменьшить контекст, убрать лишние вложения, добавить строгий формат ответа или отправить запрос в модель, которая лучше держит структуру.

Самая частая ошибка - передавать в fallback весь диалог целиком. Для второй ступени обычно нужен только последний вопрос, короткая системная инструкция и несколько последних сообщений. Если в поддержку пришел запрос на возврат, запасной модели не нужен весь чат за две недели. Лишний контекст напрямую раздувает стоимость.

Еще до запуска посчитайте цену каждой ступени. Допустим, первая модель стоит 1x, вторая 4x, третья 12x. Если простой тикет приносит бизнесу экономию в несколько рублей, третья ступень уже не имеет смысла. Цепочку надо останавливать в тот момент, когда следующий шаг дороже пользы от ответа.

На практике лучше держать жесткий лимит: не больше двух попыток на один пользовательский запрос и не больше заданной суммы на весь маршрут. Хороший fallback короткий, предсказуемый и включает дорогие модели редко. Если запасной путь срабатывает часто, чинить нужно основной маршрут.

Как запустить схему без лишнего риска

Начните не с правил, а с живых данных. Возьмите 100-200 реальных запросов из продакшена или пилота и разложите их по типам: короткие фактовые вопросы, извлечение полей, классификация, длинные рассуждения, ответы с высокой ценой ошибки. Если взять только аккуратные примеры из демо, схема быстро сломается на реальном трафике.

Дальше вручную пометьте этот набор. Для каждого запроса проверьте, где дешевая модель дает нормальный результат, а где начинает путать факты, терять поля или писать слишком общий ответ. На этом этапе не нужна идеальная разметка. Нужна честная граница между "можно отправлять в дешевый маршрут" и "лучше сразу вести в сильную модель".

Смотрите не только на качество ответа, но и на цену ошибки. Для сброса пароля в SaaS можно терпеть простой шаблонный ответ. Для вопроса про биллинг, договор или персональные данные такой риск уже дороже, чем несколько лишних рублей на более сильную модель.

После разметки соберите первый роутер с простыми правилами. Например, короткие запросы до определенной длины и типовые интенты идут в дешевую модель, сложные или неуверенные случаи - в старшую. Fallback для LLM тоже лучше строить по понятным условиям: пустой ответ, низкая уверенность, пропуск обязательных полей, превышение лимита по времени.

Не выпускайте схему сразу на весь поток. Дайте ей 5-10% трафика или запустите в теневом режиме, если можете сравнить ответы без влияния на пользователя. Так вы быстро увидите, где правило выглядит разумно на бумаге, но дает лишние эскалации или, наоборот, пропускает сложные запросы в дешевую модель.

Сравнивайте маршруты по одним и тем же метрикам:

  • цена на запрос и на 1000 запросов
  • p95 задержка
  • доля ответов, которые проходят вашу проверку качества
  • частота срабатывания fallback
  • доля ручных разборов после ответа модели

И еще один практичный момент: закрепляйте правила в конфиге, версиях маршрутов и логах, а не в ручных исключениях вроде "если пишет клиент X, шлем в модель Y". Иначе через месяц схема станет непонятной даже собственной команде.

Пример для поддержки в SaaS

Инвойсинг в рублях
Считайте расход по маршрутам с инвойсингом в рублях и поддержкой внутри РФ.

У поддержки в SaaS почти всегда смешанный поток. Утром приходят короткие вопросы про тариф, лимиты и статус заказа. Чуть позже появляется тикет с длинной перепиской, спором по возврату и тремя версиями событий от клиента и менеджера. Если оба типа запросов отправлять в одну дорогую модель, цена растет без пользы.

Рабочая схема здесь довольно проста. Короткие обращения без вложений и без спорных условий идут в дешевую модель. Она хорошо справляется с вопросами вроде "какой у меня тариф", "когда спишется оплата" или "можно ли сменить план в середине месяца". Такие ответы обычно опираются на правила и базу знаний, а не на сложное рассуждение.

Длинные жалобы лучше сразу отправлять в сильный маршрут. Туда же стоит вести тикеты, где есть история диалога, конфликт по условиям оферты, риск возврата денег или явное несоответствие между данными клиента и правилами сервиса. На таких кейсах экономия на модели часто выходит дороже, потому что команда потом тратит время на ручную правку.

Представим 1000 тикетов в день. До маршрутизации все уходили в сильную модель, и средняя цена одного тикета была 12 рублей. Итого 12 000 рублей в день.

После разделения поток может выглядеть так:

  • 700 простых тикетов идут в дешевую модель по 2 рубля
  • 250 сложных тикетов сразу идут в сильную модель по 12 рублей
  • 50 тикетов получают один fallback в сильную модель только при таймауте или пустом ответе

Расход считается просто: 700 x 2 = 1400 рублей, 250 x 12 = 3000 рублей, 50 x (2 + 12) = 700 рублей. Общая сумма - 5100 рублей в день. Средняя цена тикета падает с 12 до 5,1 рубля.

Здесь важно не делать fallback по любому сомнению. Если дешевая модель ответила по форме и уложилась в правила, не надо запускать вторую модель "на всякий случай". Повтор нужен только там, где был таймаут или модель вернула пустой ответ. Так вы сохраняете качество на сложных обращениях и не платите дважды за обычную рутину.

Ошибки, которые быстро съедают бюджет

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

Первая частая ошибка - слишком много маршрутов без простых правил выбора. На старте обычно хватает двух или трех веток: простые запросы, запросы средней сложности и редкие тяжелые случаи. Если маршрутов семь, а условия размыты, система начинает метаться между моделями, и цена растет без заметной пользы.

Вторая ошибка - включать fallback после любого сбоя. Причина отказа имеет значение. Если модель не ответила из-за таймаута, можно повторить запрос в другой модели. Если она уперлась в лимит контекста, слепой fallback только дублирует расход. Если проблема в политике ответа или в битом вложении, вы просто оплатите вторую неудачу.

Часто деньги уходят и на промпты. Один и тот же системный промпт для короткого вопроса и длинной аналитической задачи почти всегда избыточен. В поддержке SaaS это видно сразу: запрос вроде "где скачать счет" не требует длинных инструкций, большого набора правил и развернутого стиля ответа. Но многие отправляют все это каждый раз, а потом удивляются счету за токены.

Еще одна дорогая привычка - слать в модель всю историю диалога, логи и вложения без обрезки. Если клиент уже три раза описал одну и ту же проблему, не нужно снова передавать весь диалог на восемь тысяч токенов. Оставьте последнее состояние, нужные факты и короткую выжимку. То же касается файлов: сначала извлеките нужный фрагмент, а не отправляйте весь документ.

Наконец, многие смотрят только на качество ответа и забывают про цену и задержку. Это плохой обмен. Модель может отвечать на 3% лучше, но стоить в пять раз дороже и работать на две секунды медленнее. Для продакшена такая сделка редко бывает разумной.

Минимум, который стоит держать под рукой:

  • мало маршрутов и правило выбора в одно предложение
  • раздельная обработка таймаута, лимита контекста, отказа по политике и ошибок входных данных
  • короткий системный промпт для простых задач
  • отдельный учет качества, цены за решенный запрос и средней задержки

Быстрые проверки перед релизом

Контур под 152-ФЗ
Маскируйте PII и получайте аудит-трейл по каждому запросу в одном контуре.

Перед запуском прогоните маршруты на плохих сценариях, а не только на удачных тестах. Бюджет обычно уходит не на сложные задачи, а на пустые ответы, повторы и лишние прыжки в дорогие модели.

Сначала задайте верхний предел стоимости на один запрос. Если лимит исчерпан, система должна остановиться, упростить маршрут или вернуть понятную ошибку. Хуже всего, когда после двух неудачных попыток она молча уходит в модель в десять раз дороже.

Потом проверьте объяснимость. По каждому запросу команда должна сразу видеть, какой маршрут выбрала система и почему. Короткий вопрос по тарифу ушел в дешевую модель. Длинная претензия с историей переписки - в более сильную. Запрос с таймаутом - в fallback. Если это нельзя быстро прочитать в логах, поддерживать схему будет тяжело.

В логах стоит держать хотя бы три поля: цену, задержку и причину fallback. Иначе снижение затрат на LLM быстро превращается в спор по ощущениям.

Перед релизом полезно проверить такой минимум:

  • есть ли лимит цены на один запрос и на всю цепочку retry
  • видно ли, почему сработала маршрутизация
  • ловит ли система пустой ответ, таймаут и повтор одного и того же запроса
  • пишутся ли в логи цена, задержка, модель и причина fallback
  • проходили ли тесты запросы с длинным контекстом и редкими форматами

Отдельно посмотрите на редкие случаи. Длинный контекст, таблицы, куски JSON, смешанный русский и английский, агрессивные инструкции пользователя часто ломают хороший маршрут. На демо все выглядит аккуратно, а в продакшене именно такие запросы и приходят.

Есть простой тест: возьмите 100 реальных запросов, где есть короткие, длинные и странные. Потом вручную проверьте 15-20 из них. Если дешевая модель ошибается там, где ошибка приводит к повторному запросу оператора или клиента, экономия оказывается мнимой.

Хороший релиз выглядит скучно. У каждого запроса есть понятный маршрут, у каждого fallback есть причина, а у команды уже в первый день есть цифры по цене и задержке.

Что делать дальше

Не пытайтесь перестроить всю систему сразу. Выберите один поток, где запросы похожи друг на друга: первую линию поддержки, разбор типовых писем или ответы на частые вопросы в SaaS. На таком участке проще увидеть, где дорогая модель тратится зря, а где без нее пока не обойтись.

Сразу заведите простую рабочую таблицу. Без нее маршрутизация моделей быстро превращается в набор догадок. Достаточно нескольких полей: тип запроса, какая модель идет первой, лимит по токенам и времени ответа, когда срабатывает fallback и почему запрос ушел дальше.

Через неделю уже видно, какие правила работают, а какие только добавляют шум и лишние вызовы. Смотрите не на среднюю цену по всем запросам, а на реальные группы. Если 70% обращений укладываются в короткий шаблон, отправляйте их в дешевую модель по умолчанию. Дорогую оставляйте для длинных диалогов, неоднозначных кейсов и задач, где ошибка потом стоит дороже, чем сам вызов.

Полезно раз в неделю пересматривать логи и расходы вместе. Большой аудит не нужен. Достаточно выбрать 50-100 запросов, посмотреть маршрут, причину fallback и итоговый ответ. После такого обзора команда часто убирает пару лишних правил и сразу видит экономию.

Если у вас уже есть код под OpenAI-совместимый API и не хочется менять SDK, RU LLM позволяет тестировать разные маршруты через единый endpoint и менять только base_url. Для команд, которым важны data residency, биллинг и поддержка внутри РФ, это снимает часть интеграционных хлопот и позволяет сосредоточиться на самой логике маршрутизации.

Хороший следующий шаг совсем простой: выберите один поток, включите два маршрута вместо одного и неделю измеряйте цену, долю fallback и качество ответа. Этого достаточно, чтобы принять первое нормальное решение без лишних затрат.

Часто задаваемые вопросы

Как понять, что бюджет уходит именно на простые запросы?

Сначала посмотрите, какие запросы идут чаще всего и сколько они стоят. Если короткие классификации, извлечение полей и шаблонные ответы занимают большую часть трафика, а вы гоняете их через дорогую модель, бюджет уходит именно туда.

Проверьте логи по длине входа, длине ответа, цене и числу повторов. Обычно картина видна быстро: простых запросов много, пользы от дорогой модели мало, а счет растет каждый день.

Какие задачи лучше сразу вести в дешевую модель?

Отправляйте туда короткие и повторяющиеся задачи с понятным форматом ответа. Это классификация тикета, извлечение номера заказа, даты или суммы, короткий пересказ письма, проверка жалобы и ответы по шаблону.

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

Когда не стоит экономить и лучше сразу брать сильную модель?

Сильную модель включайте там, где ошибка обходится дорого или запрос сам по себе сложный. Это длинные переписки, несколько документов, спорные возвраты, договоры, финансовые расчеты и работа с персональными данными.

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

Как оценить сложность до вызова модели?

На старте хватит простых сигналов до основного вызова: длина текста, наличие файла, язык запроса и тип задачи. Две короткие фразы без вложений почти всегда проще, чем длинная цепочка сообщений с PDF и таблицей.

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

Сколько уровней сложности делать на старте?

Обычно хватает четырех уровней. Первый закрывает шаблонные запросы, второй — обычные рабочие, третий — длинные тексты и файлы, четвертый — спорные случаи с высокой ценой ошибки.

Если уровней больше, команда начинает спорить о границах вместо того, чтобы снижать расход. Простая схема почти всегда живет дольше и работает понятнее.

Как настроить fallback без двойной оплаты?

Держите fallback коротким и редким. Переводите запрос на запасной маршрут только после сетевой ошибки, rate limit, таймаута или пустого ответа.

Не запускайте вторую модель просто из-за сомнений. Если половина трафика стабильно уходит в fallback, чините основной маршрут или меняйте провайдера, а не наращивайте число повторов.

Что отправлять в fallback, чтобы не раздувать токены?

Во второй запрос кладите только то, что реально нужно для ответа. Чаще всего хватает последнего вопроса, короткой системной инструкции и нескольких последних сообщений.

Не тащите весь диалог и все вложения по привычке. Лишний контекст раздувает цену и редко помогает запасной модели ответить лучше.

Какие метрики смотреть после запуска маршрутизации?

Смотрите не только на качество. Для каждого маршрута держите цену на запрос, p95 задержку, долю срабатываний fallback и число случаев, где оператору пришлось исправлять ответ.

Полезно считать и цену решенного запроса, а не только цену вызова. Дешевая модель теряет смысл, если после нее команда постоянно делает ручную правку.

Как безопасно запустить такую схему в продакшене?

Не включайте схему сразу на весь поток. Возьмите 100–200 реальных запросов, разметьте их руками, соберите простые правила и дайте новой логике 5–10% трафика или теневой режим.

Так вы быстро увидите, где дешевый маршрут справляется, а где он пропускает сложные случаи. После этого уже можно подкрутить правила и расширять долю трафика.

Можно внедрить маршрутизацию без переписывания всей интеграции?

Да, если у вас уже есть код под OpenAI-совместимый API. В таком случае вы можете оставить SDK, промпты и логику клиента, а для тестов сменить только base_url и разнести маршруты по моделям и провайдерам.

Это удобно, когда нужно быстро проверить экономию без большой переделки приложения. Дальше вы уже смотрите на цену, задержку и качество по живому трафику.