- BrainTools - https://www.braintools.ru -
Если вы работаете с LLM-провайдерами, то наверняка сталкивались с одной и той же проблемой: у OpenAI лимит 100 RPM на ключ, у Vertex AI — свои квоты на проект, у Anthropic — отдельные ограничения. В итоге приходится держать несколько ключей, балансировать нагрузку вручную, следить, чтобы один заблокированный доступ не уронил всё приложение, и при этом хочется сохранить единый OpenAI-совсместимый эндпоинт для клиентского кода.
Именно для этого и создан Auto AI Router — лёгкий прокси-роутер на Go, который принимает запросы в формате OpenAI API и прозрачно распределяет их между несколькими провайдерами и ключами с балансировкой нагрузки, защитой от банов и контролем RPM-лимитов.
Репозиторий [1]
Документация: auto_ai_router [2]
LiteLLM — отличный инструмент, но он написан на Python и несёт весь соответствующий груз: интерпретатор, GIL, потребление памяти [3] 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-формат.
Один endpoint может обслуживать несколько провайдеров:
OpenAI
Vertex AI
Anthropic
Gemini AI Studio
Amazon Bedrock
Proxy — отправка запроса в другой Auto AI Router
Клиент продолжает работать через OpenAI SDK, а роутер берёт на себя маршрутизацию и конвертацию.
Если у одной и той же модели несколько ключей, нагрузка распределяется автоматически:
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: 100
models:
- 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 при пропуске ключей. Если креды временно забанен или упираются в лимит, роутер не “залипает” на первом доступном, а сохраняет честное чередование между оставшимися.
Каждый доступ отслеживается отдельно. Если по нему начинает расти число ошибок, он временно или навсегда исключается из ротации.
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.
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.
Важно, что привязка записывается только после успешного завершения запроса. Если запрос завершился ошибкой [4], sticky-связка не фиксируется, и следующий запрос снова пойдёт через обычный выбор доступного ключа.
Лимиты задаются сразу на двух уровнях:
Per-credential — RPM и TPM для конкретного ключа;
Per-model — RPM и TPM для конкретной модели.
credentials:
- name: openai_main
rpm: 200
tpm: 100000
models:
- name: gpt-4o
credential: openai_main
rpm: 100
tpm: 50000
Если превышается любой из лимитов, ключ временно пропускается и роутер пытается использовать следующий.
Это позволяет гибко настраивать поведение [5]: например, ограничивать конкретную модель сильнее, чем весь ключ целиком.
Благодаря логике [6] Ai-router проекты способы держать нагрузку до нескольких десятков миллионов TPM без ошибок или необходимости поиска дорогостоящих энтерпрайз-решений от провайдеров.
На одной инстанции локальных счётчиков достаточно. Но при горизонтальном масштабировании появляются проблемы: каждая реплика видит только свою часть трафика, и лимиты перестают быть глобальными.
С 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-гонок.
Можно настроить 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 секунд.
Для 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-совместимый клиентский интерфейс поверх разных провайдеров без переписывания интеграции.
Роутер поддерживает и 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",
)
Если у вас уже развёрнут 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 run -p 8080:8080
-v $(pwd)/config.yaml:/app/config.yaml
ghcr.io/mixaill76/auto_ai_router:latest
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: 50000
models:
- name: gpt-4o
credential: openai_main
from openai import OpenAI
client = 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: Bearer header
Дополнительно: валидация по токенам 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 [1]
Документация: auto_ai_router [2]
Автор: MiXaiLL76
Источник [7]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/29374
URLs in this post:
[1] Репозиторий: https://github.com/MiXaiLL76/auto_ai_router
[2] auto_ai_router: https://mixaill76.github.io/auto_ai_router/
[3] памяти: http://www.braintools.ru/article/4140
[4] ошибкой: http://www.braintools.ru/article/4192
[5] поведение: http://www.braintools.ru/article/9372
[6] логике: http://www.braintools.ru/article/7640
[7] Источник: https://habr.com/ru/articles/1027878/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1027878
Нажмите здесь для печати.