Если вы работаете с LLM-провайдерами, то наверняка сталкивались с одной и той же проблемой: у OpenAI лимит 100 RPM на ключ, у Vertex AI — свои квоты на проект, у Anthropic — отдельные ограничения. В итоге приходится держать несколько ключей, балансировать нагрузку вручную, следить, чтобы один заблокированный доступ не уронил всё приложение, и при этом хочется сохранить единый OpenAI-совсместимый эндпоинт для клиентского кода.
Именно для этого и создан Auto AI Router — лёгкий прокси-роутер на Go, который принимает запросы в формате OpenAI API и прозрачно распределяет их между несколькими провайдерами и ключами с балансировкой нагрузки, защитой от банов и контролем RPM-лимитов.
Документация: auto_ai_router
Зачем ещё один роутер? Почему не LiteLLM?
LiteLLM — отличный инструмент, но он написан на Python и несёт весь соответствующий груз: интерпретатор, GIL, потребление памяти 200–500 МБ даже в простой конфигурации. Для высоконагруженного прокси, где каждые несколько миллисекунд задержки на маршрутизацию имеют значение, это не идеал.
Auto AI Router написан на Go и компилируется в единый статический бинарник. Типичное потребление RAM — десятки мегабайт, старт — меньше секунды. Это делает его удобным для деплоя в сайдкар-контейнерах или на ресурсоограниченных узлах.
Принципиальные отличия:
|
Аспект |
LiteLLM |
Auto AI Router |
|---|---|---|
|
Язык |
Python |
Go |
|
Бинарник |
нет (pip/docker) |
один статический бинарник / docker |
|
Потребление RAM |
200–500 МБ |
~30–80 МБ |
|
Round-robin балансировка |
есть |
есть, исправлен классический баг распределения |
|
Session-sticky routing |
нет |
есть (по |
|
Fail2ban per credential |
нет |
есть (настраиваемые правила по HTTP-кодам) |
|
LiteLLM DB совместимость |
нативная |
интеграция с БД LiteLLM (PostgreSQL) |
|
Режим прокси-цепочки |
нет (есть кривая fallback система) |
есть (proxy-credential → другой роутер) |
|
Redis для rate limiting |
нет |
есть (глобальные счётчики для кластера) |
Важный момент: Auto AI Router не заменяет LiteLLM полностью — он не управляет виртуальными ключами, моделями и пользователями через UI. Его задача уже и конкретнее: быть максимально быстрым и надёжным прокси-слоем между вашими приложениями и LLM-провайдерами.
Архитектура
Роутер принимает все запросы в формате OpenAI Chat Completions и конвертирует их в нативный формат нужного провайдера. Для Vertex AI — это Google GenAI SDK, для Anthropic — Messages API, и т.д. Ответы конвертируются обратно в OpenAI-формат.
Основные возможности
1. Multi-provider routing
Один endpoint может обслуживать несколько провайдеров:
-
OpenAI
-
Vertex AI
-
Anthropic
-
Gemini AI Studio
-
Amazon Bedrock
-
Proxy — отправка запроса в другой Auto AI Router
Клиент продолжает работать через OpenAI SDK, а роутер берёт на себя маршрутизацию и конвертацию.
2. Round-robin балансировка между credentials
Если у одной и той же модели несколько ключей, нагрузка распределяется автоматически:
credentials: - name: vertex_cred_1 type: vertex-ai project_id: project-a credentials_file: sa-a.json rpm: 100 - name: vertex_cred_2 type: vertex-ai project_id: project-b credentials_file: sa-b.json rpm: 100models: - name: gemini-2.5-flash credential: vertex_cred_1 - name: gemini-2.5-flash credential: vertex_cred_2
В этом примере gemini-2.5-flash получает уже не 100 RPM, а 200 RPM суммарно. Запросы будут чередоваться между vertex_cred_1 и vertex_cred_2.
Отдельный момент — корректная реализация round-robin при пропуске ключей. Если креды временно забанен или упираются в лимит, роутер не “залипает” на первом доступном, а сохраняет честное чередование между оставшимися.
3. Fail2ban для credentials
Каждый доступ отслеживается отдельно. Если по нему начинает расти число ошибок, он временно или навсегда исключается из ротации.
fail2ban: max_attempts: 3 ban_duration: permanent error_codes: [401, 403, 429, 500, 502, 503, 504] error_code_rules: - code: 429 max_attempts: 5 ban_duration: 5m
Например:
-
429— временный бан на 5 минут; -
401или403— повод навсегда убрать credential из ротации; -
5xx— можно трактовать как временную деградацию upstream.
За счёт этого один проблемный ключ не ломает всю систему.
Пример отслеживания блокировок ключей, фактически роутер позволяет экспериментировать с различными источниками, не переживая за стабильность, ввиду системы Fail2ban.
4. Session-sticky routing
WIP — находится на стадии клиентского тестирования
Это одна из самых полезных функций в сценариях с длинными контекстами. Многие провайдеры поддерживают кэширование запросов: если следующий запрос в рамках одной сессии приходит на тот же ключ, часть токенов может не тарифицироваться повторно.
Проблема в том, что обычный round-robin разрушает такую привязку.
Решение — session-sticky routing. Роутер запоминает, какой кред уже обслуживал конкретную сессию, и направляет следующие запросы туда же.
response = client.chat.completions.create( model="gemini-2.5-flash", messages=[...], user="conversation-id-123",)
Достаточно передать стабильный идентификатор сессии, например через user.
|
Сценарий |
Без sticky |
С sticky |
|---|---|---|
|
Запрос 1 (10 000 токенов) |
cred_A, полная стоимость |
cred_A, полная стоимость |
|
Запрос 2 (10 200 токенов) |
cred_B, полная стоимость |
cred_A, 200 новых токенов |
|
Запрос 3 (10 400 токенов) |
cred_A, полная стоимость |
cred_A, 200 новых токенов |
Для длинных контекстов экономия достигает 80–90%.
Источники session_id поддерживаются по приоритету: extra_body.litellm_session_id, extra_body.chat_id, extra_body.session_id, session_id, user, safety_identifier, prompt_cache_key.
Важно, что привязка записывается только после успешного завершения запроса. Если запрос завершился ошибкой, sticky-связка не фиксируется, и следующий запрос снова пойдёт через обычный выбор доступного ключа.
5. Двухуровневый rate limiting
Лимиты задаются сразу на двух уровнях:
-
Per-credential — RPM и TPM для конкретного ключа;
-
Per-model — RPM и TPM для конкретной модели.
credentials: - name: openai_main rpm: 200 tpm: 100000models: - name: gpt-4o credential: openai_main rpm: 100 tpm: 50000
Если превышается любой из лимитов, ключ временно пропускается и роутер пытается использовать следующий.
Это позволяет гибко настраивать поведение: например, ограничивать конкретную модель сильнее, чем весь ключ целиком.
Благодаря логике Ai-router проекты способы держать нагрузку до нескольких десятков миллионов TPM без ошибок или необходимости поиска дорогостоящих энтерпрайз-решений от провайдеров.
6. Redis для распределённого rate limiting
На одной инстанции локальных счётчиков достаточно. Но при горизонтальном масштабировании появляются проблемы: каждая реплика видит только свою часть трафика, и лимиты перестают быть глобальными.
С Redis лимиты становятся глобальными — все реплики делят единый счётчик:
redis: enabled: true addresses: - "valkey:6379" force_single_client: true
Реализовано через Lua-скрипты на стороне Redis: sliding window в sorted set, атомарная проверка всех 4 счётчиков (credential RPM + credential TPM + model RPM + model TPM) в одном вызове без TOCTOU-гонок.
7. Proxy chains
Можно настроить fallback на другой Auto AI Router:
credentials: - name: proxy_backup type: proxy base_url: http://backup-router.internal:8080 api_key: sk-remote-master-key is_fallback: true
При недоступности всех primary-кредентиалов трафик автоматически уходит на резервный роутер. Статистика с удалённого /health синхронизируется каждые 30 секунд.
8. Поддержка Vertex AI, Anthropic и других провайдеров
Для OpenAI запросы идут почти напрямую. Для остальных провайдеров роутер берёт на себя адаптацию OpenAI-совместимого формата к нативному API. Например, для Vertex AI он поддерживает мультимодальность, streaming через SSE, tools, structured output на основе JSON Schema, thinking/reasoning для Gemini, генерацию изображений и маппинг reasoning_effort из OpenAI- и Anthropic-форматов.
# Чтобы включить thinking на Gemini 2.5 Flash,# достаточно передать стандартный параметрresponse = client.chat.completions.create( model="gemini-2.5-flash", messages=[...], reasoning_effort="high",)
Это позволяет использовать один и тот же OpenAI-совместимый клиентский интерфейс поверх разных провайдеров без переписывания интеграции.
9. Responses API
Роутер поддерживает и OpenAI Responses API на endpoint /v1/responses:
-
конвертирует
inputвmessagesи обратно; (для моделей, у которых нет официальной поддержки Responses API) -
поддерживает multi-turn через
previous_response_id; -
хранит историю в
bboltили Redis; -
может использовать сохранённый credential для продолжения той же цепочки запросов.
r1 = client.responses.create( model="gpt-4o", input="Привет! Я работаю над проектом на Go.", store=True, user="conv-123",)r2 = client.responses.create( model="gpt-4o", input="Расскажи о горутинах.", previous_response_id=r1.id, store=True, user="conv-123",)
10. Интеграция с LiteLLM DB
Если у вас уже развёрнут LiteLLM с PostgreSQL — роутер может:
-
Валидировать API-ключи через таблицу
LiteLLM_VerificationToken -
Логировать расходы в
LiteLLM_SpendLogsс батчевой записью -
Агрегировать дневные расходы по пользователям, командам
litellm_db: enabled: true database_url: "os.environ/LITELLM_DATABASE_URL" log_batch_size: 100 log_flush_interval: 5s
Это позволяет использовать Auto AI Router как высокопроизводительный прокси-слой поверх существующей LiteLLM-инфраструктуры, не мигрируя всю систему.
Мониторинг
Роутер предоставляет несколько способов наблюдения за состоянием системы:
-
/health— JSON со статусом credentials, моделей и удалённых proxy; -
/vhealth— HTML-страница для быстрого визуального осмотра; -
/metrics— Prometheus-метрики.
monitoring: prometheus_enabled: true
Пример Grafana-дашборда можно построить на метриках:
-
auto_ai_router_credential_rpm_current— загрузка креда -
auto_ai_router_credential_banned— 1 = кред забанен -
auto_ai_router_requests_duration_seconds— распределение задержки (latency distribution)
Быстрый старт
Docker
docker run -p 8080:8080 \ -v $(pwd)/config.yaml:/app/config.yaml \ ghcr.io/mixaill76/auto_ai_router:latest
Минимальный config.yaml
server: port: 8080 master_key: "sk-your-master-key"credentials: - name: openai_main type: openai api_key: "os.environ/OPENAI_API_KEY" base_url: "https://api.openai.com" rpm: 100 tpm: 50000models: - name: gpt-4o credential: openai_main
Запрос через OpenAI SDK
from openai import OpenAIclient = OpenAI( base_url="http://localhost:8080/v1", api_key="sk-your-master-key",)response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Hello!"}],)
Для клиентского кода меняются только base_url и api_key.
Безопасность
Безопасность — ещё один важный аргумент в пользу Auto AI Router. Для прокси-слоя, через который проходят ключи, лимиты и маршрутизация запросов, безопасность — базовое требование. У Auto AI Router здесь есть понятное преимущество: это более узкий и простой по устройству инструмент, чем крупные универсальные решения. А значит, его легче проверять, изолировать внутри инфраструктуры, ограничивать сетевой доступ и использовать строго по назначению — как слой маршрутизации ключей и запросов, без лишних интерфейсов и дополнительной логики.
На этом фоне показателен недавний инцидент вокруг LiteLLM, а также другие случаи, связанные с раскрытием чувствительных данных через эндпоинты и логи. Это не означает, что большие инструменты “плохие”, но хорошо показывает общий принцип: чем уже зона ответственности компонента, тем проще сделать его безопасным и держать под контролем.
-
Секреты в конфиге через
os.environ/VAR_NAME— ключи не хранятся в файлах -
Аутентификация по master key через
Authorization: Bearerheader -
Дополнительно: валидация по токенам LiteLLM DB
-
/health,/vhealth,/metrics— без аутентификации (для мониторинга)
Итоги
Auto AI Router решает прикладную задачу: принять OpenAI-совместимый запрос и надёжно доставить его до нужного LLM-провайдера, даже если у вас несколько ключей, несколько поставщиков и разные ограничения по rate limit.
Он особенно полезен, если:
-
у вас несколько доступов для одного или нескольких LLM-провайдеров;
-
нужен единый OpenAI-совместимый эндпоинт без переписывания клиентского кода;
-
важны отказоустойчивость и автоматическое исключение проблемных ключей;
-
хочется использовать кэширование запросов эффективнее за счёт session-sticky routing;
-
уже есть LiteLLM DB, но нужен более лёгкий и быстрый прокси-слой.
При этом Auto AI Router не пытается заменить LiteLLM как систему управления доступом, моделями и пользователями. Это более узкий инструмент: быстрый маршрутизатор и прокси для LLM API.
Репозиторий: github.com/MiXaiLL76/auto_ai_router
Документация: auto_ai_router
ссылка на оригинал статьи https://habr.com/ru/articles/1027878/