中文翻译暂不可用,显示俄语原文。

Как проектировать cost-aware routing (дешёвая модель для простых запросов, дорогая — для сложных)?

Краткий тезис

routing|Cost-aware routing — это архитектурный паттерн в Agentic RAG, при котором система на основе лёгкого классификатора оценивает сложность пользовательского запроса и направляет его к модели с оптимальным соотношением цена-качество. Такой подход позволяет снизить затраты на инференс на 50–70% при минимальной потере точности (1–5%). Ключевые компоненты: классификатор сложности, пул моделей разного размера и фолбэк-механизм для перевызова на уровень выше при неудаче.


1. Термин: Cost-aware routing (роутинг с учётом стоимости)

routing|Cost-aware routing — это компонент системы, который перед вызовом LLM решает, какую модель использовать для данного запроса. Решение принимается на основе предсказанной сложности запроса, стоимости модели и требуемого качества. Цель — минимизировать среднюю стоимость одного запроса, сохраняя приемлемое качество ответа.

Основные метрики

  • Average cost per query (ACP) — средняя стоимость одного запроса после роутинга.
  • Quality degradation — падение метрик (точность, faithfulness, answer relevance) по сравнению с использованием только лучшей модели.
  • Cost saving — процент экономии относительно baseline (только дорогая модель).

2. Зачем нужен cost-aware routing

В реальных RAG-системах запросы сильно различаются:

  • Простые запросы (30–50% трафика): фактологические вопросы, извлечение информации из одного документа, суммаризация коротких текстов. Для них достаточно небольшой модели (8B параметров).
  • Сложные запросы (20–30%): multi-hop рассуждения, сравнение нескольких документов, аналитические вопросы. Требуют мощной модели (GPT-4, Claude 3.5).
  • Средние запросы (20–30%): запросы, требующие некоторого анализа, но не экстремально сложные.

Без роутинга вы платите максимальную цену за каждый запрос, хотя 60–70% из них могли бы быть обработаны дешёвой моделью. Cost-aware routing позволяет снизить затраты в 2–3 раза.


3. Архитектура: классификатор сложности

Основной компонент — легковесный текстовый классификатор, который присваивает запросу метку сложности (обычно 3–5 классов). Типичные реализации:

3.1. Классификатор на основе эмбеддингов + линейный слой

Используется предобученный энкодер (например, all-MiniLM-L6-v2) или BERT (tiny или base). Вектор запроса подаётся на softmax-классификатор с 3–5 классами.

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

model_name = "bert-tiny-finetuned-complexity"
tokenizer = AutoTokenizer.from_pretrained(model_name)
classifier = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=5)

def predict_complexity(query: str) -> int:
    inputs = tokenizer(query, return_tensors="pt", truncation=True, max_length=128)
    with torch.no_grad():
        logits = classifier(**inputs).logits
    return torch.argmax(logits).item()  # 0-4

3.2. Rule-based классификатор (без ML)

Простые эвристики: длина запроса, количество вопросительных слов, наличие специфических паттернов ("сравни", "объясни", "почему"). Может использоваться как fallback или для zero-shot старта.

3.3. LLM-as-Judge (гибридный)

Сначала пытается классифицировать быстрый эмбеддинг-классификатор, при низкой уверенности (confidence < 0.7) запрос направляется на крошечную модель (например, GPT-3.5-turbo-mini) для оценки сложности. Это дороже, но повышает точность роутинга.


4. Методы оценки сложности запроса

Для классификации используются следующие признаки:

ПризнакОписаниеПример простогоПример сложного
Длина запросаКоличество токенов10-2050-200
Количество сущностейИменованные сущности (NER)1-25+
Тип вопросаФактологический (who, what, where) vs аналитический (why, how, compare)"Сколько стоит?""Сравните эффективность методов"
Необходимость multi-hopТребуется объединить информацию из нескольких документовНетДа
Наличие таблиц/кодаЗапрос требует понимания структурированных данныхНетДа

Для обучения классификатора нужно размеченное множество: на 500–2000 запросах аннотаторы ставят метку сложности (1–5). Затем fine-tune BERT-tiny на этой разметке.


5. Стратегии роутинга: три уровня моделей

Типичная схема с тремя уровнями (аналогично multi-model orchestration):

УровеньМодели (пример)Стоимость за 1K токенов (вход/выход)Применение
Light (дешёвая)Llama-3-8B (Groq), GPT-3.5-turbo-mini, Mistral-7B$0.00005 - $0.0001Простые фактологические вопросы, суммаризация коротких документов
Medium (средняя)Mistral-8x22B, GPT-3.5-turbo, Claude-3-Haiku$0.001 - $0.002Средняя сложность, требующая небольшого анализа
Heavy (дорогая)GPT-4-turbo, Claude-3-Opus, Llama-3-405B (через API)$0.01 - $0.03Многошаговые рассуждения, глубокий анализ, запросы с кодом или таблицами

Выбор модели может быть гибким если запрос относится к классам 1-2 → Light, класс 3 → Medium, классы 4-5 → Heavy.


