跳到主要內容

【2026 最新】LiteLM 實戰:5 步驗收多供應商路由,和 LLM Gateway 差在哪?

最後更新: ·
LiteLM 實戰教學首圖,以開口控制面呈現路由核心不等於完整 LLM Gateway

LiteLM 實戰最容易踩的坑,不是安裝失敗,而是把一個 Python library 當成完整 LLM Gateway。這個 alpha 專案以「約 2,900 行、2 個依賴、19 個 provider 路由目標」在 Show HN 吸引注意;但我們在 pinned tree 依「所有 litelm/**/*.py 實體行、含空白與註解」重數是 3,121 行,兩個也只指 direct base runtime dependencies。熱度與小巧都不等於 production readiness,真正要問的是:它替你完成哪一段,又把哪些責任留給應用程式?

這篇會先用不需要 API Key 的 mock request 跑通呼叫,再用同一組 contract 思維檢查 streaming、tool calling、錯誤、跨供應商 fallback 與 trace 收據。先把結論說在前面:LiteLM 適合學習 provider 路由、在單一 Python 應用內統一呼叫介面;它本身不是可讓 OpenAI client 連入的 HTTP Proxy。

先記住這條判斷式:LiteLM = provider/model 路由+格式翻譯;完整 Gateway = 這類呼叫核心+HTTP 入口+身分驗證/限流+跨 Provider fallback+端到端觀測。這是責任邊界的心智模型,不代表每個 Gateway 都採用 LiteLM。

LiteLM 實戰先說結論:小而可讀,但不是 Gateway

⚡ 三句話版:
一、截至 v0.5.2,LiteLM 提供 Python 函式,不提供 Proxy server;你不能只啟動它,就讓既有 OpenAI SDK 改一個 base_url 連入。
二、provider/model 可決定單次呼叫去哪裡,但 Router、load balancing 與跨供應商 fallback 不在其宣告範圍。
三、先用 mock 與 contract tests 理解介面,再用你自己的故障注入與 trace 收據驗收;需要多人共用的網路入口時,另選 Gateway 或自行補齊控制面。

LiteLM v0.5.2 README把範圍寫得很直接:保留 model routing、訊息格式轉換、streaming、tool use、embeddings,以及選定上游有 OpenAI-compatible Responses endpoint 時的 SDK passthrough;排除 Router、Proxy、cache、預算與成本追蹤。這也是它和名稱只多一個大寫 L 的 LiteLLM AI Gateway最關鍵的差別。

LiteLM 從 provider model 路由到格式轉換與標準化回應的請求生命週期圖
LiteLM 處理的是 Python 程序內的呼叫路徑:解析 provider 前綴、選 handler、翻譯請求、呼叫上游,再標準化回應;HTTP 入口、集中權限與跨供應商策略仍在外層。

LiteLM 到底做什麼?先拆開一個 request

  1. 解析目標:openai/model-nameanthropic/model-name 這類前綴決定 provider;沒有前綴時預設走 OpenAI。
  2. 選擇呼叫路徑:Anthropic、Cloudflare、Mistral 等有客製 handler;許多其他服務走 OpenAI-compatible endpoint。
  3. 轉換輸入:把 messages、tools 與部分 provider 特有欄位整理成對方接受的格式。
  4. 送出上游呼叫:在同一個 Python process 內使用 SDK 或 HTTP client;這一步不是接收外部 client 的 Proxy。
  5. 標準化輸出:整理文字、串流 chunk、tool call,並映射部分起始呼叫的常見錯誤;多數 route 在串流開始後拋出的例外仍可能保留原 SDK 型別。

原始碼雖有 Bedrock handler,但 AlphaLab 在 v0.5.2 與相同 package code 的 main 快照重現:未顯式傳入 api_key 的一般 bedrock/... 路徑,會先在 provider parserkey_env=None 傳入 os.environ.get(),觸發 TypeError,尚未走到 handler。這就是「路由表有一列」不能等同「目前可用」的具體反例。

這個設計和AI Agent Harness的想法相同:薄薄的模型呼叫層只是系統的一部分;外面還要有 secrets、policy、eval、觀測與部署邊界。如果你想看完整 Gateway 的 OpenTelemetry、cache 與 failover 驗收,可搭配AI Gateway 故障實驗閱讀。

