TL;DR
Маршрутизация с учётом истории — это схема, где перед каждым запросом пользователя лёгкая модель-диспетчер получает сам запрос и всю историю сессии. Она выдаёт одну метку: «простой» или «сложный». Простые ходы идут на дешёвую модель, сложные на дорогую. Выбранная модель ведёт весь ход целиком: все вызовы инструментов и правки до ответа пользователю.
Главная находка: диспетчер без истории ошибается там, где запрос выглядит простым. «Примени тот же формат к Q3» или «поменяй параметр у сводной» без контекста читаются как мелочь. На деле они зависят от того, что агент уже строил, какие были ошибки и на что ссылается просьба. Доля ходов, отданных дешёвой модели, в обоих вариантах почти одинаковая. Но с историей качество выше, потому что отбираются другие ходы. Есть и вторая ловушка: цена за токен не равна цене за задачу. Дешёвая модель делает больше вызовов и тянет больше входного текста, поэтому скидка «в 6,8 раза» сжимается до 3,2 раза на длинных сессиях.
Суть метода в одном запросе на ход: «запрос + история → метка». Ещё три вывода из статьи: случайное переключение хуже, чем держаться одной модели; переключать «вниз» (дорогая → дешёвая) дёшево по кэшу, «вверх» нет; выбор пары моделей важнее самой маршрутизации. В тестах диспетчер сохранял качество дорогой модели, но реальной экономии почти не дал (подробнее в «Ограничениях»).
Схема метода
ШАГ 1: Перед ходом t собрать вход → запрос пользователя + сериализованная история
(прошлые запросы, ответы, вызовы инструментов, ошибки, прошлые решения диспетчера)
ШАГ 2: Диспетчер (дешёвая модель, отдельный вызов, один раз на ход) → метка SIMPLE / COMPLEX
ШАГ 3: Метка → модель. SIMPLE → дешёвая, COMPLEX → дорогая
(таймаут, битый формат, сбой диспетчера → дорогая)
ШАГ 4: Выбранная модель ведёт ВЕСЬ ход (все вызовы и инструменты), роутер внутри хода не вмешивается
ШАГ 5: Результаты хода дописываются в историю → вход для следующего решения
Каждый шаг — это отдельный вызов или действие в оркестрации. В один промпт всё это не сводится.
Пример применения
Задача: Финансовый аналитик маркетплейса ведёт долгую сессию в агенте над выгрузкой продаж с Ozon. Ходы: «собери сводную по артикулам», «поменяй период на третий квартал», «почини формулы, где #ССЫЛКА». Он хочет, чтобы дорогая модель брала только сложные ходы. Метод лучше всего работает на многоходовых сессиях с накопленным состоянием, поэтому пример взят именно такой.
Промпт (для модели-диспетчера, вызывается перед каждым ходом):
Ты диспетчер. Ты не выполняешь задачу. Ты решаешь, какой модели отдать следующий ход:
SIMPLE (дешёвая) или COMPLEX (дорогая).
COMPLEX, если ход требует: планирования из нескольких шагов, согласования
нескольких листов или объектов, исправления более ранней ошибки, либо если непонятно,
на что ссылается запрос.
SIMPLE, если это локальная правка по уже понятной структуре: смена параметра,
форматирование, копирование уже созданного шаблона.
Ход 1: «Собери сводную по артикулам из листа Продажи_Ozon». Агент создал лист «Сводная»,
формулы СУММЕСЛИМН по колонкам выручки и возвратов. Успешно.
Ход 2: «Добавь колонку с маржой». Агент добавил колонку, ошибок нет.
«Теперь поменяй период на третий квартал и сделай как в прошлом отчёте по Wildberries».
Сначала проверь, на что ссылается запрос, по истории. Учти, что «как в прошлом отчёте»
в истории не найден. Ответь одним словом: SIMPLE или COMPLEX.
Если сомневаешься — COMPLEX.
Результат: Диспетчер вернёт одну метку. Здесь он, скорее всего, пометит ход как сложный: фраза про «прошлый отчёт по Wildberries» в истории не находится, и без неё запрос двусмысленный. Без истории тот же запрос выглядел бы как «поменять период», то есть простая правка. Ход уйдёт на дорогую модель. Если бы просьба была «поменяй период на третий квартал» (структура уже в истории и понятна), метка скорее всего была бы SIMPLE.
Почему это работает
Слабость: запрос пользователя в многоходовой сессии почти никогда не самодостаточен. Фразы вроде «сделай так же» зависят от того, что уже в таблице. Диспетчер без истории оценивает сложность по тексту реплики и принимает неоднозначный запрос за простой. Дешёвая модель получает ход, который ей не по силам, и ошибка тянется дальше по сессии.
Сильная сторона: LLM хорошо классифицирует, когда у неё есть контекст: что уже построено, что падало, на что ссылаются. Бинарная метка — самая простая из задач для лёгкой модели. А если дорогая модель уже построила структуру, дешёвая часто может её продолжить, следуя образцам в контексте. Ход, сложный в изоляции, в контексте становится лёгким.
Как метод это использует: история добавляется диспетчеру как вход, поэтому он различает «параметр у существующего объекта» и «что-то неясное, нужно восстанавливаться после ошибки». Все остальные части конвейера остаются прежними.
Рычаги управления: - Что входит в историю (только запросы, или ещё ошибки и вызовы инструментов) → больше деталей даёт точнее решение, но длиннее вход. - Критерии COMPLEX/SIMPLE → ужесточи («при сомнении COMPLEX»), если ошибка дороже экономии. - Правило при сбое → в статье таймаут, битый формат и сбой диспетчера уводят ход на дорогую модель. - Выбор пары моделей → не гони все ходы через диспетчер, если дешёвая модель сама справляется (см. «Как исследовали»).
Шаблон промпта
Промпт диспетчера в доступной части статьи не приведён. Известно, что это дешёвая LLM, настроенная как бинарный классификатор, который выдаёт структурированную метку. Шаблон ниже — реконструкция по этому описанию, а критерии взяты из введения статьи (планирование, согласование объектов, исправление ошибок).
Ты диспетчер. Ты не выполняешь задачу пользователя.
Твоя единственная работа — выбрать модель для следующего хода: SIMPLE ({дешёвая_модель}) или COMPLEX ({дорогая_модель}).
COMPLEX, если ход требует: планирования, согласования нескольких {объектов},
исправления более ранней ошибки, или если запрос непонятен без истории и в истории ответа нет.
SIMPLE, если это локальная правка по уже понятной структуре.
{сериализованная_история: запросы, ответы агента, вызовы инструментов, ошибки, прошлые решения диспетчера}
{запрос_пользователя}
Определи по истории, на что ссылается запрос и были ли ошибки.
Ответь одним словом: SIMPLE или COMPLEX.
Если сомневаешься — COMPLEX.
Что подставлять: {дешёвая_модель} и {дорогая_модель} — названия двух моделей из вашей пары. {объекты} — то, что в вашей задаче связывает ходы (листы, файлы, модули, документы). {история} — весь лог сессии, включая ошибки и вызовы инструментов, а не только реплики пользователя.
🚀 Быстрый старт — вставь в чат:
Вот шаблон диспетчера для выбора модели по ходам сессии. Адаптируй под мою задачу: [твоя задача и какие модели у меня есть].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие модели у тебя в паре, что связывает ходы в твоей сессии и какие ошибки для тебя дорогие. Это нужно, чтобы критерии COMPLEX/SIMPLE описывали твои реальные сложные ходы, а не абстрактные. Она возьмёт структуру из шаблона и подстроит критерии.
Чтобы метод заработал, диспетчер должен вызываться автоматически перед каждым ходом. Для этого нужна оркестрация (код или готовый инструмент). В обычном чате маршрутизатор не заменить.
Ограничения
⚠️ Экономия не доказана: диспетчер сохранял качество дорогой модели, но реальные затраты почти не снижал. Для Opus high/low он стоил $0,369 против $0,365 у «только дорогой» на SheetCopilot и $2,080 против $2,009 на SpreadsheetBench 2. Выигрыша по цене в этих тестах нет.
⚠️ Диспетчер не видит разницу между моделями: он отправляет на дешёвую модель около 21–24% ходов в любой паре, независимо от того, насколько она слабее дорогой. Там, где дешёвая модель не уступает дорогой, лучше вообще не маршрутизировать. Luna одна давала 28,6% при $0,061 за задачу против 26,8% у диспетчера с историей. Opus на низком уровне рассуждений дал 31,2% при $0,268 против $0,369.
⚠️ На сложных задачах он почти всегда выбирает дорогую модель: на SpreadsheetBench 2 дешёвой модели доставалось менее 2% ходов. Выигрыш от истории там маленький и непостоянный.
⚠️ Нужна оркестрация: метод требует автоматического вызова диспетчера, сборки истории и переключения моделей. В обычном чате это не применить, нужен код или готовый конвейер.
⚠️ Узкая область и искусственные диалоги: тесты только на таблицах. Многоходовые диалоги получены разрезанием одноходовых задач на подзадачи, а в SheetCopilot продолжения часто прямо следуют из первого запроса. Это упрощает работу диспетчера.
⚠️ Случайное и «вниз по умолчанию» слабее: случайный выбор давал худшее качество, чем любая фиксированная модель. Схема «всегда начинать с дорогой и передавать дешёвой» (деэскалация) тоже показала слабый результат.
⚠️ Текст статьи в источнике обрезан: детали анализа кэша и последняя часть выводов в доступном фрагменте не видны, поэтому здесь пересказаны только цифры из реферата.
Как исследовали
Исследователи из Microsoft проверяли маршрутизацию на двух таблично-агентных бенчмарках, превратив их в многоходовые диалоги. Из SheetCopilot взяли 112 задач (в среднем 2,88 хода), из SpreadsheetBench 2 — 221 сквозной сценарий (4,76 хода). Задачи в таблицах хороши тем, что у результата нет проверки на ошибки: формула по неверному диапазону даёт правдоподобное число, а не сообщение об ошибке. Успех мерили по финальной таблице в конце диалога.
Сравнивали шесть подходов: только дорогая, только дешёвая, диспетчер без истории, диспетчер с историей, эскалация (старт на дешёвой, передача дорогой), деэскалация и случайный выбор. Тестировали три пары, в каждой менялся один фактор: размер модели внутри одного провайдера (GPT-5.6 Sol и Luna), провайдер (Sol и Claude Haiku 4.5), уровень рассуждений (Opus 4.8 high и low). В стоимость включили вызовы самого диспетчера и эффект кэша промпта.
Результат с историей: 28,3% успеха против 25,0% без неё при почти одинаковой доле дешёвых ходов (22,7% и 23,3%), и выигрыш был в каждой паре. Значит, дело в выборе ходов, а не в их количестве. Случайный выбор оказался хуже обеих крайностей: решение без сигнала не лучше, чем держаться одной модели.
Неожиданности: во-первых, цена за токен не равна цене за задачу. Haiku делал в 1,6 раза больше вызовов и тянул в 1,7 раза больше входных токенов, поэтому его выигрыш сжимался с 6,8 до 3,2 раза. Во-вторых, Opus на низком уровне рассуждений был одновременно и дешевле, и точнее, чем на высоком. В-третьих, по расчёту кэша переключение «вниз» (дорогая → дешёвая) окупает потерю кэша за два вызова, а «вверх» при проверенных условиях не окупается вовсе. Для практики это значит: сначала проверь, не справится ли одна дешёвая модель, а маршрутизацию добавляй, только если пара того стоит.
Адаптации и экстраполяции
🔧 Техника: добавить в критерии ограничитель «ссылка без источника» → меньше ошибок на неоднозначных запросах
В шаблон уже включено правило «если запрос непонятен без истории и ответа в истории нет — COMPLEX». Его можно усилить явной проверкой:
Перед решением выпиши, на что ссылается запрос ("тот же формат", "как раньше") и найди это в истории. Если не нашёл — COMPLEX.Это соответствует наблюдению статьи, что без истории неоднозначные follow-up воспринимаются как простые. Прямо этот вариант авторы не проверяли.
Экстраполяция: ручная маршрутизация в Claude Code или Cursor. Диспетчера можно заменить собственным правилом выбора модели перед каждым шагом (в статье этого нет, это вывод из её результатов). Сложные шаги (план, правка нескольких файлов, исправление ошибки) делает сильная модель или высокий уровень рассуждений. Локальные правки продолжает дешёвая, которая видит уже построенную структуру в контексте. Две проверки из статьи: сравнивай реальную стоимость задачи, а не прайс токенов, и сначала проверь, не хватает ли одной дешёвой модели или низкого уровня рассуждений на всю сессию.
Ресурсы
- Whose turn is it? Context-guided model routing for stateful agents (Preprint)
- Авторы: Anikesh Parashar, Avik Dutta, Vashu Chauhan, Sumit Gulwani, Priyanshu Gupta, Hosein Hasanbeig, Vu Le, Ashish Tiwari, Jack Williams — Microsoft
- Бенчмарки: SheetCopilot (Li et al., 2023), SpreadsheetBench 2 (Zhu et al., 2026)
- Ближайшие работы по маршрутизации с историей: DialRouter и MTRouter (Zhang et al., 2026a;b)
