LiteLLM: прокси и роутер LLM для команды. Гайд

Автор: Обновлено

Что такое LiteLLM?

LiteLLM - открытая (MIT) Python-библиотека и прокси-сервер (AI Gateway), которые приводят вызовы 100+ LLM-провайдеров к формату OpenAI. SDK подключают в код одного приложения, Proxy поднимают как общий шлюз для команды: с виртуальными ключами, бюджетами, fallback между моделями и централизованными логами.

TL;DR

  • -У LiteLLM две роли. Python SDK (litellm.completion и Router) встраивают в одно приложение. Proxy поднимают отдельным сервером на порту 4000, и любой клиент OpenAI-формата подключается к нему сменой base_url.
  • -Модели описываются в config.yaml, в секции model_list: model_name - имя для клиента, litellm_params - реальный провайдер и модель. Несколько записей с одним model_name образуют группу с балансировкой, fallbacks задают запасную модель.
  • -Virtual keys, бюджеты, команды и Admin UI работают только с Postgres. Без базы прокси принимает лишь master key, а бюджеты не применяются. Redis нужен, когда инстансов или воркеров больше одного.
  • -Ядро под MIT, каталог enterprise/ под отдельной лицензией. SSO больше чем на 5 пользователей, JWT-аутентификация, audit logs, бюджеты по моделям на ключ и часть guardrails требуют Enterprise-ключа.
  • -Прокси хранит ключи всех провайдеров. В 2026 году у LiteLLM были критичные CVE в аутентификации и management-эндпоинтах и компрометация PyPI-релизов 1.82.7 и 1.82.8, поэтому версию фиксируют, а прокси не выставляют в интернет.

LiteLLM - открытая (MIT) Python-библиотека и прокси-сервер, которые приводят вызовы 100+ LLM-провайдеров к формату OpenAI. Python SDK подключают в код одного приложения. Proxy (в документации AI Gateway) поднимают как общий шлюз для команды: виртуальные ключи на сотрудника, бюджеты, fallback между моделями, логи в одном месте. У репозитория BerriAI/litellm около 62 тысяч звёзд, последний stable-релиз на 2 ноября 2026 года - 1.106.6 от 28 октября.

Первый config.yaml укладывается в два десятка строк. Сложности начинаются, когда прокси отдают команде: виртуальные ключи и бюджеты молча не работают без Postgres, часть функций из документации требует Enterprise-лицензии, а сам прокси хранит ключи всех провайдеров. За 2026 год у LiteLLM вышло больше десятка CVE с оценкой High и Critical, а в марте на PyPI на 40 минут попали два релиза с вредоносным кодом.

Статья о том, как поднять LiteLLM Proxy, описать модели в config.yaml, настроить fallback с локальной модели на облачную, выдать ключи с бюджетами, подключить OpenAI SDK, Claude Code и OpenCode и как эксплуатировать прокси с учётом его истории уязвимостей. Fallback, накладные расходы прокси, авторизация без базы и Anthropic-формат проверены на LiteLLM 1.108.1 (вышла 5 ноября) с Ollama 0.40.14 на Mac с Apple M4 Max. Docker, Postgres, Redis, Admin UI и Enterprise-функции описаны по документации.

Что такое LiteLLM и когда он нужен

Запрос «litellm» объединяет два продукта с разными задачами.

LiteLLM SDKLiteLLM Proxy
Что этоPython-библиотекаОтдельный HTTP-сервер, порт 4000
КлиентыКод на PythonЛюбой язык, OpenAI SDK, агенты, curl
Функцииcompletion() для 100+ провайдеров, Router с ретраями и fallback, стоимость ответа, callbacksВсё из SDK плюс virtual keys, бюджеты, rate limits, учёт расходов, Admin UI, кэш, guardrails, MCP Gateway
ХранилищеНе нужноPostgres для ключей и бюджетов, Redis для нескольких инстансов
КомуОдному приложениюКоманде, нескольким сервисам, агентам

Выбор по ситуации:

СитуацияЧто брать
Одно Python-приложение, два-три провайдераSDK
Один разработчик, одна модельНи то, ни другое: хватит SDK провайдера
Несколько сервисов на разных языках ходят к LLMProxy
Нужны ключи на сотрудника, лимиты и отчёт по расходамProxy + Postgres
Локальная модель с запасной облачнойSDK Router или Proxy
Нет желания администрировать серверОблачный агрегатор, например OpenRouter

Где self-hosted proxy стоит в общей архитектуре провайдеров рядом с адаптерами в коде и managed-шлюзами, разобрано в статье о провайдерах LLM в production.

Чем LiteLLM отличается от OpenRouter и Portkey

