LiteLLM — обзор, запуск и тестирование
Подробная инструкция по запуску и настройке liteLLM, которая упростит работу, если нужен доступ к множеству больших языковых моделей.
Если вы или ваша команда уже используете LLM или планируете интегрировать в проект, то наверняка у вас возникал вопрос, как лучше и красивее написать такой интерфейс, который мог бы общаться с разными моделями. И на такой вопрос уже есть ответ.
Теперь можно сэкономить время разработки и управлять нейросетями в одном месте. Поможет в этом простой инструмент LiteLLM, про который далее и пойдет речь.
Для чего нужен LiteLLM
LiteLLM — это прокси-шлюз (gateway) для LLM, который умеет общаться со 100+ LLM-провайдерами, переводя все их ответы в формат OpenAI API. Это значит, что можно написать один раз код под паттерн chat/completions, а дальше переключаться в любой момент на нужную модель. Локально, например, можно установить Llama через Ollama, и обращаться к ней, а на продакшене использовать любую облачную модель, например GPT-4o, вообще не меняя код. Вкусно же? Очень даже.
Этот инструмент также содержит в себе такие полезные функции, как отслеживание расходов, установка лимитов на бюджет по пользователям или группам пользователей, fallback-механизмы моделей, логирование и другие операционные функции.