LiteLM 實戰步驟 1:鎖版安裝,先跑零成本 mock

本文以 2026 年 9 月 11 日發布的 v0.5.2 為基準;PyPI 要求 Python 3.10 以上。先建獨立環境並鎖版,不要讓明天的新 release 偷換掉今天的結果。

python3 -m venv .venv
. .venv/bin/activate
python -m pip install "litelm==0.5.2"

python - <<'PY'
import litelm

r = litelm.completion(
    "openai/demo-model",
    messages=[{"role": "user", "content": "ping"}],
    mock_response="pong",
)
print(litelm.__version__, r.choices[0].message.content)
PY

預期輸出是 0.5.2 pong。它只證明套件可載入、completion contract 與標準化回應可走通,不證明 OpenAI 或任何真實 provider 已連線。這種把證據拆小的做法,也適合放進從零建立 AI Agent Harness的 smoke gate。

步驟 2:用環境變數替換 provider,不把模型名寫死

真正呼叫時,讓部署環境決定 target 與金鑰。下方 LLM_TARGET 必須換成帳戶目前可用的真實模型;範例刻意不硬編一個可能退役的 model ID。

export LLM_TARGET='openai/<your-model>'
export OPENAI_API_KEY='<your-key>'

python - <<'PY'
import os, litelm

response = litelm.completion(
    os.environ["LLM_TARGET"],
    messages=[{"role": "user", "content": "只回答 OK"}],
    timeout=20,
)
print(response.choices[0].message.content)
PY

要換到 OpenRouter、Groq 或自架 OpenAI-compatible endpoint,可改 target、對應金鑰或 api_base;但「語法能路由」仍不等於「每個模型的參數與回應完全等價」。api_base 會收到解析後的 bearer key,只能由受信任部署設定控制,不要讓終端使用者任意指定。需要固定上游、避免 provider 漂移時,可延伸使用OpenRouter Provider Pinning的驗收方法。

步驟 3:先寫 streaming 與 tool calling 的驗收條件

Streaming 至少要驗證三件事:首段文字是否在門檻內到達、空 choices/空 delta 不會弄壞 UI、中途斷線能被記錄。Tool calling 則要檢查 tool name、arguments 是否為合法 JSON、未知工具是否拒絕。LiteLM 只回傳 tool call;真正執行函式、驗證參數與權限仍是你的應用責任。

python - <<'PY'
import os, time, litelm

started, first_text_ms, pieces = time.monotonic(), None, []
for chunk in litelm.completion(
    os.environ["LLM_TARGET"],
    messages=[{"role": "user", "content": "用三個字打招呼"}],
    stream=True, timeout=20,
):
    if not chunk.choices:
        continue
    text = chunk.choices[0].delta.content or ""
    if text and first_text_ms is None:
        first_text_ms = (time.monotonic() - started) * 1000
    pieces.append(text)
assert first_text_ms is not None and "".join(pieces)
print({"first_text_ms": round(first_text_ms, 1), "text": "".join(pieces)})
PY
python - <<'PY'
import json, os, litelm

tools = [{"type": "function", "function": {
    "name": "get_weather",
    "parameters": {"type": "object", "properties": {
        "city": {"type": "string"}}, "required": ["city"]},
}}]
r = litelm.completion(os.environ["LLM_TARGET"],
    messages=[{"role": "user", "content": "查台北天氣"}],
    tools=tools, tool_choice="required", timeout=20)
call = r.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)
assert call.function.name == "get_weather" and isinstance(args["city"], str)
print({"tool": call.function.name, "args": args})
PY

這兩段是需要真實模型能力的 success-path probes,不是完成的 failure-path contract,也不是 AlphaLab 已替所有 route 跑過的成績。請先替 first_text_ms 寫下自己的 SLO 門檻,再用可控制的 OpenAI-compatible stub 注入首段後斷線。把同一批合法、未知工具、壞 JSON 與故意中斷的 requests 分別送到每個候選 target,保存 request ID、首段延遲、完成原因、tool arguments、usage 與實際錯誤型別;不要把 capability helper 當成即時保證。這才是OpenRouter 六組 Contract Tests所強調的「同一把尺」。

