Блог AST-SoftPro
Почему привязка к одному LLM-провайдеру убивает ваш проект: архитектура универсальной системы маршрутизации
Когда одна модель становится точкой отказа
Каждый стартап с ИИ-функцией начинается одинаково: команда выбирает «лучшую» модель, подключает API, пишет код. Через несколько месяцев модель дорожает, меняет интерфейс, ограничивает запросы в минуту или просто перестаёт отвечать. И тогда оказывается, что вся архитектура приклеена к одному провайдеру — чтобы переключиться, нужно переписывать половину кода.
Проблема не в провайдере. Проблема в архитектуре.
Почему монопровайдер — это риск
Привязка к одному провайдеру создаёт уязвимости на всех уровнях:
-
Финансовая. Провайдер поднимает цены — ваша маржа сжимается. У вас нет альтернативы, потому что переключение стоит дороже, чем перенести стоимость на клиента.
-
Техническая. API меняется без предупреждения. Лимиты запросов пересчитываются. Модель обновляется и начинает отвечать иначе. Вы становитесь заложником чужого road map.
-
Операционная. Даунтайм провайдера означает даунтайм вашего сервиса. Даже 99.9% uptime — это 8.7 часов простоя в год.
-
Качественная. Одна модель не оптимальна для всех задач. Код, планирование, ответы на вопросы, генерация текста — каждая категория требует разных сильных сторон.
Принцип универсальности
Решение — абстрагировать вызов модели за единым интерфейсом. Вместо прямого вызова openai.ChatCompletion.create() ваш код работает с абстракцией «роутер», который решает, какую модель использовать.
Ключевые принципы:
Единый интерфейс вызова
Все провайдеры — OpenAI, DeepSeek, Gemini, локальные модели через LM Studio или Ollama — поддерживают OpenAI-совместимый REST API. Это значит, что ваш код вызывает один и тот же эндпоинт /chat/completions, меняя только URL, ключ и имя модели:
def call_llm(provider, messages, model=None):
url = f"{provider['url']}/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {provider['api_key']}",
}
payload = {
"model": model or provider["default_model"],
"messages": messages,
"temperature": 0.7,
}
response = requests.post(url, headers=headers, json=payload)
return response.json()
Разница между провайдерами — в конфигурации, а не в коде.
Реестр провайдеров
Все доступные провайдеры описываются в едином конфиге — JSON-файле, где для каждого провайдера указаны URL, API-ключ, доступные модели и рейтинги по категориям: код, написание текста, планирование, ответы на вопросы.
Такой реестр позволяет:
-
Видеть все доступные опции в одном месте;
-
Сравнивать модели по рейтингам;
-
Быстро добавлять нового провайдера без изменения кода;
-
Отключать недоступного провайдера одним действием.
Профили маршрутизации
Не все запросы одинаково важны. Система определяет профиль задачи и выбирает модель accordingly:
| Профиль | Назначение | Тип модели |
|---|---|---|
| Quality | Сложный код, архитектура | Самая мощная доступная модель |
| Balanced | Повседневные задачи | Баланс скорость/качество |
| Emergency | Fallback при сбоях | Самая быстрая доступная модель |
Профиль «quality» может использовать модель с рейтингом 9/9/8/7, а «emergency» — модель с рейтингом 6/5/5/7, которая отвечает в три раза быстрее. Пользователь не теряет функциональность — меняется только качество и скорость.
Fallback-цепочка
Когда основной провайдер недоступен, система не падает с ошибкой. Она переключается по заранее настроенной цепочке:
-
Текущий провайдер — попытка повторить запрос;
-
Альтернативная модель того же провайдера;
-
Локальный провайдер (LM Studio, Ollama, llama.cpp);
-
Облачный провайдер с самым низким тарифом;
-
Облачный провайдер premium.
Каждый шаг проверяет доступность (GET /v1/models) перед отправкой запроса. Если все провайдеры недоступны — только тогда возвращается ошибка.
Локальные модели как страховка
Локальные модели (GGUF через llama.cpp, LM Studio, Ollama) не зависят от интернета, тарифов и политик провайдеров. Они медленнее и требуют GPU, но обеспечивают независимость.
В гибридной архитектуре локальная модель — это не замена облачной, а страховка. Когда облако недоступно, локальная модель берёт на себя критические задачи. Когда локальная модель не справляется со сложным запросом — работа перенаправляется в облако.
Облачные против локальных: не выбор, а комбинация
Облачные провайдеры предлагают лучшие модели, но с рисками зависимости. Локальные модели дают независимость, но ограничены железом. Правильная архитектура использует оба подхода:
-
Облачные — для задач, где качество критично (сложный код, архитектурное планирование);
-
Локальные — для рутинных операций, быстрых ответов и fallback;
-
Маршрутизация — автоматически выбирает оптимальный вариант в зависимости от задачи и доступности.
Типичный стек включает 6+ облачных провайдеров (OpenAI, DeepSeek, Gemini, xAI Grok, OpenRouter, GitHub Models) и 4+ локальных инстанса (LM Studio с несколькими моделями, llama.cpp, Ollama).
Оценка моделей по категориям
Не все модели одинаково хороши во всём. Система рейтингов помогает выбрать правильную модель для конкретной задачи. Каждая модель оценивается по четырём параметрам:
-
Code — создание и рефакторинг кода;
-
Write — генерация текста и документации;
-
Plan — архитектурное планирование;
-
QA — ответы на вопросы и анализ.
Модель с рейтингом 10/10/10/8 идеальна для кода и планирования, но модель с рейтингом 8/8/8/9 может быть лучше для аналитики и вопросов — при этом в два раза быстрее и дешевле.
Что это даёт на практике
Команда, внедрившая универсальную систему маршрутизации с реестром из 13 провайдеров, столкнулась с ситуацией: основной провайдер поднял цены на 40% и снизил лимиты. Вместо паники и переписывания кода команда:
-
Перенесела 60% запросов на DeepSeek (дешевле, рейтинг 9/8/8/8);
-
Критические задачи оставила на OpenAI через GitHub Models;
-
Локальные модели взяли на себя рутинные операции и сканирование;
-
Общая стоимость снизилась на 25% при том же качестве.
Всё это заняло час настройки конфигурации — не неделю разработки.
Архитектура без единой точки отказа
Универсальная система маршрутизации LLM — это не «ещё одна библиотека». Это архитектурный паттерн, который делает ваш проект устойчивым к изменениям рынка.
Привязка к одному провайдеру — это технический долг, который вы накапливаете с каждым коммитом. Универсальность — это инвестиция в независимость. Когда провайдер меняет цены, обновляет модель или отключает доступ, ваша система адаптируется за минуты, а не за недели.
Ключевые выводы:
-
Абстрагируйте вызов модели за единым интерфейсом — OpenAI-совместимый API покрывает 95% провайдеров;
-
Ведите реестр провайдеров в отдельном конфиге — новый провайдер добавляется без изменения кода;
-
Используйте профили маршрутизации — разные задачи требуют разных моделей;
-
Настройте fallback-цепочку — даунтайм одного провайдера не должен останавливать сервис;
-
Держите локальные модели как страховку — независимость от интернета стоит VRAM, но окупается;
-
Оценивайте модели по категориям, а не по бенчмаркам — рейтинг по задачам точнее общих таблиц.
Архитектура, которая переживает смену провайдеров, — это архитектура, которая переживает всё.