LiteLLMOpenRouterPortkey Gateway
МодельSelf-hosted SDK и Proxy, MIT + каталог enterprise/SaaS, единый API и счётOpen-source шлюз (MIT, ~13 тысяч звёзд) плюс облачный Portkey
Ключи провайдеровВаши, лежат на вашем сервереКлюч OpenRouter или свои (BYOK)Ваши
ДеньгиСофт бесплатный, платите за инфраструктуру; Enterprise по запросуКомиссия платформы 5,5% (Standard), 8% (Business); BYOK без комиссии до $25 000 в месяц по прайсу, дальше 5%Условия на сайте Portkey
ДанныеЧерез ваш хостЧерез серверы OpenRouterЧерез ваш хост (open-source версия)

Цены OpenRouter взяты со страницы pricing в начале ноября 2026. Подробно облачный вариант разобран в гайде по OpenRouter. Схемы совмещаются: OpenRouter подключается к LiteLLM как ещё один провайдер.

Быстрый старт LiteLLM Proxy

Установка по quick start:

uv tool install 'litellm[proxy]==1.106.6'
# или
pip install 'litellm[proxy]==1.106.6'

С версии 1.84.0 LiteLLM требует Python 3.10 или новее, верхняя граница на PyPI <3.15. uv tool install сам подберёт подходящий интерпретатор. Голый pip на старом Python, по документации, молча поставит последнюю совместимую старую версию. Если системный Python 3.15 или новее, версию интерпретатора для uv задают явно, разовый запуск выглядит так:

uvx --python 3.12 --from 'litellm[proxy]==1.106.6' litellm --config config.yaml --host 127.0.0.1 --port 4000

Версию лучше указывать сразу. Релизы выходят несколько раз в неделю, исправления выпускают сразу для нескольких минорных линий, а версии 1.82.7 и 1.82.8 были вредоносными (подробности в разделе о безопасности).

Минимальный config.yaml с локальной и облачной моделью:

model_list:
  - model_name: local-qwen
    litellm_params:
      model: ollama_chat/qwen3:8b
      api_base: http://127.0.0.1:11434
  - model_name: cloud-sonnet
    litellm_params:
      model: anthropic/claude-sonnet-5-5
      api_key: os.environ/ANTHROPIC_API_KEY

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY   # должен начинаться с sk-

Первый запрос:

curl http://127.0.0.1:4000/v1/chat/completions \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "local-qwen", "messages": [{"role": "user", "content": "ping"}]}'

Клиент OpenAI SDK меняет только адрес и ключ:

from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:4000", api_key="sk-...")  # master или virtual key
resp = client.chat.completions.create(
    model="cloud-sonnet",  # model_name из config.yaml
    messages=[{"role": "user", "content": "ping"}],
)
print(resp.choices[0].message.content)

Клиент видит только model_name. Какой провайдер стоит за алиасом, решает конфиг, и модель меняют без правки кода приложений.

SDK: LiteLLM без сервера

Если шлюз не нужен, тот же вызов делается библиотекой:

from litellm import completion

resp = completion(
    model="ollama_chat/qwen3:8b",
    api_base="http://127.0.0.1:11434",
    messages=[{"role": "user", "content": "ping"}],
)
print(resp.choices[0].message.content)

Для балансировки и fallback в SDK есть класс Router с тем же форматом model_list, что и в конфиге прокси.

config.yaml: модели, роутинг, секреты

В config.yaml пять секций:

СекцияЧто в ней
model_listМодели: model_name (алиас для клиента), litellm_params (провайдер, модель, api_base, api_key, rpm, tpm), опционально model_info
router_settingsСтратегия роутинга, ретраи, cooldown, fallbacks
litellm_settingsПоведение библиотеки: fallbacks, таймауты, кэш, callbacks, глобальный бюджет
general_settingsMaster key, база данных, параметры сервера
environment_variablesПеременные окружения прямо в конфиге

Секреты не пишут в файл открытым текстом. Запись os.environ/ИМЯ прокси читает из окружения при старте.

Несколько записей с одинаковым model_name образуют группу, и прокси распределяет запросы между ними:

model_list:
  - model_name: fast
    litellm_params:
      model: anthropic/claude-haiku-5-5
      api_key: os.environ/ANTHROPIC_API_KEY
      rpm: 500
  - model_name: fast
    litellm_params:
      model: openai/<модель GPT-6>
      api_key: os.environ/OPENAI_API_KEY
      rpm: 300

router_settings:
  routing_strategy: simple-shuffle

Стратегии по документации роутинга:

