Реалізація маршрутизатора LLM запитів (мультипровайдерна маршрутизація)
LLM Router — проміжний шар, який маршрутизує запити до оптимального провайдера на основі характеристик запиту: складності, типу задачі, вимог до latency, вартості. Прості класифікації йдуть на GPT-4o-mini. Складна генерація коду йде на Claude Opus. Real-time чат йде на Groq. Це знижує вартість в 3–5 разів без втрати якості.
Архітектура маршрутизатора
from anthropic import Anthropic
from openai import OpenAI
from groq import Groq
from dataclasses import dataclass
from typing import Callable, Optional
@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] = [
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="Короткий простий запит за допомогою швидкого інфренсу",
),
RoutingRule(
name="code_generation",
condition=lambda text, meta: self._is_code_task(text),
provider="anthropic",
model="claude-sonnet-4-5",
reason="Задача з кодом Claude працює краще",
),
RoutingRule(
name="reasoning",
condition=lambda text, meta: self._is_reasoning_task(text),
provider="openai",
model="o3-mini",
reason="Задача міркування використання o3-mini",
),
RoutingRule(
name="default",
condition=lambda text, meta: True,
provider="openai",
model="gpt-4o",
reason="Стандартна маршрутизація",
),
]
def _is_code_task(self, text: str) -> bool:
code_keywords = [
"write code", "implement", "function", "class", "algorithm",
"python", "javascript", "sql", "refactor", "debug",
"напиши код", "реалізуй", "функція", "клас"
]
return any(kw in text.lower() for kw in code_keywords)
def _is_reasoning_task(self, text: str) -> bool:
reasoning_keywords = [
"prove", "calculate", "optimize", "find optimal",
"докажи", "вирахуй", "оптимізуй"
]
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]
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"Маршрутизатор {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)
Практичний кейс: SaaS платформа
Профіль запитів: 60% простих питань, 25% аналітики, 15% генерації коду.
Перед маршрутизацією: всі йдуть на GPT-4o = $450/місяць.
Після маршрутизації:
- Прості на Groq Llama 8B: $12/місяць
- Аналітика на GPT-4o-mini: $45/місяць
- Код на Claude Sonnet: $67/місяць
- Всього: $124/місяць (-72%)
Терміни
- Маршрутизатор на основі правил: 2–3 дні
- Семантичний маршрутизатор з ML: 1 тиждень
- Моніторинг та A/B тестування: 1 тиждень