6. Фолбэк и обработка ошибок классификатора

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

  • Сгенерировать неточный ответ (hallucination)
  • Не справиться с multi-hop
  • Вернуть "I don't know"

Стратегии фолбэка

  1. Наивный: после ответа дешёвой модели запускается фильтр качества (например, confidence score выходного логита или небольшой LLM-as-Judge). Если качество ниже порога → перезапрос на модель уровнем выше.
  2. Прогрессивный: всегда сначала вызывается Light, если ответ признан неудовлетворительным → Medium, затем Heavy. Это гарантирует минимальную стоимость при максимальном качестве, но увеличивает latency.
  3. Direct fallback: если классификатор даёт класс 3, но уверенность < 0.8 → сразу Heavy (без Medium).
def route_with_fallback(query: str) -> str:
    complexity = predict_complexity(query)
    if complexity <= 2:
        answer = call_light_model(query)
        if quality_check(answer, query) > 0.8:  # произвольный порог
            return answer
        else:  # fallback на Medium
            return call_medium_model(query)
    elif complexity == 3:
        return call_medium_model(query)
    else:  # 4-5
        return call_heavy_model(query)

7. Метрики и эффект

Реальный эффект от внедрения cost-aware routing (данные из статей и практики):

  • Снижение затрат: 50–70% (в среднем -60%)
  • Падение качества: -2%..-5% (зависит от порога фолбэка)
  • Увеличение latency: +20% из-за классификатора и фолбэка (однако для простых запросов ответ приходит быстрее)

Таблица сравнения baseline vs routing

МетрикаBaseline (только GPT-4)Cost-aware routing
Average cost per query$0.02$0.008
Accuracy (на тестовом датасете)94%92%
P50 latency1.2 сек0.9 сек
P95 latency3.5 сек4.0 сек (из-за фолбэков)

8. Инструменты и библиотеки

  • Router LLM — открытая библиотека для построения мультимодельных роутеров (поддерживает классификаторы на основе эмбеддингов и rule-based).
  • LiteLLM Router — встроенный роутер в litellm с поддержкой fallback и cost-лимитов.
  • OpenAI Router (Assistants API) — позволяет задавать несколько моделей в одном Assistants, хотя управление сложностью ограничено.
  • LangChain / Haystack — имеют экспериментальные модули RouterChain или Agent с выбором инструмента, можно адаптировать под cost-aware.

9. Альтернативные подходы

  • Speculative decoding — ускоряет генерацию дорогой модели за счёт дешёвого драфтера, но не снижает cost (только latency).
  • Cascading — последовательный вызов моделей (сначала маленькая, потом большая при ошибке), похож на наш фолбэк, но без классификатора. Может быть медленнее.
  • Mixture of Agents (MoA) — несколько моделей голосуют, но стоимость выше.
  • Adaptive context — уменьшает количество токенов контекста для простых запросов, косвенно снижая cost.

10. Практические рекомендации

  1. Начните с лейблов — соберите 1000 запросов, вручную назначьте классы сложности.
  2. Используйте BERT-tiny — он достаточно быстрый (10-20 мс на классификацию) и точный.
  3. Храните кэш — для повторяющихся запросов можно кешировать ответ дешёвой модели.
  4. Мониторьте долю фолбэков — если >20% запросов уходят на Medium после Light, значит классификатор плохо обучен.
  5. A/B тестируйте — запускайте cost-aware routing на 10% трафика, сравнивайте с 100% Heavy моделью.

Пет-проект для закрепления

Задача: Реализовать cost-aware routing для RAG-системы на документах Wikipedia о животных (500 статей).

Инструменты: Python, Hugging Face (BERT-tiny, sentence-transformers), FastAPI, litellm (для вызова моделей).

Шаги:

  1. Сгенерировать 500 синтетических запросов с помощью GPT-4, разбить на 5 уровней сложности (по длине, типу, multi-hop).
  2. Разметить каждый запрос меткой сложности (1-5) через аннотатора (можно с помощью LLM).
  3. Обучить bert-tiny-finetuned-complexity на этой разметке (эпохи=5, lr=2e-5).
  4. Поднять FastAPI-сервис с эндпоинтом /classify.
  5. Создать роутер, который вызывает:
    • Groq (Llama-3-8B) для class 1-2,
    • GPT-3.5-turbo для class 3,
    • GPT-4-turbo для class 4-5.
  6. Добавить fallback: если ответ от Llama-3-8B имеет низкий confidence (средняя вероятность токенов < 0.6) → перезапрос на GPT-3.5-turbo.
  7. Замерить cost (счёт от API) и точность (сравнить с ответами только GPT-4) на 200 тестовых запросах.

Ожидаемый результат: экономия cost ~55% при падении accuracy не более 5%. Демо-приложение с визуализацией пути каждого запроса.


Связь с другими вопросами

ВопросТема
775Как проектировать routing в Agentic RAG
776Что такое dynamic routing и зачем он нужен
777Как балансировать между несколькими LLM в одной системе
779Как оценивать стоимость инференса LLM
780Как организовать fallback при отказе одной модели
781Как использовать LLM-as-Judge для контроля качества

Навигация