리텔름(litelm): LiteLLM에서 꼭 필요한 기능만 남긴 초경량 라이브러리
litelm은 LLM 호출 라우팅과 메시지 형식 변환 기능만을 약 2,900줄의 코드와 2개의 의존성(openai, httpx)으로 제공하는 초경량 오픈소스 라이브러리입니다. 기존 LiteLLM이 10만 줄 이상의 프록시 서버, 캐싱, 비용 추적 등 무거운 기능을 포함하는 것과 달리, 핵심 호출 경로(모델 라우팅, 메시지 변환, 스트리밍, 툴 호출, 임베딩)만 남겼습니다. API가 LiteLLM과 동일해 import만 바꾸면 바로 마이그레이션할 수 있다는 점이 실무자에게 큰 장점입니다.
litelm: LiteLLM에서 부피를 뺀 버전
litellm의 라우팅 + 변환 기능을 약 2,900줄의 코드와 2개의 의존성(openai, httpx)으로 구현한 라이브러리입니다.
litellm은 LLM 호출을 여러 프로바이더에 걸쳐 라우팅하고 메시지 형식 간 변환을 해주는 라이브러리입니다. 하지만 그 핵심 기능은 10만 줄 이상의 프록시 서버, 캐싱 레이어, 비용 추적, 그리고 대부분의 사용자가 한 번도 쓰지 않을 수많은 기능들 아래에 묻혀 있습니다.
litelm은 오직 호출 경로만 추려냈습니다 — 모델 라우팅, 메시지 변환, 스트리밍, 툴(함수) 호출, 임베딩. 그 외에는 아무것도 없습니다. Router 클래스도, 프록시도, 캐싱도 없습니다.
설치
pip install litelm # openai + httpx
pip install litelm[anthropic] # + anthropic SDK
pip install litelm[bedrock] # + boto3
pip install litelm[all] # 전체
사용법
import litelm
# 기본 완성(completion)
response = litelm.completion(
"openai/gpt-4o",
messages=[{"role": "user", "content": "안녕하세요!"}]
)
print(response.choices[0].message.content)
# 스트리밍
for chunk in litelm.completion(
"groq/llama-3.1-70b-versatile",
messages=[...],
stream=True
):
print(chunk.choices[0].delta.content or "", end="")
# 임베딩
response = litelm.embedding(
"openai/text-embedding-3-small",
input=["hello world"]
)
모든 함수에는 비동기 버전이 있습니다: acompletion, aembedding, aresponses, atext_completion.
API는 litellm과 완전히 동일합니다 — 같은 함수명, 같은 인자, 같은 응답 타입. 현재 litellm을 쓰고 있다면 import에서 litellm을 litelm로 바꾸기만 하면 됩니다.
포함된 것 / 제외된 것
| 기능 | litellm | litelm |
|---|---|---|
| 모델 라우팅 (provider/model → 올바른 엔드포인트) | ✓ | ✓ |
| 메시지 변환 (Anthropic, Bedrock, Cloudflare, Mistral) | ✓ | ✓ |
| 스트리밍 + stream_chunk_builder | ✓ | ✓ |
| 툴 호출 (function calling) | ✓ | ✓ |
| 임베딩 | ✓ | ✓ |
| 텍스트 완성 | ✓ | ✓ |
| OpenAI Responses API | ✓ | ✓ |
| 모의(Mock) 응답 | ✓ | ✓ |
| Router (로드 밸런싱, 폴백) | ✓ | ✗ |
| 프록시 서버 | ✓ | ✗ |
| 캐싱 / 예산 관리 / 비용 추적 | ✓ | ✗ |
| 토큰 카운팅 | ✓ | ✗ |
| 이미지 생성, 오디오, OCR, 파인튜닝 | ✓ | ✗ |
| 에이전트, 가드레일, 스케줄러 | ✓ | ✗ |
프로바이더
"provider/model-name" 문법을 통해 19개 프로바이더로 라우팅합니다. OpenAI 호환 엔드포인트는 api_base로 모두 사용 가능합니다.
| 프로바이더 | 환경 변수 | 핸들러 | 검증 여부 |
|---|---|---|---|
| OpenAI | OPENAI_API_KEY | OpenAI SDK | Yes |
| Anthropic | ANTHROPIC_API_KEY | 커스텀 | Yes |
| Groq | GROQ_API_KEY | OpenAI 호환 | Yes |
| Mistral | MISTRAL_API_KEY | 커스텀 | Yes |
| xAI | XAI_API_KEY | OpenAI 호환 | Yes |
| OpenRouter | OPENROUTER_API_KEY | OpenAI 호환 | Yes |
| Azure | AZURE_API_KEY | OpenAI SDK (Azure) | Yes |
| Bedrock | AWS_ACCESS_KEY_ID | 커스텀 | No |
| Cloudflare | CLOUDFLARE_API_TOKEN | 커스텀 | No |
| Together | TOGETHERAI_API_KEY | OpenAI 호환 | No |
| Fireworks | FIREWORKS_API_KEY | OpenAI 호환 | No |
| DeepSeek | DEEPSEEK_API_KEY | OpenAI 호환 | No |
| Perplexity | PERPLEXITYAI_API_KEY | OpenAI 호환 | No |
| DeepInfra | DEEPINFRA_API_TOKEN | OpenAI 호환 | No |
| Gemini | GEMINI_API_KEY | OpenAI 호환 | No |
| Cohere | COHERE_API_KEY | OpenAI 호환 | No |
| Ollama | — | OpenAI 호환 | No |
| vLLM | — | OpenAI 호환 | No |
| LM Studio | — | OpenAI 호환 | No |
API 키
프로바이더의 환경 변수를 설정합니다:
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
또는 직접 전달할 수도 있습니다:
litelm.completion("openai/gpt-4o", messages=[...], api_key="sk-...")
litelm.completion("openai/gpt-4o", messages=[...], api_base="http://localhost:8000/v1")
에러 처리
모든 프로바이더 에러는 litelm의 예외 계층으로 매핑됩니다:
from litelm import ContextWindowExceededError, RateLimitError, AuthenticationError
try:
response = litelm.completion("openai/gpt-4o", messages=messages)
except ContextWindowExceededError:
# 프롬프트가 너무 긺 — 잘라내고 재시도
pass
except RateLimitError:
# 백오프 필요
pass
except AuthenticationError:
# 잘못된 API 키
pass
툴 호출
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
},
},
}]
response = litelm.completion(
"openai/gpt-4o",
messages=[{"role": "user", "content": "파리 날씨 어때?"}],
tools=tools,
tool_choice="required",
)
tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name, tool_call.function.arguments)
커스텀 / 로컬 프로바이더
(원문 발췌 종료)