測驗:LiteLLM 為什麼你需要一個 LLM 統一閘道
共 5 題,點選答案後會立即顯示結果
1. LiteLLM 要解決的核心痛點是什麼?
2. 用 LiteLLM 時,若想從 OpenAI 換成 Anthropic Claude,通常需要改動什麼?
3. 以下這段程式,要拿到「AI 回覆的文字」,應該讀哪個欄位?
4. LiteLLM 的 model 字串格式是 供應商/模型名稱。當你寫 anthropic/claude-sonnet-4-20250514 時,LiteLLM 會自動去找哪一把 key?
5. 關於 LiteLLM 的 SDK 模式與 Proxy Server 模式,下列敘述何者正確?
一句話說明
LiteLLM 把 100+ 家 LLM 供應商的 API 全部統一成同一種格式,換模型只要改一個字串。
你為什麼會需要它
假設你的 AI 專案這樣長大:
- 一開始用 OpenAI 的
gpt-4o,程式照著 OpenAI SDK 寫。 - 老闆說 Claude 比較會寫程式,改用 Anthropic —— 你發現 Anthropic 的 SDK 長得完全不一樣,回傳結構也不一樣,一堆地方要改。
- 過幾週又想試 Google Gemini —— 再學一套 SDK、再改一輪。
每換一家,你(或 AI)就得重寫呼叫程式、重寫解析回應的程式。這就是 LiteLLM 要解決的核心痛點:
**每家 LLM 供應商的 API 格式都不一樣,切換成本很高。**
LiteLLM 的作法是:不管背後是哪一家,你都用「OpenAI 的格式」去呼叫、也用「OpenAI 的格式」拿回結果。換供應商 = 改 model 參數的字串,其他程式碼原封不動。
LiteLLM 是什麼
它其實是兩個東西,這系列先講第一個:
| 模式 | 是什麼 | 適合誰 |
|---|---|---|
| SDK 模式(本篇) | 一個 Python 函式庫,import litellm 直接在程式裡呼叫 |
單一應用、寫腳本、快速試 |
| Proxy Server 模式(後續篇章) | 一個獨立跑起來的閘道伺服器,多個應用共用、統一管 key 與用量 | 團隊、多服務、要控管成本 |
兩個模式的「呼叫格式」是一樣的(都是 OpenAI 相容格式),差別只在「跑在你程式裡」還是「跑成一台獨立服務」。本篇聚焦 SDK,先把最核心的一行學會。
30 秒範例
安裝:
uv add litellm
# 或 pip install litellm
Code language: PHP (php)設定 API key(用環境變數,不要寫死在程式裡):
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
export GEMINI_API_KEY="..."
Code language: JavaScript (javascript)最小可執行範例:
from litellm import completion
response = completion(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "用一句話解釋什麼是 API"}],
)
print(response.choices[0].message.content)
Code language: JavaScript (javascript)這段代碼做了什麼:
- 從 litellm 匯入
completion這個函式(你唯一需要記住的入口)。 - 呼叫它,告訴它「用哪個模型」(
model)、「對話內容是什麼」(messages)。 - 從回傳結果裡把 AI 講的那句話挖出來印出。
如果你以前用過 OpenAI 的 SDK,會覺得 messages 這個格式很眼熟 —— 沒錯,這就是重點:LiteLLM 故意長得跟 OpenAI 一樣。
換供應商,只改一個字串
同樣一段程式,想換成 Claude 或 Gemini,只動 model:
# OpenAI
response = completion(model="openai/gpt-4o", messages=messages)
# Anthropic Claude
response = completion(model="anthropic/claude-sonnet-4-20250514", messages=messages)
# Google Gemini
response = completion(model="gemini/gemini-2.0-flash", messages=messages)
Code language: PHP (php)其餘的程式(messages 怎麼組、response.choices[0].message.content 怎麼讀)完全不用改。這就是「統一閘道」的價值。
model 字串的格式是 供應商/模型名稱,例如 openai/、anthropic/、gemini/ 開頭。LiteLLM 看到前綴就知道要去呼叫哪一家、要用哪一把 key(它會自動去找對應的環境變數,例如 anthropic/... 就找 ANTHROPIC_API_KEY)。
核心概念翻譯
看 AI 寫 LiteLLM 的程式時,這張表對照著讀:
| 你會看到 | 意思 |
|---|---|
from litellm import completion |
匯入唯一的主要入口函式 |
model="openai/gpt-4o" |
用哪一家的哪個模型,格式是 供應商/模型 |
messages=[{"role": ..., "content": ...}] |
對話內容,一則一則訊息組成的清單 |
"role": "user" |
這則是「使用者」說的話 |
"role": "system" |
給模型的設定指令(例如「你是一個翻譯助手」) |
"role": "assistant" |
這則是 AI 之前回過的話(多輪對話時會出現) |
response.choices[0].message.content |
AI 回覆的文字內容 |
response.usage |
這次用了多少 token(跟計費有關) |
逐行解讀回應物件
completion() 回來的東西不是一個字串,是一個結構化物件。搞懂它的長相,你才知道要從哪裡挖資料。印出來大概長這樣(簡化版):
ModelResponse(
id="chatcmpl-abc123",
choices=[
Choices(
index=0,
message=Message(
role="assistant",
content="API 是讓兩個程式互相溝通的介面。",
),
finish_reason="stop",
)
],
usage=Usage(
prompt_tokens=15,
completion_tokens=20,
total_tokens=35,
),
)
Code language: JavaScript (javascript)一層一層翻譯:
response.choices # 一個清單,裝著模型給的所有回答(通常只有 1 個)
response.choices[0] # 取第一個回答(index 0)
.message # 這個回答的訊息本體
.content # 訊息的文字 ← 99% 的時候你要的就是這個
.role # 是誰說的,這裡固定是 "assistant"
response.choices[0].finish_reason # 為什麼停下來,"stop" = 正常講完
# "length" = 撞到長度上限被截斷了
response.usage.prompt_tokens # 你送進去的 token 數
response.usage.completion_tokens # 模型回覆的 token 數
response.usage.total_tokens # 兩者相加(帳單看這個)
Code language: PHP (php)為什麼是 choices 而且還是清單? 因為 OpenAI 格式允許一次要模型生成多個候選答案(設 n=3 就會有 3 個)。預設只有一個,所以你幾乎永遠是寫 choices[0]。這是 LiteLLM 照抄 OpenAI 格式的結果,不是它自己發明的。
看不懂某個欄位?把整個
response印出來,貼給 AI 問:「這個物件每個欄位是什麼意思,我要拿 AI 回覆的文字該讀哪個?」
AI 最常這樣用
用法 1:加一則 system 訊息設定角色
response = completion(
model="anthropic/claude-sonnet-4-20250514",
messages=[
{"role": "system", "content": "你是一個只回覆繁體中文的助手"},
{"role": "user", "content": "Explain recursion"},
],
)
Code language: JavaScript (javascript)翻譯:system 那則是「幕後設定」,user 那則才是這次真正的問題。
用法 2:串流輸出(一個字一個字吐)
response = completion(
model="openai/gpt-4o",
messages=messages,
stream=True, # 打開串流
)
for chunk in response: # 一塊一塊收
print(chunk.choices[0].delta.content or "", end="")
Code language: PHP (php)翻譯:stream=True 時回來的不是完整結果,而是一段一段的碎片,要用 for 迴圈收。注意這時候讀的是 delta.content(增量),不是 message.content。看到 delta 就知道這是串流。
用法 3:常見參數
response = completion(
model="openai/gpt-4o",
messages=messages,
temperature=0.7, # 隨機性,0 = 最穩定/可重現,越高越有創意
max_tokens=500, # 最多回這麼多 token,防止太長
)
Code language: PHP (php)翻譯:這些參數是所有供應商共通的,LiteLLM 會幫你翻譯成各家自己的講法。
🚩 紅旗
紅旗 1:API key 寫死在程式裡
completion(model="openai/gpt-4o", messages=m, api_key="sk-proj-abc123...") # 🚩 金鑰硬編碼
Code language: PHP (php)寫死的 key 一旦被 commit 進 git,等於公開你的付費帳號,別人可以拿去燒你的錢。
跟 AI 這樣說:「把 API key 改成從環境變數讀,不要寫死在程式裡,也不要 commit 進版控。」
紅旗 2:直接讀 content 卻沒處理可能的 None
text = response.choices[0].message.content
print(text.upper()) # 🚩 content 可能是 None(例如模型只回了 tool call),會直接爆掉
Code language: PHP (php)跟 AI 這樣說:「這裡 content 有沒有可能是 None?如果會,幫我加上防呆處理。」
紅旗 3:吞掉錯誤,供應商掛了你也不知道
try:
response = completion(model="openai/gpt-4o", messages=m)
except Exception:
pass # 🚩 網路錯誤、餘額不足、key 失效全被吃掉,靜默失敗
Code language: PHP (php)跟 AI 這樣說:「不要用 except: pass 把錯誤吞掉,至少把錯誤 log 出來,並告訴我 LiteLLM 有哪些常見的例外類型可以分別處理。」
Vibe Coder 驗收檢查點
- [ ] 跑
uv add litellm,確認安裝成功沒報錯。 - [ ] 設好至少一家的環境變數(如
export OPENAI_API_KEY=...),跑最小範例,應該印出一句 AI 回覆。 - [ ] 把範例的
model從openai/gpt-4o改成另一家(如anthropic/...),其他程式不動,確認一樣能跑 —— 這就驗證了「統一閘道」。 - [ ] 印出完整
response,找到choices[0].message.content和usage.total_tokens在哪。 - [ ] 檢查 AI 寫的程式裡,API key 是不是從環境變數讀,而不是寫死的字串。
- [ ] 問 AI:「這段 completion 呼叫如果供應商回錯誤或餘額不足,會發生什麼?有沒有處理?」
看不懂就這樣問 AI
「我在用 LiteLLM 的
completion(),把這段回應物件印出來後,請一個欄位一個欄位用白話解釋,並告訴我要拿 AI 回覆的文字該讀哪個欄位。我是初學者。」
「請把這段 OpenAI SDK 的程式改寫成用 LiteLLM 的
completion(),並解釋你改了哪些地方、為什麼。」
延伸:知道就好
這些遇到再查就好,不用現在鑽:
acompletion():completion()的非同步版本,AI 寫 FastAPI 這類服務時會用到。看到await acompletion(...)就知道是同一個東西的 async 版。- Router / fallbacks:設定「A 家掛了自動改打 B 家」的容錯機制,屬於進階可靠性設定。
litellm.set_verbose/ callbacks:把每次呼叫的細節印出來或送到監控系統,除錯與觀測用。- Proxy Server 模式:把 LiteLLM 跑成獨立閘道服務,統一管 key、限流、記帳 —— 這是本系列後面的重點。
一句話總結
LiteLLM 讓你用同一套 OpenAI 格式呼叫任何一家 LLM,換供應商只改 model 字串。 記住三件事就夠上手:入口是 completion()、輸入是 messages、輸出讀 choices[0].message.content。
進階測驗:LiteLLM 為什麼你需要一個 LLM 統一閘道
共 5 題,包含情境題與錯誤診斷題。