На практике LiteLLM особо проявляется, когда появляется необходимость в использовании нескольких нейросетей. Если у вас несколько микросервисов, которые могут обращаться каждый к своей модели, этот инструмент поможет унифицировать запросы и как-то следить за всем этим.
Как запустить LiteLLM
Проще и быстрее всего развернуть LiteLLM в виде Docker-контейнера — этот способ изолирует окружение и избавляет от ручной настройки Python-зависимостей.
Для начала скачаем на сервер актуальный официальный образ шлюза из репозитория:
docker pull docker.litellm.ai/berriai/litellm:latest
Далее нужно создать конфиг со списком нейросетей. Для примера возьмем двух популярных провайдеров — Perplexity и Groq — и подключим по две модели от каждого.
model_list:
# --- Perplexity (Sonar) ---
- model_name: sonar
litellm_params:
model: perplexity/sonar
api_key: os.environ/PERPLEXITYAI_API_KEY
- model_name: sonar-pro
litellm_params:
model: perplexity/sonar-pro
api_key: os.environ/PERPLEXITYAI_API_KEY
# --- Groq ---
- model_name: gpt-oss
litellm_params:
model: groq/openai/gpt-oss-120b
api_key: os.environ/GROQ_API_KEY
- model_name: groq-llama-3.1-8b
litellm_params:
model: groq/llama-3.1-8b-instant
api_key: os.environ/GROQ_API_KEY
litellm_settings:
drop_params: true
set_verbose: false
request_timeout: 300
router_settings:
timeout: 300
fallbacks:
- sonar: ['gpt-oss']
- gpt-oss: ['sonar']
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
Здесь в model_list находится перечисление всех моделей, которые будут доступны в вашем инстансе LiteLLM. В litellm_settings перечислены параметры, которые применяются ко всем моделям в запросах. В router_settings находятся настройки роутера, которые описывают таймауты, запасные модели, количество попыток при ошибках и тому подобное. А general_settings — это уже настройки самого LiteLLM инстанса.
LiteLLM сам знает, какие базовые адреса у провайдеров, но, если что-то изменится или вы захотите переопределить базовый адрес, то можно добавить api_base на том же уровне, что и api_key.
Запуск производим через docker run следующим образом:
docker run -d \
--name litellm \
-p 4000:4000 \
-v "$(pwd)/config.yaml:/app/config.yaml:ro" \
-e PERPLEXITYAI_API_KEY=pplx-... \
-e GROQ_API_KEY=gsk_... \
-e LITELLM_MASTER_KEY=sk-litellm-local \
docker.litellm.ai/berriai/litellm:latest \
--config /app/config.yaml \
--port 4000
После запуска можно попробовать сделать запрос через curl:
curl http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-litellm-local" \
-H "Content-Type: application/json" \
-d '{
"model": "sonar",
"messages": [{"role": "user", "content": "Привет!"}]
}'
В ответе получаем большой JSON, содержащий в себе контент ответа, использованное количество токенов и другую полезную информацию:
{
"id":"12e3374a-7ea7-4eac-b744-0f6013b06366",
"created":1782896750,
"model":"sonar",
"object":"chat.completion",
"choices":[...],
"usage":{...},
"citations":[...],
"search_results":[...]
}
Хорошо, LiteLLM поднят и базовые запросы на него проходят. Но в чем его главная суть? Она как раз в том, что можно написать один код, который будет работать под все модели. Даже если у ИИ-провайдеров будут разные схемы запросов и ответов, LiteLLM сам подгонит все под один формат.
Тестируем возможности
Для реализации этого на практике у LiteLLM есть библиотека на Python. Давайте протестируем ее и заодно проверим, как разные модели справляются с поиском актуальной информации. Для этого зададим им специфический вопрос о компании Selectel.
Минимальный рабочий код выглядит следующим образом:
import os
from litellm import completion
response = completion(
model="perplexity/sonar",
messages=[
{"role": "user", "content": "Кто маскот в Selectel"}
],
api_base="http://localhost:4000",
api_key="sk-litellm-local",
)
print(response.choices[0].message.content)
Здесь импортируется функция completion из библиотеки LiteLLM, добавляется ключ для perplexity в переменные окружения, отправляется запрос и выводится ответ:
“Маскот компании Selectel — это **динозавр Тирекс (T‑Rex)**.[1][2][3]
По брендбуку Selectel, Тирекс описывается как любознательный, самоироничный персонаж с маленькими ручками и большим сердцем, открытый к общению и новым идеям. В материалах компании и партнеров он напрямую назван «маскотом Selectel» и талисманом компании.”
Теперь можно просто поменять модель, например, на groq/gpt-oss и проверить, какой вывод будет при другой модели:
“У Selectel официального маскота нет.
В публичных материалах компании иногда встречается стилизованный персонаж — простая графическая «зубчатая» иконка‑робот в фирменных синих тонах, который служит лишь визуальным акцентом к логотипу. Но это не персонализированный маскот в привычном понимании (как, например, «Пингвин» у Linux). Если бы у Selectel появился собственный персонаж‑талисман, об этом обычно объявляют в пресс‑релизах или на официальных страницах, а пока такой информации нет.”
Ответ не верный, но он есть, что говорит о том, что мы можем с легкостью переключаться между моделями в любое время, без необходимости править кучу кода.
Хорошо, основную фишку разобрали, теперь пойдем дальше.
Интерфейс
Помимо работы через код, у LiteLLM есть встроенный веб-интерфейс. В нем можно смотреть расходы, логировать запросы и управлять группами пользователей. Чтобы UI заработал, необходимо подключить базу данных для хранения пользователей, иначе просто не сможем залогиниться.
Для этого необходимо в general_settings в конфиге добавить переменную DATABASE_URL.
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
# Database settings
database_url: os.environ/DATABASE_URL
И перезапустить контейнер с пробросом переменной:
docker run -d \
--name litellm \
-p 4000:4000 \
-v "$(pwd)/litellm-config.yaml:/app/config.yaml:ro" \
-e PERPLEXITYAI_API_KEY=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 \
-e GROQ_API_KEY=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 \
-e LITELLM_MASTER_KEY=sk-litellm-local \
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/litellm \
docker.litellm.ai/berriai/litellm:latest \
--config /app/config.yaml \
--port 4000
Вот и все. Теперь, если перейти по адресу localhost:4000/ui, то увидим страницу логина.

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

Если перейти на вкладку Usage, то сразу видим учет расхода:


