Logo
Overview

LiteLLM: как подружить Claude, OpenAI-совместимый провайдер и один API-слой

May 13, 2026
9 min read

LiteLLM: как подружить Claude, OpenAI-совместимый провайдер и один API-слой

Если у вас в проекте уже больше одной LLM — поздравляю, у вас уже зоопарк. Один скрипт ходит в Anthropic SDK, второй — в openai через base_url какого-нибудь облачного провайдера, третий написан на curl потому что «быстро надо было, потом перепишу». Знакомо? И каждый раз, когда меняется ключ, тариф или модель, приходится править все три места (а ещё забыть про четвёртое, которое крутится в кроне раз в неделю).

LiteLLM — это попытка свести этот зоопарк к одной точке входа. В этом посте разберём, что такое LiteLLM, чем он принципиально отличается от обычного SDK, как его поднять локально и в Docker, как подключить к нему Claude и OpenAI-совместимого провайдера одновременно, и зачем это вообще нужно практикующему инженеру, а не только команде с ML-платформой на сто человек.

Что такое LiteLLM простыми словами

LiteLLM — открытая прослойка над провайдерами LLM (Anthropic, OpenAI, Google, Bedrock, Azure, локальные Ollama и десятки других), которая выставляет наружу единый OpenAI-совместимый HTTP API.

Можно использовать LiteLLM в двух режимах:

  • SDK-режим (litellm как Python-библиотека). Вы импортируете litellm.completion(...) и под капотом он ходит в нужный провайдер. Удобно для скриптов, но слабо помогает, если у вас не Python.
  • Proxy-режим (LiteLLM Proxy Server). Поднимается отдельный сервис — обычно в Docker, — который принимает запросы по адресу https://your-llm.example.com/v1/chat/completions, а внутри сам решает, кому реально их отправить. Любой клиент, умеющий говорить с OpenAI, теперь умеет говорить с чем угодно.

Если очень грубо — LiteLLM Proxy это API Gateway, но специально заточенный под LLM-трафик: он знает про токены контекста, про tool calling, про streaming, про разные форматы сообщений у Anthropic и OpenAI.

Чем LiteLLM не является

  • Не модель. Своих весов у него нет, считать он ничего не умеет. Это маршрутизатор и адаптер форматов.
  • Не кеш по умолчанию. Кеш есть, но его нужно явно включить и подключить Redis, иначе платите за каждый запрос.
  • Не замена Anthropic SDK для тонкой работы. Если вам нужны экзотические фичи Claude вроде Model Context Protocol или специфичных полей prompt caching, иногда проще ходить в Anthropic напрямую, а через LiteLLM пускать массовый «обычный» трафик.

Зачем нужен LiteLLM: какие проблемы он решает

Без прокси у вас типичный набор боли:

  • Привязка к одному провайдеру. Менять Anthropic на OpenAI = переписывать половину кода. С LiteLLM меняется одна строка в конфиге.
  • Размазанные ключи. API-ключи лежат в env-переменных каждого сервиса, ротация — это квест на полдня.
  • Нет единого учёта. Сколько в этом месяце реально потратили на LLM по проектам? Без прокси — никто не знает (и финдир делает грустное лицо).
  • Нет лимитов на пользователя. Любой скрипт может случайно запулить 50к токенов в цикле и съесть бюджет за выходные.
  • Несовместимые форматы. У Claude system это отдельный параметр, у OpenAI — это сообщение с ролью system в массиве. LiteLLM это разруливает.

Всё это в одиночку решаемо, но каждое решение — это код, который вы пишете и поддерживаете сами. Прокси берёт это на себя.

Архитектура: как устроен LiteLLM Proxy

Тут важна не картинка ради картинки, а понимание, где что происходит и что может пойти не так на каждом шаге.