步驟 4:重試和 fallback 要分開,並保留 trace 收據

Retry 是同一 target 再試一次;fallback 是改投另一個 target。兩者混在一起,事故後就無法回答「到底呼叫了誰」。截至 v0.5.2,README 明列 Router/fallbacks 不在 LiteLM 範圍;目前原始碼也會移除傳入的 fallbacks。另一方面,OpenAI-compatible 路徑可把 max_retriesnum_retries 交給 SDK,但客製 handler 並未一致接收,retry_strategy 也會被移除;所以不能宣稱有跨 provider 一致的 retry policy。

最小可驗收做法,是在應用層維護有序 target 清單,只有 rate limit、timeout、連線或 5xx 類型才允許轉移;authentication、權限、格式錯誤應直接失敗。每次應用層 retry/fallback 決策至少留下 target、attempt、decision、error type 與 latency;這不會揭露 SDK 內部每個 HTTP attempt。正式版本再補 status code、upstream request ID、總 deadline、Retry-After、指數 backoff 與 jitter,但不要把 prompt 或金鑰寫入收據。

import time, litelm
from litelm import APIConnectionError, InternalServerError, RateLimitError, Timeout

RETRYABLE = (RateLimitError, Timeout, APIConnectionError, InternalServerError)

def call_with_fallback(targets, messages, *, invoke=litelm.completion,
                       retryable_errors=RETRYABLE, retries_per_target=1):
    receipt = []
    for target_index, target in enumerate(targets):
        for attempt in range(1, retries_per_target + 2):
            started = time.monotonic()
            try:
                result = invoke(target, messages=messages, timeout=20)
            except retryable_errors as exc:
                can_retry = attempt <= retries_per_target
                has_fallback = target_index < len(targets) - 1
                decision = "retry" if can_retry else "fallback" if has_fallback else "exhausted"
                receipt.append({"target": target, "attempt": attempt, "ok": False,
                    "decision": decision, "error_type": type(exc).__name__,
                    "latency_ms": round((time.monotonic() - started) * 1000, 3)})
                if can_retry:
                    continue
                break
            receipt.append({"target": target, "attempt": attempt, "ok": True,
                "decision": "return", "error_type": None,
                "latency_ms": round((time.monotonic() - started) * 1000, 3)})
            return result, receipt
    raise RuntimeError(f"all targets failed: {receipt}")

這是可測的 state machine,不是完整 production retry library。AlphaLab 對同一份函式注入可重試例外,重現決策順序 [retry, fallback, return];另注入不在 allowlist 的 authentication 類錯誤,確認它直接拋出且不會轉投。接著仍要測「兩個都失敗」與「stream 已輸出部分內容後不得重播」。跨 provider 可能重複計費,也可能把資料送往不同司法轄區;target 必須先經 allowlist,而不是見錯就全送一輪。

步驟 5:跑兩層測試,別把 maintainer claim 當你的結果

AlphaLab 在 LiteLM main commit 4a260c7、Python 3.14.7 的隔離環境跑了兩層不需供應商金鑰的檢查:專案非 live suite 為 262 passed、55 skipped;同步到當時 LiteLLM upstream commit 9276317 後,專案挑選的快速 ported contract 為 49 passed。這個 main 只比 v0.5.2 tag 多一個文件/測試/腳本 commit,package source 相同;官方 CI 範圍是 Python 3.10–3.13,並不包含我們的 3.14.7 環境。

Mock completion 另回傳版本 0.5.2 與內容 pong,故障注入收據也通過上述三段決策。這些結果只支持「本機 contract 在該快照可重現」;快速 ported gate 是 49 個 allowlisted nodes,官方 CI 也不跑這道 gate 或 live provider tests,不能外推成完整 LiteLLM parity。維護者的表宣告 19 個 canonical routing targets,其中 7 個標成 verified、12 個仍是 No;專案狀態也明寫 Alpha。AlphaLab 沒有執行付費 live provider 測試。

