Не женитесь на своей модели
Маршрутизация LLM, сейчас это огонь
Большинство инженерных команд выбирают одну языковую модель и придерживаются её. Один провайдер, одна модель, все задачи. Это как нанять одного человека для кода, копирайтинга и налогов только потому, что он хорошо прошёл первое собеседование.
В любой момент времени одна модель лучше пишет код, другая — работает с длинным запутанным контекстом, третья — дешёвая и скучная рабочая лошадка для классификации. Названия меняются. Суть задачи — нет. Относиться к одной модели как к универсальному решению — значит либо переплачивать за простые задачи, либо получать посредственные результаты на специализированных.
Я видел, как команда сжигала тысячи долларов, прогоняя анализ тональности через модель за 30 долларов за миллион токенов, когда модель за 0,50 долларов справилась бы не хуже. Простое JSON-форматирование, базовые задачи классификации — всё уходило через их премиум-провайдера. Единственное, что действительно нагревалось, — это счёт от AWS.
Есть способ лучше, и он не особенно сложен.
Делегирование вместо преданности
Что, если бы вы могли направлять запросы к модели, которая лучше всего подходит для этой конкретной задачи? Используйте свою дорогую «рабочую лошадку» для сложных вещей, а простой парсинг и форматирование спускайте на что-то подешевле. Получайте преимущества от нескольких провайдеров, не жонглируя ими вручную в коде.
Mastra позволяет построить именно такую систему. Вы создаёте агентов-специалистов для разных типов работ, а затем — супервизора, который решает, к какому специалисту направить каждый запрос. Идентификаторы моделей ниже используют текущий формат строки provider/model в Mastra; это примеры, а не таблица лидеров. Замените их на актуальные модели, которые побеждают в ваших eval’ах и вписываются в бюджет.
Представьте это так: у вас в команде три специалиста.
import { Mastra } from '@mastra/core/mastra';import { Agent } from '@mastra/core/agent';import { Memory } from '@mastra/memory';import { LibSQLStore } from '@mastra/libsql';
export const claudeAgent = new Agent({ id: 'claude-agent', description: 'Handles implementation, refactoring, and code review tasks.', instructions: 'You are an expert engineer. Write bugs? You are fired.', model: process.env.CODE_MODEL ?? 'anthropic/claude-sonnet-4-6',});
export const geminiAgent = new Agent({ id: 'gemini-agent', description: 'Handles long-context synthesis and messy document analysis.', instructions: 'You are a creative writer. Be weird.', model: process.env.LONG_CONTEXT_MODEL ?? 'google/gemini-2.5-pro',});
export const gptAgent = new Agent({ id: 'gpt-agent', description: 'Handles routine classification, formatting, and general Q&A.', instructions: 'You are a helpful assistant. Be boring.', model: process.env.GENERAL_MODEL ?? 'openai/gpt-5-mini',});У каждого своя работа, и поле description — часть поверхности маршрутизации. Ваш код-агент должен быть моделью, которая проходит ваши репозиторий-специфичные eval’ы по коду. Ваш агент длинного контекста должен быть тем, кто выживает на ваших реальных документах, не превращая середину в кашу. Ваш общий агент должен быть дешёвым, надёжным и настолько скучным, насколько это возможно.
Вот где становится интересно. Вы добавляете лёгкого супервизора, который работает как интеллектуальный прокси:
export const supervisorAgent = new Agent({ id: 'supervisor-agent', name: 'The Boss', instructions: `You route work to the right specialist. Delegate coding work to claude-agent. Delegate long-context document work to gemini-agent. Delegate routine classification and formatting to gpt-agent. Do not do specialist work yourself unless delegation is unnecessary.`, model: process.env.ROUTER_MODEL ?? 'openai/gpt-5-mini', agents: { claudeAgent, geminiAgent, gptAgent, }, memory: new Memory({ storage: new LibSQLStore({ id: 'router-memory', url: 'file:mastra.db' }), }),});
export const mastra = new Mastra({ agents: { supervisorAgent, claudeAgent, geminiAgent, gptAgent },});Сам супервизор может работать на лёгкой модели, потому что он в основном решает, куда направить трафик. Вы не платите премиальные ставки за то, чтобы выяснить, какую другую премиум-модель использовать. Измеряйте и это тоже — плохой слой маршрутизации незаметно превращает экономию в неверные направления.
Когда кто-то просит реализовать пузырьковую сортировку, маршрутизатор распознаёт это как работу с кодом и передаёт вашему специалисту по коду. Запрос на креативное письмо? Он уходит к модели, которую вы выбрали за голос и диапазон. Фактический вопрос об исторических событиях? Направляйте его общему агенту, в идеале с поиском (retrieval), если важны свежесть или цитирование.
Практические выгоды
Экономическая эффективность важнее, чем вы думаете. Маленькая модель маршрутизации, принимающая решения о делегировании, стоит копейки по сравнению с прогоном каждого запроса через самого дорогого провайдера. Со временем, особенно на масштабе, это превращается в реальные деньги. Вы платите за тяжёлую интеллектуальную работу только тогда, когда она действительно нужна.
Качество растёт, когда вы сопоставляете модели с задачами. Победитель меняется каждый месяц, в зависимости от задачи и формы промпта. Именно поэтому слой маршрутизации должен опираться на ваши eval’ы, а не на то, какая модель побеждала в твиттере на неделе, когда вы писали интеграцию.
Отказоустойчивость становится возможной, но не автоматической. Супервизор выше не повторяет запросы через другого агента в случае отказа провайдера, и сам он зависит от OpenAI для принятия решения о маршрутизации. Если вам важна отработка отказа провайдера, добавьте явный retry/fallback в прикладной код, держите запасной маршрутизатор на другом провайдере и тестируйте путь отказа. Набор агентов — это не circuit breaker только потому, что у моделей разные логотипы.
Это не про то, чтобы быть умным ради самого процесса. Это про то, чтобы строить системы, которые имеют смысл как с финансовой, так и с технической точки зрения. Вы же не будете использовать один и тот же молоток для всех строительных задач. И вам, вероятно, не следует использовать одну и ту же языковую модель для всех AI-задач.
Красота этого подхода в том, что ваш прикладной код не нуждается в разветвлённом лабиринте условных операторов. Вы по-прежнему вызываете одного агента. Сложность принятия решения о том, какую модель использовать для какой задачи, живёт в одном месте, настраивается один раз и не размазана по всей кодовой базе в виде кучи условной логики.
Ресурсы
Читайте серию
- Маршрутизация LLM (Этот пост)
- Безопасность и защитные механизмы
- Интеграции MCP и инструментов
- Рабочие процессы и память