СтратегияКак выбирает
simple-shuffleПо умолчанию, рекомендована для production; выбирает с учётом rpm/tpm или weight, без них случайно
least-busyДеплой с наименьшим числом запросов в работе
latency-based-routingСамый быстрый по недавним замерам
usage-based-routing-v2По текущему расходу rpm/tpm через Redis; документация не советует её для production
cost-based-routingСамый дешёвый деплой

Имена моделей в примерах документации LiteLLM меняются вместе с релизами провайдеров и не всегда совпадают с актуальными ID. Реальный идентификатор берут из документации провайдера: у Anthropic на ноябрь 2026 это claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5.

Ollama за прокси

LiteLLM поддерживает два префикса для Ollama. ollama_chat/ отправляет запросы в /api/chat, его рекомендует документация. ollama/ идёт в /api/generate. api_base указывает на сервер Ollama, по умолчанию http://localhost:11434.

  - model_name: local-qwen
    litellm_params:
      model: ollama_chat/qwen3:8b
      api_base: http://127.0.0.1:11434
      keep_alive: 30m
    model_info:
      supports_function_calling: true

supports_function_calling нужен, когда модель умеет нативные tool calls, а LiteLLM этого не определил: иначе он эмулирует вызовы инструментов через JSON-режим. Какие модели Ollama действительно справляются с инструментами и почему агенту нужен контекст от 64k, разобрано в гайде по Ollama. Выбор между Ollama и LM Studio как локальным бэкендом - в отдельном сравнении.

Fallback, ретраи и таймауты

Fallback - запасная модель, на которую прокси переключает запрос после ошибки основной. Параметры по документации reliability:

ПараметрЧто делает
fallbacks: [{"a": ["b", "c"]}]При ошибке группы a пробует b, затем c
context_window_fallbacksПереключение при превышении контекста; для проверки до отправки нужен router_settings.enable_pre_call_checks: true
content_policy_fallbacksПереключение, когда провайдер отказал по контент-политике
default_fallbacksЗапасные модели для всех групп без своего правила
num_retriesПовторы на той же группе до перехода к fallback
request_timeoutТаймаут запроса, секунды
allowed_fails, cooldown_timeСколько ошибок допустимо, прежде чем деплой уйдёт в cooldown, и на сколько

Документация показывает fallbacks в litellm_settings. Ключ принимается и в router_settings, так он и настроен в проверке ниже. Отключить fallback для одного запроса можно полем "disable_fallbacks": true в теле.

Сценарий «локальная модель упала, отвечает облако»:

model_list:
  - model_name: local-qwen
    litellm_params:
      model: ollama_chat/qwen3:8b
      api_base: http://127.0.0.1:11434
  - model_name: cloud-deepseek
    litellm_params:
      model: deepseek/deepseek-flash
      api_key: os.environ/DEEPSEEK_API_KEY

router_settings:
  num_retries: 0
  fallbacks:
    - local-qwen: ["cloud-deepseek"]

Проверено: 7 ноября 2026 года, LiteLLM 1.108.1 через uvx --python 3.12, без Docker и Postgres, Ollama 0.40.14 с qwen3:8b, резервная модель DeepSeek deepseek-flash. Падение Ollama имитировала отдельная группа с api_base на закрытый порт, это та же ошибка соединения. Запрос к ней вернул ответ облачной модели, в заголовках ответа: x-litellm-model-group: cloud-deepseek, x-litellm-attempted-fallbacks: 1, x-litellm-attempted-retries: 0, x-litellm-response-duration-ms: 1280.09, x-litellm-overhead-duration-ms: 234.18.

По этим заголовкам видно, что ответ пришёл с запасной модели. Если их не логировать, приложение получит обычный ответ и не узнает, что основная модель лежит.

В той же проверке всплыла деталь про резервную модель. deepseek-flash - рассуждающая модель, и при max_tokens: 200 все 200 токенов ушли в reasoning_tokens, а текст ответа оказался пустым. У запасной модели в цепочке должен быть запас по max_tokens, либо в fallback ставят модель без рассуждений.

Как проектировать роутинг и деградацию на уровне всего стека, а не одного прокси, описано в статье Production LLM Stack.

Накладные расходы прокси

Прокси добавляет ещё один сетевой хоп. Насколько это заметно, проверялось на локальной модели, где сеть до провайдера не маскирует задержку самого LiteLLM.

Проверено: 7 ноября 2026 года, LiteLLM 1.108.1, Ollama 0.40.14, прогретая qwen3:8b, запросы с max_tokens: 1. 15 запросов на каждый путь, первые 3 отброшены, n=12.

ПутьМедиана, мсp90, мс
Напрямую в Ollama (/v1/chat/completions)19,519,7
Через LiteLLM Proxy26,826,9