100%
graph LR
  subgraph CLIENTS["Клиенты"]
      APP["Backend сервис"]
      CLI["CLI / Claude Code"]
      CRON["Cron / Скрипты"]
  end

  subgraph PROXY["LiteLLM Proxy"]
      AUTH["Virtual Keys / Auth"]
      ROUTE["Router / Fallback"]
      TRANS["Адаптер форматов"]
      CACHE["Redis Cache"]
      BUDGET["Budget / Rate Limit"]
      LOG["Логирование / Spend"]
  end

  subgraph PROVIDERS["LLM провайдеры"]
      ANT["Anthropic Claude"]
      OAI["OpenAI совместимый"]
      OLL["Ollama локальная"]
  end

  DB["Postgres: ключи, бюджеты"]
  REDIS["Redis: кеш, лимиты"]

  APP --> AUTH
  CLI --> AUTH
  CRON --> AUTH
  AUTH -.проверка ключа.-> DB
  AUTH --> BUDGET
  BUDGET -.лимиты.-> REDIS
  BUDGET --> ROUTE
  ROUTE --> TRANS
  TRANS --> CACHE
  CACHE -.hit/miss.-> REDIS
  TRANS --> ANT
  TRANS --> OAI
  TRANS --> OLL
  TRANS --> LOG
  LOG -.spend.-> DB

  style APP fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style CLI fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style CRON fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style AUTH fill:#50c878,stroke:#3a9a5c,color:#fff
  style ROUTE fill:#50c878,stroke:#3a9a5c,color:#fff
  style TRANS fill:#50c878,stroke:#3a9a5c,color:#fff
  style CACHE fill:#50c878,stroke:#3a9a5c,color:#fff
  style BUDGET fill:#50c878,stroke:#3a9a5c,color:#fff
  style LOG fill:#50c878,stroke:#3a9a5c,color:#fff
  style ANT fill:#f0a500,stroke:#c88400,color:#fff
  style OAI fill:#f0a500,stroke:#c88400,color:#fff
  style OLL fill:#f0a500,stroke:#c88400,color:#fff
  style DB fill:#7b68ee,stroke:#5a4db2,color:#fff
  style REDIS fill:#7b68ee,stroke:#5a4db2,color:#fff

На диаграмме три зоны. Синяя — клиенты, которым всё равно, какая модель за стенкой: они говорят на одном диалекте OpenAI Chat Completions и не знают про существование Anthropic. Зелёная — сам прокси, разделённый на модули: аутентификация по virtual keys, бюджет и лимиты, маршрутизатор с fallback, адаптер форматов, кеш и логирование. Жёлтая — реальные провайдеры моделей. Фиолетовая — состояние: Postgres хранит ключи, пользователей и spend, Redis — кеш и счётчики rate limit.

Поток одного запроса

  1. Клиент шлёт POST /v1/chat/completions с заголовком Authorization: Bearer sk-virtual-... — это виртуальный ключ, выписанный администратором прокси.
  2. Прокси валидирует ключ, поднимает связанный с ним лимит (например, $50 в месяц на проект).
  3. Роутер по model: "claude-sonnet" смотрит в конфиг и решает: первый кандидат — Anthropic напрямую, fallback — Bedrock, ещё fallback — OpenAI совместимый GPT-аналог. Если Anthropic вернул 529 или таймаут — автоматически следующий.
  4. Адаптер собирает payload в формате выбранного провайдера. Для Anthropic это значит вытащить system из массива сообщений и положить его в отдельное поле.
  5. Если включён кеш — считается хеш промпта, проверяется Redis. Hit — отдаём из кеша, miss — идём в провайдера.
  6. Ответ нормализуется обратно в OpenAI-формат и отдаётся клиенту. Параллельно в Postgres пишется spend, в логи — request_id.

Если прокси и REST API в целом для вас новая тема — здесь полезно знать про разницу stateless и stateful. LiteLLM Proxy сам по себе stateless (состояние — в Postgres/Redis), и это ровно то, почему его легко масштабировать горизонтально.

Как поднять LiteLLM Proxy: минимальный пример

Самый быстрый способ — Docker. Создайте config.yaml:

model_list:
- model_name: claude-sonnet
litellm_params:
model: anthropic/claude-sonnet-4-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: gpt-fallback
litellm_params:
model: openai/gpt-4o-mini
api_base: https://your-openai-compat.example.com/v1
api_key: os.environ/OPENAI_COMPAT_KEY
router_settings:
fallbacks:
- claude-sonnet: ["gpt-fallback"]
litellm_settings:
drop_params: true
cache: true
cache_params:
type: redis
host: redis
port: 6379

Здесь:

  • model_name — это псевдоним, по которому клиент будет запрашивать модель. Внутри он может указывать на что угодно.
  • litellm_params.model — реальный провайдер и модель. Префикс (anthropic/, openai/, bedrock/, ollama/) подсказывает прокси, какой адаптер использовать.
  • fallbacks — если первая модель упала, пробуем следующую. Удобно, когда у Anthropic очередной 529.
  • drop_params: true — молча выкидывать параметры, которые провайдер не понимает, а не падать с 400. Спорная штука, но в проде живётся легче.

Поднимаем:

Terminal window
docker run -d --name litellm \
-e ANTHROPIC_API_KEY=sk-ant-... \
-e OPENAI_COMPAT_KEY=sk-... \
-e LITELLM_MASTER_KEY=sk-master-secret \
-p 4000:4000 \
-v $(pwd)/config.yaml:/app/config.yaml \
ghcr.io/berriai/litellm:main-stable \
--config /app/config.yaml

И проверяем:

Terminal window
curl http://localhost:4000/v1/chat/completions \
-H "Authorization: Bearer sk-master-secret" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet",
"messages": [{"role": "user", "content": "Привет"}]
}'