LiteLM library 與完整 LLM Gateway 的責任邊界及採用判斷圖
LiteLM 的優勢是呼叫路徑小、容易閱讀;完整 Gateway 的價值則在共享 HTTP 入口、集中政策、跨供應商可靠性與可觀測性。兩者解的是不同層級的問題。

何時適合 LiteLM?何時直接選完整 Gateway?

  • 適合學習:想讀懂 provider 路由、訊息翻譯、stream chunk 與錯誤標準化,而且願意接受 alpha 變動。
  • 可評估內網單一應用:只有一個受控 Python service,自行管理金鑰、重試、fallback、log 與部署,並有鎖版和 rollback。
  • 不該只靠 LiteLM:多個團隊或 client 要共用 HTTP endpoint,需要 API key 管理、rate limit、預算、集中稽核、負載平衡或跨 provider failover。

若需求落在第三種,請比較有明確 Gateway contract 的產品。以 LiteLLM 官方文件為例,它另有 Proxy 與跨供應商 fallback/可靠性設定;選擇標準不該是程式碼行數最少,而是事故時能否證明 policy 真有執行。想從系統層建立完整清單,可再讀AI Agent Harness 實作指南

常見問題 FAQ

LiteLM 是 LiteLLM 的官方精簡版嗎?

不是。兩者是不同套件與 repository;LiteLM 的目標是相容部分 Python 呼叫面,不能從名稱推定官方從屬關係。

LiteLM 可以直接當 OpenAI-compatible Proxy 嗎?

不可以單獨做到。v0.5.2 不提供 Proxy server;若要讓外部 OpenAI client 透過 base_url 連線,必須自建 HTTP 層或選擇現成 Gateway。

「19 個 routing targets」代表全部實測通過嗎?

不代表。截至本文版本,19 個是 canonical 路由目標,不全是公司;registry 另含別名。維護者只把其中 7 個標成 verified,AlphaLab 也沒有執行付費 live provider 測試。

LiteLM 會自動跨供應商 fallback 嗎?

不會。README 明列 Router/fallbacks 不在範圍;需要時應由應用層明確實作,或交給有此 contract 的 Gateway。

Tool calling 會替我執行函式嗎?

不會。它標準化模型回傳的 tool call;白名單、參數驗證、真正執行與結果回傳仍屬應用責任。

內建 callback 足以做 production tracing 嗎?

目前不夠完整。v0.5.2 相同 package source只對成功、非 streaming 的 completionacompletion chat calls 提供 success callback;失敗、stream、embedding、Responses、text completion 與跨 target attempt 應在外層補收據。

2 個 direct runtime dependencies 就代表風險更低嗎?

不能只看數量下結論。兩個只是 base requirements;它們的 transitive packages、optional SDK、上游服務、版本更新與你補上的 Proxy/觀測層仍要一起盤點。

新手第一個 production gate 應該是什麼?

先驗證失敗路徑。固定版本與模型,注入 timeout、429、5xx、authentication error 和串流中斷,確認每次應用層 retry/fallback 決策都可由 trace 收據還原。

給新手的 5 個重點

  1. LiteLM 是程序內的多供應商呼叫 library,不是可直接對外服務的 Gateway。
  2. provider/model 解決路由語法,不自動帶來負載平衡或跨供應商 fallback;retry 行為也不是所有 handler 一致。
  3. 先用 mock 和 non-live tests 驗證 contract,再用自己的 provider 金鑰做 live acceptance。
  4. Streaming、tool calling、錯誤與 fallback 都要用故障情境驗收,並保留逐次 attempt 收據。
  5. 選型看責任邊界與可證明的 SLO,不看最少行數或一次熱門討論。

結語:LiteLM 的價值,在於讓邊界看得見

LiteLM 最值得學的不是「行數少就能取代所有 Gateway」,而是把 provider routing 與格式翻譯縮到可以讀懂的尺度。先跑 mock、再跑 contract、最後故意讓 timeout 與上游失敗發生;如果你能從收據還原每次應用層路由決策,它就可能是合適的內部呼叫層。若還需要共享 HTTP 入口、中央政策與營運控制,就把那些責任明確交給 Gateway。想把這套驗收延伸成完整工作流,也可從 AlphaLab 的AI 與投資實戰課程繼續學。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。