Разница около 7 мс на запрос. Заголовок x-litellm-overhead-duration-ms в трёх отдельных запросах показал 7,13, 6,77 и 5,59 мс. Первый запрос после старта прокси медленнее: в fallback-запросе выше overhead 234 мс, и туда входит переключение на запасную модель. Для облачных моделей, где ответ занимает секунды, 7 мс теряются в шуме. Под параллельной нагрузкой замер не делался.

Virtual keys, бюджеты и лимиты

Virtual key - ключ вида sk-..., который прокси выдаёт сотруднику, сервису или агенту вместо ключа провайдера. Для них нужны две вещи (virtual keys): Postgres в DATABASE_URL и master key, начинающийся с sk-.

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  database_url: os.environ/DATABASE_URL

Ключ с доступом к одной группе моделей, бюджетом $10 на 30 дней и лимитом 60 запросов в минуту:

curl http://127.0.0.1:4000/key/generate \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"models": ["cloud-sonnet"], "max_budget": 10, "budget_duration": "30d",
       "rpm_limit": 60, "metadata": {"owner": "dev-1"}}'

Команда с общим бюджетом создаётся через /team/new, ключ привязывается к ней полем team_id:

curl http://127.0.0.1:4000/team/new \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"team_alias": "backend", "max_budget": 100, "budget_duration": "30d"}'

Уровни бюджетов по документации:

УровеньКак задаётся
Ключ/key/generate: max_budget, budget_duration, rpm_limit, tpm_limit, max_parallel_requests
Пользователь/user/new
Команда/team/new
Участник команды/team/member_add с max_budget_in_team
Внешний клиент/budget/new + /customer/new, поле user в запросе
Весь проксиlitellm_settings.max_budget и budget_duration

budget_duration принимает секунды, минуты, часы и дни: 30s, 30m, 30h, 30d. Ключ сверх бюджета получает ошибку с ExceededTokenBudget или ExceededBudget в тексте.

Нюансы, которые легко пропустить:

  • Без базы бюджеты не применяются. Документация показывает пример: в конфиге max_budget, а прокси продолжает отвечать.
  • Модели с нулевой стоимостью обходят проверку бюджета целиком. Документация описывает это для моделей с явными input_cost_per_token: 0 и output_cost_per_token: 0, чтобы ключ с исчерпанным бюджетом мог уйти на бесплатную модель. В карте цен LiteLLM модели Ollama записаны с нулевой стоимостью: расход по ним не растёт, и денежный бюджет их не ограничит. Локальную модель ограничивают через rpm_limit и tpm_limit.
  • У ключа с team_id личный бюджет владельца не действует, работают командные лимиты.

Проверено: 7 ноября 2026 года, LiteLLM 1.108.1 через uvx, без Postgres и без пакета prisma в окружении. Запрос без заголовка Authorization получил 500 Internal Server Error, неверный ключ sk-wrong - 400, верный master key - 200. В логе ModuleNotFoundError: No module named 'prisma': обработка ошибки авторизации обращается к слою базы данных, которого нет.

Запросы без ключа прокси отклонил, но кодом 500 вместо 401. Мониторинг, который ловит неавторизованные попытки по 401, в такой конфигурации ничего не увидит. Без Postgres прокси годится для локального теста, для команды база обязательна.

budget_fallbacks и бюджеты по моделям

С версии 1.92.0 у ключа есть поле budget_fallbacks: когда бюджет ключа на конкретную модель исчерпан, запрос уходит на модель из цепочки вместо ошибки. Страница budget_fallbacks пометки Enterprise не содержит. Но срабатывает он только при model_max_budget (бюджет ключа по отдельным моделям), а model_max_budget документация бюджетов помечает как Enterprise, и в коде /key/generate без лицензии отказывает с сообщением, что для model_max_budget нужен Enterprise. На практике budget_fallbacks без лицензии не работает.

Docker и production

Быстрый старт с Postgres по Docker quickstart:

curl -sSLO https://github.com/BerriAI/litellm/raw/main/docker/docker-compose.quickstart.yml
printf 'LITELLM_MASTER_KEY=sk-%s\nLITELLM_SALT_KEY=sk-%s\n' \
  "$(openssl rand -hex 32)" "$(openssl rand -hex 32)" > .env
docker compose -f docker-compose.quickstart.yml up -d

Compose поднимает шлюз на порту 4000 и Postgres. Перед запуском файл стоит прочитать и заменить тег образа на конкретную версию. Одиночный docker run с конфигом без базы даёт только OpenAI-совместимый API: без ключей, бюджетов и учёта расходов.

