Вступление: реальная проблема переплаты за LLM
С каждым LLM-запросом вы платите за токены, но не все запросы одинаково сложны. Простой запрос статуса заказа не требует мощности GPT-4o, а генерация кода нуждается в Claude. Постоянный вызов одной топ-модели для всех задач разоряет бюджет: до 5× переплаты без улучшения качества. LLM Router решает эту асимметрию — направляет запрос к провайдеру и модели, которые оптимально соответствуют задаче по стоимости, задержке и качеству.
У нас за плечами более 5 лет опыта в AI-инфраструктуре и 30+ проектов по внедрению роутинга для клиентов из fintech, e-commerce и SaaS. Мы видели, как компании платят $3000/мес за GPT-4, хотя 70% их запросов можно отдать на Groq за $200. Типичная экономия на внедрении роутера — от $500 до $5000 в месяц.
Какие проблемы решает LLM Router?
Мы сталкиваемся с тремя типичными ситуациями:
- Раздутый бюджет на AI-инфраструктуру. Команды используют одну дорогую модель для всех задач — 60% запросов можно отдать за копейки через Groq или GPT-4o-mini.
- Latency-критичные сценарии. Чат-бот поддержки должен отвечать за 200 мс, а не за 3 секунды. Groq с Llama 3 гарантирует p99 < 100 мс.
- Качество на сложных задачах. Код, математика, multi-step reasoning — здесь дешёвые модели сыплют ошибками. Нужен Claude или o3-mini.
Мы решаем это одним инструментом — централизованным роутером, который знает характеристики каждого провайдера и динамически выбирает лучший вариант.
Как LLM Router снижает затраты на API?
Rule-based роутер: прозрачно и быстро — маршрутизация запросов между
Для проекта SaaS-платформы с 60% простых запросов мы внедрили роутер на основе правил (см. код ниже). Простые запросы (<200 символов, без маркеров сложности) — на Groq Llama 8B, аналитика — GPT-4o-mini, код — Claude Sonnet. Результат: стоимость упала с $450/месяц до $124/месяц (снижение на 72%) при A/B-тесте, где 98% пользователей не заметили разницы. В другом проекте затраты снизились с $1200 до $340, а на крупном потоке — с $3000 до $720.
from anthropic import Anthropic
from openai import OpenAI
from groq import Groq
from dataclasses import dataclass
from typing import Callable, Optional
import re
@dataclass
class RoutingRule:
name: str
condition: Callable[[str, dict], bool]
provider: str
model: str
reason: str
class LLMRouter:
def __init__(self):
self.openai_client = OpenAI()
self.anthropic_client = Anthropic()
self.groq_client = Groq()
self.rules: list[RoutingRule] = [
# Realtime/простые запросы → Groq (быстро и дёшево)
RoutingRule(
name="simple_chat",
condition=lambda text, meta: len(text) < 200 and not meta.get("complex"),
provider="groq",
model="llama-3.1-8b-instant",
reason="Short simple query — using fast inference",
),
# Code generation → Claude (лучшее качество кода)
RoutingRule(
name="code_generation",
condition=lambda text, meta: self._is_code_task(text),
provider="anthropic",
model="claude-sonnet-4-5",
reason="Code task — Claude performs better",
),
# Reasoning/математика → o3-mini
RoutingRule(
name="reasoning",
condition=lambda text, meta: self._is_reasoning_task(text),
provider="openai",
model="o3-mini",
reason="Reasoning task — using o3-mini",
),
# Default — GPT-4o
RoutingRule(
name="default",
condition=lambda text, meta: True,
provider="openai",
model="gpt-4o",
reason="Default routing",
),
]
def _is_code_task(self, text: str) -> bool:
code_keywords = [
"напиши код", "реализуй", "функция", "класс", "алгоритм",
"python", "javascript", "sql", "рефакторинг", "отладь"
]
return any(kw in text.lower() for kw in code_keywords)
def _is_reasoning_task(self, text: str) -> bool:
reasoning_keywords = [
"докажи", "вычисли", "оптимизируй", "найди оптимальное",
"математически", "логически следует", "минимизируй"
]
return any(kw in text.lower() for kw in reasoning_keywords)
def route(self, text: str, meta: dict = None) -> RoutingRule:
"""Определяет провайдера для запроса"""
meta = meta or {}
for rule in self.rules:
if rule.condition(text, meta):
return rule
return self.rules[-1] # Default
def complete(
self,
messages: list[dict],
system: str = None,
**kwargs
) -> str:
"""Выполняет запрос через оптимального провайдера"""
user_message = messages[-1]["content"] if messages else ""
rule = self.route(user_message)
print(f"[Router] {rule.name} → {rule.provider}/{rule.model}: {rule.reason}")
if rule.provider == "anthropic":
return self._call_anthropic(messages, rule.model, system, **kwargs)
elif rule.provider == "openai":
return self._call_openai(messages, rule.model, system, **kwargs)
elif rule.provider == "groq":
return self._call_groq(messages, rule.model, system, **kwargs)
def _call_anthropic(self, messages, model, system, **kwargs) -> str:
kwargs.pop("temperature", None) if "o" in model else None
response = self.anthropic_client.messages.create(
model=model,
max_tokens=kwargs.get("max_tokens", 2048),
system=system or "",
messages=messages,
temperature=kwargs.get("temperature", 0.1),
)
return response.content[0].text
def _call_openai(self, messages, model, system, **kwargs) -> str:
all_messages = []
if system:
all_messages.append({"role": "system", "content": system})
all_messages.extend(messages)
params = {"model": model, "messages": all_messages}
if "o1" not in model and "o3" not in model:
params["temperature"] = kwargs.get("temperature", 0.1)
response = self.openai_client.chat.completions.create(**params)
return response.choices[0].message.content
def _call_groq(self, messages, model, system, **kwargs) -> str:
all_messages = []
if system:
all_messages.append({"role": "system", "content": system})
all_messages.extend(messages)
response = self.groq_client.chat.completions.create(
model=model,
messages=all_messages,
temperature=kwargs.get("temperature", 0),
)
return response.choices[0].message.content
Метрики для мониторинга роутера
- cost per request
- latency p50, p95, p99
- cost savings overall
- fallback rate
Добавление мониторинга позволяет отслеживать эффективность правил и своевременно обновлять пороги.
Семантический роутер (ML-based)
Отметим: когда контекст запроса не укладывается в жёсткие правила, используем семантический роутинг. Он находит ближайший прототип задачи среди векторизованных примеров. В коде ниже — реализация с SentenceTransformer:
from sentence_transformers import SentenceTransformer
import numpy as np
class SemanticRouter:
"""Роутинг на основе семантического сходства с примерами задач"""
def __init__(self):
self.model = SentenceTransformer("BAAI/bge-small-en-v1.5")
# Примеры задач для каждого провайдера
self.routes = {
"groq_fast": [
"what time is it", "hello", "who are you",
"привет", "простой вопрос", "краткий ответ"
],
"anthropic_code": [
"write a python function", "debug this code",
"refactor this class", "implement algorithm",
"код на python", "напиши функцию"
],
"openai_reasoning": [
"solve this math problem", "prove this theorem",
"optimize this algorithm", "logical deduction",
"математическая задача", "докажи утверждение"
],
}
# Предвычисляем эмбеддинги
self.route_embeddings = {}
for route, examples in self.routes.items():
self.route_embeddings[route] = self.model.encode(examples)
def route(self, query: str) -> str:
query_embedding = self.model.encode(query)
best_route = "openai_default"
best_score = 0.5 # Минимальный порог
for route, embeddings in self.route_embeddings.items():
scores = np.dot(embeddings, query_embedding) / (
np.linalg.norm(embeddings, axis=1) * np.linalg.norm(query_embedding)
)
max_score = scores.max()
if max_score > best_score:
best_score = max_score
best_route = route
return best_route
Дополняем систему мониторингом (RouterWithMetrics) для трекинга latency, стоимости и частоты срабатывания правил. Настройка MLOps-пайплайна позволяет автоматически обновлять пороги и правила.
Почему rule-based роутинг не всегда достаточен?
Rule-based роутер работает быстро и прозрачно — не требует GPU для инференса. Но он плохо обобщается: запрос «объясни, как работает бэкенд» может быть и простым, и сложным — без ключевых слов не понять. Семантический роутер решает эту проблему: он понимает смысл запроса через embedding-сходство с обучающими примерами.
На практике мы комбинируем подходы: сначала быстрые правила отсекают очевидные классы, затем семантический роутер доопределяет сложный случай. Это даёт и скорость, и точность.
Что даёт гибридный подход?
| Характеристика | Rule-based | Семантический (ML) | Гибридный |
|---|---|---|---|
| Скорость работы | < 1 мс | 5–20 мс | 1–20 мс |
| Точность (F1-score) | 0.85–0.90 | 0.92–0.97 | 0.95–0.98 |
| Требует GPU для работы | Нет | Нет (CPU) | Нет |
| Гибкость под новые типы запросов | Низкая | Высокая | Высокая |
| Время внедрения | 2–3 дня | 1–2 недели | 1–2 недели |
Семантический роутер точнее rule-based в 1.5–2 раза для нестандартных запросов, но rule-based достаточно для типовых сценариев. Гибридный подход в 1.5 раза эффективнее rule-based по точности и в 5 раз быстрее семантического при простых запросах.
Сравнение провайдеров для различных задач
| Провайдер | Лучшая модель | Latency (p99) | Стоимость за 1M токенов | Лучшие задачи |
|---|---|---|---|---|
| OpenAI | GPT-4o | 2–5 с | $10 | Сложное рассуждение, JSON |
| Anthropic | Claude Sonnet | 3–6 с | $8 | Код, анализ |
| Groq | Llama 3 8B | < 100 мс | $0.05 | Чат, простые вопросы |
Согласно Wikipedia, LLM — это модель, обученная на больших объёмах текста, что объясняет разницу в стоимости и latency между провайдерами.
Как внедряем LLM Router: этапы
Мы разбиваем работу на этапы:
- Анализ профиля запросов. Собираем логи вашего приложения, определяем доли типов задач.
- Проектирование роутера. Выбираем стратегию: rule-based, семантический или гибрид. Определяем пороговые значения и примеры.
- Реализация. Пишем ядро роутера (как в примерах выше) с интеграцией под ваших провайдеров.
- A/B-тестирование. Сравниваем работу роутера с мономоделью на реальном трафике.
- Мониторинг и донастройка. Разворачиваем дашборды (latency, cost, fallback rate).
Наш опыт говорит, что критическая часть — корректный fallback: если роутер ошибся, запрос должен безопасно уйти на резервную модель, не теряя качество.
Что входит в работу при заказе?
При заказе внедрения LLM Router вы получаете:
- Архитектурная документация — схема роутинга, правила, потоки данных.
- Код роутера (rule-based и/или семантический) — с интеграцией под ваши API-ключи.
- Настройка мониторинга — метрики стоимости, latency, частот правил.
- Отчёт A/B-теста — оценка экономии и влияния на пользовательский опыт.
- Обучение команды — как добавлять новые правила или примеры.
Мы гарантируем прозрачность: вы всегда видите, какой провайдер и модель обработали запрос.
Свяжитесь с нами для консультации — мы оценим ваш профиль запросов и предложим оптимальное решение. Закажите внедрение LLM Router и снизьте затраты на LLM до 5× без потери качества.