На боковой панели слева также можно наблюдать остальные доступные инструменты, которыми можно пользоваться прямо из коробки. Например, установка лимита на бюджет, создание команд, распределение организаций и еще много полезных штук.
Включаем кэширование запросов
Раз уж мы заговорили про экономию бюджета, нельзя обойти стороной еще одну мощную возможность LiteLLM — кэширование. Это полезный инструмент, если приходится часто тестировать какой-то функционал с одинаковым промптом, и нет необходимости в разных ответах при одинаковых запросах.
Для начала обновим конфиг LiteLLM, добавив в блок litellm_settings следующие параметры:
litellm_settings:
drop_params: true
set_verbose: false
request_timeout: 300
cache: true
cache_params:
type: local
ttl: 600
Как видите, мы просто включили параметр cache и задали локальный тип хранения (cache_params) на 10 минут. Этого уже достаточно, чтобы кэширование начало работать.
Теперь давайте наглядно проверим результат. Для этого мы слегка обновим наш Python-код, добавив отслеживание времени ответа от LiteLLM.
import time
from litellm import completion
start = time.perf_counter()
response = completion(
model="perplexity/sonar",
messages=[
{"role": "user", "content": "Кто маскот в Selectel"}
],
api_base="http://localhost:4000",
api_key="sk-litellm-local",
)
elapsed = time.perf_counter() - start
print(response.choices[0].message.content)
print(f"\nВремя выполнения: {elapsed:.2f} с")
Теперь, после ответа, будет выводиться время, за которое LiteLLM выдал ответ.
При первом запуске скрипта системе нужно достучаться до провайдера, дождаться генерации текста и получить его обратно. У меня этот процесс занял почти 5 секунд:
Маскот компании Selectel — это добрый и обаятельный динозавр **Тирекс** (T-Rex) [1][2]. **Основные характеристики маскота:** * **Внешность:** У него маленькие ручки и большое сердце [1]. * **Характер:** Тирекс любознателен, склонен к самоиронии, обожает приключения и всегда открыт новым знаниям [1][2]. * **Роль в компании:** Он занимает должность «самого зубастого автора» Академии Selectel и помогает объяснять (разжёвывать) новые сложные темы или устранять поломки [2]. * **Церезия:** maschot появился впервые в комментариях к статье на Хабре о причинах даунтайма [3]. * **Детали:** Тирекс родился в год Дракона, за свою карьеру написал 381 статью для Академии Selectel, а его плюшевые копии раздаются хорошим людям под руководством котёнка Хрума [4]. Тирекс является частью бренда и талисманом компании, каждый новый сотрудник получает его стикер или игрушку при трудоустройстве [5][6]. Время выполнения: 4.82 с
А второй раз запрос уже выполнился быстрее, и ответ был тот же. Это указывает на то, что кэширование работает и теперь при одинаковых запросах не будут расходоваться лишние токены.
Маскот компании Selectel — это добрый и обаятельный динозавр **Тирекс** (T-Rex) [1][2]. **Основные характеристики маскота:** * **Внешность:** У него маленькие ручки и большое сердце [1]. * **Характер:** Тирекс любознателен, склонен к самоиронии, обожает приключения и всегда открыт новым знаниям [1][2]. * **Роль в компании:** Он занимает должность «самого зубастого автора» Академии Selectel и помогает объяснять (разжёвывать) новые сложные темы или устранять поломки [2]. * **Церезия:** maschot появился впервые в комментариях к статье на Хабре о причинах даунтайма [3]. * **Детали:** Тирекс родился в год Дракона, за свою карьеру написал 381 статью для Академии Selectel, а его плюшевые копии раздаются хорошим людям под руководством котёнка Хрума [4]. Тирекс является частью бренда и талисманом компании, каждый новый сотрудник получает его стикер или игрушку при трудоустройстве [5][6]. Время выполнения: 0.27 с
Стоит учесть, что для использования кэширования в продакшене рекомендуется подключать Redis. Для этого необходимо изменить cache_params в litellm_settings следующим образом:
cache_params:
type: redis
host: os.environ/REDIS_HOST
port: os.environ/REDIS_PORT
password: os.environ/REDIS_PASSWORD
ttl: 600
namespace: litellm.cache
После обновления конфига необходимо просто перезапустить LiteLLM с переданными переменными окружения, и кэширование будет работать через Redis.
Заключение
Будем честны: ввязываться в ИИ-разработку и жестко привязываться к API одного вендора (тот самый Vendor Lock) — это технический долг, который вы берете на себя с первого же дня. Рынок штормит, провайдеры то и дело меняют схемы запросов, обновляют тарифы.
В этом плане LiteLLM работает как локальный ИИ-роутер, который забирает на себя всю рутину с маршрутизацией, авторизацией через админку и экономией токенов через кэш. Архитектура вашего приложения остается чистой и независимой.
Правда, когда дело доходит до продакшена, удобство open-source начинает требовать внимания. Вам придется самостоятельно администрировать Docker-контейнеры, следить за базой пользователей, настраивать и поддерживать кластер Redis для кэша, а главное — как-то решать проблемы (в том числе и с безопасностью) с оплатой зарубежных API-ключей.
Если идея «единого окна» для сотен моделей вам близка, но тратить время команды на поддержку еще одного куска инфраструктуры не хочется, можно использовать готовый ИИ-роутер.
В конце концов, задача разработчика — пилить крутые фичи для пользователей, а рутину с шлюзами и серверами интеграции вполне можно делегировать.