Образы и теги по Docker Image Security:

  • ghcr.io/berriai/litellm - основной образ, есть варианты litellm-non_root и litellm-spend_logs;
  • теги vX.Y.Z неизменяемы, main-stable и main-latest помечены deprecated, latest в production не используют;
  • с v1.83.0 все образы в GHCR подписаны cosign, подпись проверяют до деплоя:
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/<commit>/cosign.pub \
  ghcr.io/berriai/litellm:v1.106.6

Что нужно для чего (production, deploy):

КомпонентКогда нужен
PostgresVirtual keys, команды, пользователи, бюджеты, журнал расходов, модели из UI
Redis 7+Больше одного инстанса или воркера: общие rate limits, состояние роутера, кэш
LITELLM_SALT_KEYШифрует креды провайдеров в базе. Менять после добавления моделей нельзя: сохранённые ключи станут нечитаемыми
DISABLE_SCHEMA_UPDATE=trueНа инстансах прокси, миграции выполняет отдельная job
/health/readiness, /health/livelinessПробы для Kubernetes

Рекомендации документации по размеру: 1 vCPU и 4 GiB на воркер, в Kubernetes --num_workers 1 на pod и 2+ реплики. Среди прочего там советуют proxy_batch_write_at: 60 (пакетная запись расходов в базу) и LITELLM_LOG=ERROR. Флаг allow_requests_on_db_unavailable пропускает запросы при недоступной базе, документация разрешает его только внутри VPC.

Admin UI и наблюдаемость

Admin UI открывается по адресу <прокси>/ui и требует базу данных. Логин - UI_USERNAME (по умолчанию admin) и UI_PASSWORD. Если пароль не задан, подходит master key, и любой вошедший так получает права админа прокси (Admin UI). Через UI выпускают ключи, добавляют модели без рестарта, заводят команды и смотрят расходы и логи.

Трейсы и метрики отправляют через callbacks:

  • Langfuse. Для Langfuse v3 и v4 документация LiteLLM рекомендует пресет langfuse_otel через OpenTelemetry v2 вместо старого SDK-колбэка langfuse. Пошаговая настройка Langfuse, включая строку про LiteLLM, есть в гайде по Langfuse, а какие метрики и алерты собирать - в статье об LLM observability.
  • OpenTelemetry v2. litellm_settings.callbacks: ["otel"] и LITELLM_OTEL_V2=true, адрес коллектора в OTEL_EXPORTER, OTEL_ENDPOINT, OTEL_HEADERS. На запрос пишется один trace: аутентификация, guardrails, вызов модели с атрибутами gen_ai.*, запись в базу. Содержимое промптов по умолчанию в трейс не попадает.

Кэш и guardrails

Кэш бывает точным (local, disk, redis, s3, gcs) и семантическим (redis-semantic, valkey-semantic, qdrant-semantic). In-memory кэш живёт внутри воркера: у прокси с четырьмя воркерами четыре отдельных кэша, поэтому начиная со второго воркера нужен Redis. Точный кэш ключуется по хешу всего запроса, и любое изменение диалога даёт промах. Семантический кэш, по словам самой документации, подходит для одиночных промптов и сильно ошибается на агентском трафике.

Guardrails подключаются блоком guardrails: с режимами pre_call, post_call, during_call и logging_only. Встроены litellm_content_filter, Presidio для маскирования PII, интеграции Lakera, Bedrock, Aporia и другие (guardrails). Конкретный guardrail включают на запрос полем "guardrails": ["имя"].

Подключение клиентов

OpenAI SDK

Любой клиент OpenAI-формата: base_url на прокси, в api_key виртуальный ключ, в model - model_name из конфига. Пример в разделе быстрого старта.

Claude Code

По туториалу LiteLLM Claude Code подключается двумя переменными:

export ANTHROPIC_BASE_URL="http://127.0.0.1:4000"
export ANTHROPIC_AUTH_TOKEN="sk-..."   # virtual key или master key
claude --model cloud-sonnet            # model_name из config.yaml

Master key даёт Claude Code доступ ко всем моделям прокси, виртуальный ключ ограничивает его моделями, разрешёнными этому ключу. Если за прокси стоит Bedrock, туториал советует CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1: Bedrock принимает не все beta-заголовки Claude Code.

Две оговорки из документации Claude Code:

  • Anthropic поддерживает шлюзы с совместимым форматом API для моделей Claude, но не аудирует сторонние шлюзы и не поддерживает работу Claude Code с не-Claude моделями через любой шлюз. Технически LiteLLM это позволяет, но качество и совместимость - на вашей стороне.
  • Пока задана переменная с кредом шлюза, запросы идут с этим ключом, а не с логином подписки claude.ai. Лимиты подписки к ним не применяются, оплата - по токенам на владельца ключа.

