메뉴
HN
Hacker News • 14일 전

리텔름(litelm): LiteLLM에서 꼭 필요한 기능만 남긴 초경량 라이브러리

IMP
6/10
핵심 요약

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)

커스텀 / 로컬 프로바이더

(원문 발췌 종료)

원문 보기
원문 보기 (영어)
litelm litellm's routing + translation in ~2,900 lines and 2 dependencies ( openai , httpx ). litellm routes LLM calls across providers and translates between message formats. That core is buried under 100k+ LOC of proxy servers, caching layers, cost tracking, and dozens of features most users never touch. litelm extracts just the call path — model routing, message translation, streaming, tool use, embeddings — and nothing else. No Router class, no proxy, no caching. Install pip install litelm # openai + httpx pip install litelm[anthropic] # + anthropic SDK pip install litelm[bedrock] # + boto3 pip install litelm[all] # everything Usage import litelm # Basic completion response = litelm . completion ( "openai/gpt-4o" , messages = [{ "role" : "user" , "content" : "Hello!" }]) print ( response . choices [ 0 ]. message . content ) # Streaming for chunk in litelm . completion ( "groq/llama-3.1-70b-versatile" , messages = [...], stream = True ): print ( chunk . choices [ 0 ]. delta . content or "" , end = "" ) # Embeddings response = litelm . embedding ( "openai/text-embedding-3-small" , input = [ "hello world" ]) Every function has an async variant: acompletion , aembedding , aresponses , atext_completion . The API mirrors litellm — same function names, same arguments, same response types. If you're using litellm today, switching is s/litellm/litelm/ in your imports. What's in / what's out litellm litelm Model routing ( provider/model → right endpoint) ✓ ✓ Message translation (Anthropic, Bedrock, Cloudflare, Mistral) ✓ ✓ Streaming + stream_chunk_builder ✓ ✓ Tool use (function calling) ✓ ✓ Embeddings ✓ ✓ Text completions ✓ ✓ OpenAI Responses API ✓ ✓ Mock responses ✓ ✓ Router (load balancing, fallbacks) ✓ ✗ Proxy server ✓ ✗ Caching / budgeting / cost tracking ✓ ✗ Token counting ✓ ✗ Image gen, audio, OCR, fine-tuning ✓ ✗ Agents, guardrails, scheduler ✓ ✗ Providers Routes to 19 providers via "provider/model-name" syntax. Any OpenAI-compatible endpoint works via api_base . Provider Env Var Handler Verified OpenAI OPENAI_API_KEY OpenAI SDK Yes Anthropic ANTHROPIC_API_KEY Custom Yes Groq GROQ_API_KEY OpenAI-compat Yes Mistral MISTRAL_API_KEY Custom Yes xAI XAI_API_KEY OpenAI-compat Yes OpenRouter OPENROUTER_API_KEY OpenAI-compat Yes Azure AZURE_API_KEY OpenAI SDK (Azure) Yes Bedrock AWS_ACCESS_KEY_ID Custom No Cloudflare CLOUDFLARE_API_TOKEN Custom No Together TOGETHERAI_API_KEY OpenAI-compat No Fireworks FIREWORKS_API_KEY OpenAI-compat No DeepSeek DEEPSEEK_API_KEY OpenAI-compat No Perplexity PERPLEXITYAI_API_KEY OpenAI-compat No DeepInfra DEEPINFRA_API_TOKEN OpenAI-compat No Gemini GEMINI_API_KEY OpenAI-compat No Cohere COHERE_API_KEY OpenAI-compat No Ollama — OpenAI-compat No vLLM — OpenAI-compat No LM Studio — OpenAI-compat No API Keys Set the environment variable for your provider: export OPENAI_API_KEY=sk-... export ANTHROPIC_API_KEY=sk-ant-... Or pass directly: litelm . completion ( "openai/gpt-4o" , messages = [...], api_key = "sk-..." ) litelm . completion ( "openai/gpt-4o" , messages = [...], api_base = "http://localhost:8000/v1" ) Error Handling All provider errors are mapped to litelm's exception hierarchy: from litelm import ContextWindowExceededError , RateLimitError , AuthenticationError try : response = litelm . completion ( "openai/gpt-4o" , messages = messages ) except ContextWindowExceededError : # prompt too long — truncate and retry pass except RateLimitError : # back off pass except AuthenticationError : # bad API key pass Tool Calling tools = [{ "type" : "function" , "function" : { "name" : "get_weather" , "parameters" : { "type" : "object" , "properties" : { "city" : { "type" : "string" }}}, }}] response = litelm . completion ( "openai/gpt-4o" , messages = [{ "role" : "user" , "content" : "Weather in Paris?" }], tools = tools , tool_choice = "required" , ) tool_call = response . choices [ 0 ]. message . tool_calls [ 0 ] print ( tool_call . function . name , tool_call . function . arguments ) Custom / Local Providers Any OpenAI-compatible server works via api_base : # vLLM litelm . completion ( "openai/my-model" , messages = [...], api_base = "http://localhost:8000/v1" ) # Ollama litelm . completion ( "ollama/llama3" , messages = [...], api_base = "http://localhost:11434/v1" ) # LM Studio litelm . completion ( "openai/local-model" , messages = [...], api_base = "http://localhost:1234/v1" ) Development transparency litelm is human-directed, AI-assisted software. Much of the code was written with Claude Code using Claude Opus 4.6/4.7. Code written from 2026-05-14 onward is written through Pi using GPT-5.5. Compatibility claims are based on tests and maintainer review, not AI authorship. Upstream attestation Maintainer attestation, 2026-09-11: LiteLLM's routing/formatting changes were reviewed from 649eb2d through 9a715df2 . The audit triaged 360 core-path commits, inspected upstream tests for potentially relevant behavior, and fixed the resulting compatibility gaps test-first. Local scoped tests: 262 passed, 55 skipped ; all 45 available-provider live tests and all 10 DSPy smoke tests also passed with the current dependency lock. This attests litelm's declared routing/formatting/DSPy surface only, not full litellm compatibility. Status Alpha. 262 own tests passing. The current scoped LiteLLM 9a715df2 baseline has 75 passing ported tests and no remaining actionable assertion/runtime failures. DSPy drop-in verified — all 7 execution paths proven live (Predict, CoT, typed signatures, streaming, embeddings, tool use, multi-output). Tests uv run --extra all pytest tests/ -x --ignore=tests/ported --timeout=10 # 262 non-live tests bash scripts/ported_contract.sh # 49 fast upstream contract tests uv run --extra all pytest tests/test_live.py -m live --timeout=30 # 45 live provider tests uv run pytest tests/test_dspy_smoke.py -m live --timeout=60 # 10 DSPy integration tests Live tests require API keys in .env.test . Skipped by default; run with -m live .