Если ответ пришёл — всё, у вас теперь единый OpenAI-совместимый слой над Claude. Любой клиент, умеющий OpenAI (и таких — почти все), теперь работает с Claude без единой строчки кода-адаптера.

Сравнение подходов: прямой SDK vs LiteLLM Proxy

АспектПрямой Anthropic / OpenAI SDKLiteLLM Proxy
Смена провайдераПереписать кодИзменить config.yaml
Управление ключамиВ env каждого сервисаVirtual keys в одном месте
Учёт расходовЧерез дашборд провайдераСквозной spend по проектам
Rate limitingСам пишешьИз коробки, по ключу/команде
Fallback при сбоеСвой код с try/exceptДекларативно в конфиге
КешированиеСам делаешьRedis в одну строчку
Поддержка специфичных фичПолнаяИногда отстаёт от провайдера
LatencyМинимум+1 hop (обычно 5–20 мс)
Ещё одна точка отказаНетДа — прокси нужно держать в HA

Последние две строки — это плата за удобство. Если прокси упал — встанут все клиенты сразу. Поэтому в проде LiteLLM поднимают минимум в двух репликах за балансировщиком, с health-check’ами и алертами на p99 latency.

Подключаем Claude Code через LiteLLM

Один из самых полезных сценариев в моей практике — пускать Claude Code CLI не напрямую в Anthropic, а через свой прокси. Зачем:

  • Лимиты и учёт. Видно, кто из команды сколько токенов сжёг.
  • Кеширование общих промптов. Если у вас десять сессий начинаются с одного и того же длинного системного промпта, Redis-кеш экономит реальные деньги.
  • Единый аудит. Все запросы логируются в одном месте, а не в личных кабинетах разных провайдеров.

Технически Claude Code умеет ходить в Anthropic-совместимый эндпоинт. LiteLLM умеет принимать запросы и в OpenAI-формате (/v1/chat/completions), и в нативном Anthropic-формате (/v1/messages) — на этом и строится трюк. Указываем CLI базовый URL прокси и virtual key, дальше всё работает как обычно, только трафик идёт через вашу инфраструктуру. Подробности подключения зависят от версии — смотрите доку, она меняется.

Важно. Не заворачивайте через прокси то, что использует фичи, которых LiteLLM ещё не поддерживает (например, экспериментальные режимы тулюзинга). Сначала протестируйте на dev-ключе, потом переводите прод.

Антипаттерны: на чём обжигаются с LiteLLM

Прокси без HA

Поднимают один контейнер на старом дроплете и забывают. Через месяц он ловит OOM посреди ночи — и весь продукт теряет LLM-фичи. Решение скучное: минимум две реплики, health-check, алерт на 5xx, мониторинг p95.

Кеш без понимания инвалидации

Включили cache: true — обрадовались экономии — потом обнаружили, что юзеры получают ответы вчерашнего дня на сегодняшние данные. Кешировать стоит только запросы, где это реально безопасно: системные промпты, справочные ответы, эмбеддинги. Динамический контент — нет.

Master key вместо virtual keys

Раздают всем разработчикам LITELLM_MASTER_KEY («ну так быстрее»). Через полгода ключ утекает в публичный репозиторий, ротация — это смена master-ключа и переподключение всего парка. Virtual keys выписываются по одному на сервис/человека и отзываются индивидуально.

Fallback на принципиально другую модель

В конфиге пишут: «если упал Claude — пускай OpenAI». Звучит логично, но качество ответов у разных моделей разное, и пользователь это заметит. Fallback’и должны быть максимально близкими: Anthropic Claude → Bedrock Claude — да; Claude Sonnet → GPT-4o-mini — почти всегда нет.

Игнорирование разницы в tool calling

У OpenAI и Anthropic разные форматы инструментов. LiteLLM их транслирует, но не магически: какие-то экзотические поля могут потеряться. Если у вас сложный tool use — тестируйте сквозным интеграционным тестом, не верьте на слово.

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

Это не серебряная пуля. Если у вас:

  • один проект, одна модель, один провайдер;
  • нет команды и нет необходимости в учёте расходов по людям;
  • очень специфичные фичи модели, которые прокси может не докинуть;

— то прямой SDK будет проще и быстрее. Прокси — это инструмент для тех, у кого LLM-трафик стал инфраструктурой, а не разовой интеграцией.

Заключение

LiteLLM решает скучную, но дорогую проблему: чем больше у вас LLM-интеграций, тем дороже их поддерживать поодиночке. Один прокси, один формат, один учёт, одна точка ротации ключей — и внезапно у вас есть рычаг управления, которого раньше не было.

PS. Как только вы поднимете прокси и начнёте видеть spend по проектам — приготовьтесь к неприятному открытию. Окажется, что один забытый скрипт в кроне жрёт половину бюджета. Это не баг прокси, это фича прозрачности (которую раньше вы себе позволить не могли).