Проверено: 7 ноября 2026 года, LiteLLM 1.108.1. POST /v1/messages с заголовками x-api-key и anthropic-version: 2023-06-01 на группу local-qwen вернул ответ в формате Anthropic: type: message, stop_reason: end_turn, размышления Qwen3 отдельным блоком thinking, ответ блоком text, usage 16 входных и 98 выходных токенов. Сам Claude Code в этой проверке не запускался.

Клиент Anthropic-формата, значит, может разговаривать с локальной моделью через прокси. Справится ли 8B-модель с агентным циклом Claude Code, это уже вопрос модели, и в тестах OpenCode локальные модели этого размера работали нестабильно. Что из Claude Code доступно в России и как ведут себя альтернативные провайдеры, разобрано в отдельной статье.

OpenCode

Отдельной записи про LiteLLM в документации OpenCode нет, работает общий механизм OpenAI-совместимого провайдера (providers). Пример для OpenCode 1, в том же формате, что и подключение Ollama в гайде по OpenCode:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "litellm": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "LiteLLM",
      "options": {
        "baseURL": "http://127.0.0.1:4000/v1",
        "apiKey": "{env:LITELLM_API_KEY}"
      },
      "models": {
        "cloud-sonnet": { "name": "Sonnet 5.5 via LiteLLM" }
      }
    }
  }
}

Ключ в models должен совпадать с model_name в конфиге прокси. В OpenCode 2 схема другая: блок providers, поля package и settings.baseURL. Адрес прокси подставляется туда же.

Локальные модели

Ollama подключается к прокси как обычный провайдер (раздел про config.yaml). Клиенты тогда ходят на один адрес и одним ключом и к локальной, и к облачной модели, а fallback переключает их без участия приложения. Обзор вариантов локального запуска собран в гайде по локальным LLM.

Что платное: MIT и Enterprise

Лицензия делит репозиторий на две части. Всё вне каталога enterprise/ распространяется под MIT. Код в enterprise/ можно копировать и менять для разработки и тестов, а в production он работает только при действующей подписке BerriAI на нужное число мест; распространять его нельзя. Enterprise - тот же образ, функции включает лицензионный ключ LITELLM_LICENSE после полного рестарта.

Бесплатно (MIT)Нужен Enterprise-ключ
Python SDK, Router, fallbackSSO и SCIM (SSO бесплатен до 5 пользователей)
Virtual keys, бюджеты и rate limits на ключ, пользователя, командуJWT-аутентификация, назначение админов команд
Учёт расходов, Admin UIAudit logs с retention, RBAC (организации, команды, роли)
Балансировка и роутингIP allowlist, ротация ключей, secret managers
Guardrails-фреймворк, кастомные guardrails, PresidioGuardrail-колбэки llmguard_moderations, llamaguard_moderations, hide_secrets, openai_moderations, google_text_moderation, lakera_prompt_injection, aporia_prompt_injection
MCP gatewayТеговые бюджеты, бюджеты по моделям на ключ (model_max_budget), временное повышение бюджета
Кэш, логирование в Langfuse и OTelSoft-budget алерты на email, отчёты по расходам, логи по командам, выгрузка в GCS и Azure Blob, guardrails на ключ и команду, лимиты размера запроса и ответа

Список взят со страницы Enterprise. Цена зависит от объёма использования и обсуждается с продажами, есть бесплатный 30-дневный trial, покупка через AWS и Azure Marketplace или по счёту.

Безопасность LiteLLM: инциденты и CVE 2026

Прокси хранит master key, ключи всех провайдеров и креды в базе. Взлом прокси означает утечку всех этих ключей сразу. Поэтому история уязвимостей за 2026 год важна для любого self-hosted развёртывания.

Компрометация PyPI, 24 марта 2026. Версии 1.82.7 и 1.82.8 содержали вредоносный код, собиравший креды, в 1.82.8 был ещё файл litellm_init.pth, который Python выполняет при старте интерпретатора. По отчёту команды пакеты были доступны с 10:39 UTC около 40 минут, затронутыми считаются установки через pip с 10:39 до 16:00 UTC. Официальный Docker-образ прокси не пострадал. Источником команда называет зависимость Trivy в CI, к расследованию подключили Mandiant. Чистые версии - 1.82.6 и раньше, 1.83.0 и новее.

Основные CVE и advisories по NVD и GitHub Security Advisories, оценка CVSS от GitHub как CNA:

IDОпубликованоCVSSСутьИсправлено в
CVE-2026-3503006.049.4Обход аутентификации при включённом JWT-auth (коллизия ключа кэша OIDC userinfo), по умолчанию выключено1.83.0
CVE-2026-3502906.048.7/config/update не проверял роль admin1.83.0
CVE-2026-4220808.059.3SQL-инъекция в проверке API-ключа: запрос без аутентификации на любой LLM-роут читает и меняет базу прокси (1.81.16-1.83.6)1.83.7
CVE-2026-4220308.058.6SSTI в POST /prompts/test: выполнение кода с любым валидным ключом1.83.7
CVE-2026-4227108.058.7Выполнение команд через тестовые MCP-эндпоинты с stdio-транспортом1.83.7
CVE-2026-4946822.069.5Обход аутентификации через заголовок Host: доступ к management-роутам без ключа1.84.0
CVE-2026-5982208.078.8Обход аутентификации в MCP Streamable HTTP через OAuth2 passthrough1.84.0
CVE-2026-8903225.098.7Семантический кэш отдавал ответы другим тенантам (/v1/responses, /bedrock/*)1.101.0-rc.1
CVE-2026-9335528.097.6JWT-auth: вход под любым пользователем по email без проверки email_verifiedВ записи NVD не указано
CVE-2026-11461222.109.9Общий криптоконтекст для секретов и сессий: internal_user подделывает admin-токен и выполняет команды через MCP stdio; с 1.91.0 в конфигурации по умолчанию1.100.4, 1.101.3, 1.102.2, 1.103.1
GHSA-w4c7-34wj-hqm827.1010.0Только Enterprise: запрос без аутентификации заставляет прокси прочитать локальный файл (например, /proc/self/environ с master key и ключами провайдеров) и отправить его на адрес атакующего1.103.10, 1.104.8, 1.105.6, 1.106.5

Даты - публикация в NVD, у GitHub advisory обычно раньше на несколько дней или недель. Кроме таблицы, в 2026 году были SSRF и утечки кредов провайдера через api_base и user_config в теле запроса (CVE-2026-84377, CVE-2026-59823, Moderate), выполнение кода через тест кастомных guardrails (CVE-2026-40217) и чтение локальных файлов через vertex_ai_credentials (GHSA-g5ff-637f-6q2m).

Почти все серьёзные дыры сидят в аутентификации, management-, test- и MCP-эндпоинтах, JWT и SSO, а не в маршрутизации запросов. Последний critical был в коде Enterprise: лицензия расширяет поверхность атаки.

Чек-лист для self-hosted:

  1. Фиксировать версию: litellm[proxy]==X.Y.Z или тег образа vX.Y.Z, лучше digest, но не latest.
  2. Проверять подпись образа cosign (подписаны с v1.83.0).
  3. Для pip и uv: убедиться, что не стоят 1.82.7 и 1.82.8 (pip show litellm), и поискать litellm_init.pth в site-packages.
  4. Не выставлять прокси в интернет. Доступ через VPN, mTLS, аутентифицирующий ingress или IP allowlist. Отдельно закрыть /ui, /key/*, /team/*, /config/* и MCP-роуты.
  5. Ограничить исходящий трафик прокси адресами провайдеров. В GHSA-w4c7 именно это обрывает эксфильтрацию даже при уязвимой версии.
  6. Не включать MCP gateway, JWT и SSO, если они не нужны.
  7. Задать отдельный LITELLM_SALT_KEY, master key по возможности держать в secret manager, а не в переменных окружения процесса.
  8. Подписаться на advisories репозитория и обновляться по ним: исправления выходят сразу в нескольких поддерживаемых линиях.

Риски MCP-эндпоинтов не уникальны для LiteLLM, общая модель угроз описана в статье о MCP-серверах.

Ограничения и подводные камни LiteLLM

Postgres обязателен для команды

Без базы нет ключей, бюджетов, Admin UI и журнала расходов, а лимиты из конфига молча игнорируются. В проверке без базы запрос без ключа получил 500 вместо 401. Для команды Postgres закладывают с первого дня.

Лишний хоп и лишняя точка отказа

Около 7 мс на запрос на локальной машине мало, но прокси становится единой точкой отказа для всех клиентов. В production нужны 2+ реплики, Redis и health-пробы, то есть ещё одна система, которую надо администрировать.

Версия каждую неделю

Релизы выходят несколько раз в неделю: 27 октября одно и то же исправление вышло в четырёх линиях сразу (1.103.10, 1.104.8, 1.105.6, 1.106.5). Поведение между версиями меняется: проверки этой статьи сделаны на 1.108.1, вышедшей через три дня после даты статьи. Перед обновлением в production читают changelog и advisories.

Плейсхолдеры в документации

Примеры в документации LiteLLM используют имена моделей, которые не всегда совпадают с актуальными ID провайдеров. Копировать их в конфиг без сверки с документацией провайдера не стоит.

Семантический кэш и агенты

Семантический кэш отдаёт ближайший по смыслу ответ. Для агентского трафика с вызовами инструментов это источник ошибок, а в CVE-2026-89032 он ещё и отдавал ответы между тенантами.

Когда LiteLLM не нужен

Одна модель и один сервис обходятся SDK провайдера. Одному разработчику с несколькими провайдерами хватит LiteLLM SDK без сервера. Если администрировать шлюз некому, облачный агрегатор дешевле по времени, хотя и дороже по комиссии.

С чего начать

  1. Поставьте зафиксированную версию: uv tool install 'litellm[proxy]==1.106.6' и проверьте litellm --version.
  2. Напишите config.yaml с одной локальной и одной облачной моделью, master key из переменной окружения, запустите прокси на 127.0.0.1.
  3. Проверьте запрос через curl и OpenAI SDK, затем настройте fallbacks и посмотрите заголовки x-litellm-attempted-fallbacks при недоступной основной модели.
  4. Для команды поднимите Postgres (compose-quickstart), задайте LITELLM_SALT_KEY, выпустите ключи с max_budget и rpm_limit.
  5. Подключите клиентов: OpenAI SDK, Claude Code через ANTHROPIC_BASE_URL, OpenCode через OpenAI-совместимый провайдер.
  6. Пройдите чек-лист безопасности: закрытая сеть, ограниченный egress, подпись образа, подписка на advisories.

Часто задаваемые вопросы

LiteLLM бесплатный?
Python SDK и Proxy распространяются под MIT: virtual keys, бюджеты и rate limits, учёт расходов, Admin UI, балансировка, guardrails-фреймворк и MCP gateway доступны без оплаты. Под отдельной лицензией лежит каталог enterprise/: SSO больше чем на 5 пользователей, JWT-аутентификация, audit logs, RBAC, бюджеты по моделям на ключ и ряд guardrail-интеграций. Enterprise стоит по запросу, есть 30-дневный trial.
Нужна ли LiteLLM база данных Postgres?
Для локального теста нет: прокси с config.yaml и master key работает без базы. Для команды да: virtual keys, бюджеты, команды, пользователи, журнал расходов и Admin UI хранятся в Postgres (переменная DATABASE_URL). Без базы бюджеты не применяются, и в проверке на 1.108.1 запрос без ключа получил 500 вместо 401.
Чем LiteLLM Proxy отличается от LiteLLM SDK?
SDK - библиотека внутри Python-приложения: единый вызов completion() к разным провайдерам, ретраи, fallback и учёт стоимости ответа. Proxy - отдельный сервер с OpenAI-совместимым API, к которому подключаются приложения на любом языке и агенты. Ключи на сотрудника, бюджеты и общий журнал расходов есть только в Proxy.
Как подключить Claude Code к LiteLLM?
Задать ANTHROPIC_BASE_URL с адресом прокси и ANTHROPIC_AUTH_TOKEN с виртуальным ключом или master key, а в claude --model указать model_name из config.yaml. LiteLLM принимает Anthropic-формат на /v1/messages. Anthropic поддерживает шлюзы для моделей Claude, но не поддерживает работу Claude Code с не-Claude моделями через любой шлюз, такая схема работает на ваш риск.
Безопасен ли LiteLLM после взлома PyPI в марте 2026?
Вредоносными были только версии 1.82.7 и 1.82.8, их удалили с PyPI, официальный Docker-образ не пострадал. Опаснее для self-hosted другое: в 2026 году вышло больше десятка CVE в аутентификации, management- и MCP-эндпоинтах, несколько с оценкой 9+ по CVSS. Безопасная эксплуатация - зафиксированная версия, проверка подписи образа cosign, прокси без доступа из интернета и ограниченный исходящий трафик.
LiteLLM или OpenRouter?
OpenRouter - облачный сервис: один аккаунт и счёт, сотни моделей, комиссия платформы 5,5% на тарифе Standard. LiteLLM вы разворачиваете сами: запросы идут через ваш сервер к провайдерам по вашим ключам, вы ставите ключи и бюджеты сотрудникам. Их совмещают: OpenRouter подключается к LiteLLM как один из провайдеров.
Работает ли LiteLLM с Ollama?
Да. В config.yaml указывают model: ollama_chat/<модель> и api_base сервера Ollama, документация LiteLLM рекомендует префикс ollama_chat. В проверке на LiteLLM 1.108.1 и Ollama 0.40.14 прокси добавил около 7 мс к запросу к qwen3:8b и переключался на облачную модель, когда Ollama была недоступна.