【LiteLLM 完全入門】#01 為什麼你需要一個 LLM 統一閘道

測驗:LiteLLM 為什麼你需要一個 LLM 統一閘道

共 5 題,點選答案後會立即顯示結果

1. LiteLLM 要解決的核心痛點是什麼?

  • A. LLM 模型的回答品質不夠好
  • B. 每家 LLM 供應商 API 格式不一,切換成本高
  • C. LLM 的 token 計費太貴
  • D. Python 沒有官方的 LLM 函式庫

2. 用 LiteLLM 時,若想從 OpenAI 換成 Anthropic Claude,通常需要改動什麼?

  • A. 整段呼叫與解析回應的程式都要重寫
  • B. 要換掉整個函式庫
  • C. 只改 model 參數的字串
  • D. 重寫 messages 的資料格式

3. 以下這段程式,要拿到「AI 回覆的文字」,應該讀哪個欄位?

response = completion(model=”openai/gpt-4o”, messages=messages)
  • A. response.choices[0].message.content
  • B. response.content
  • C. response.message.text
  • D. response.usage.total_tokens

4. LiteLLM 的 model 字串格式是 供應商/模型名稱。當你寫 anthropic/claude-sonnet-4-20250514 時,LiteLLM 會自動去找哪一把 key?

  • A. OPENAI_API_KEY
  • B. LITELLM_API_KEY
  • C. ANTHROPIC_API_KEY
  • D. 不需要 key,LiteLLM 免費代打

5. 關於 LiteLLM 的 SDK 模式與 Proxy Server 模式,下列敘述何者正確?

  • A. 兩者的呼叫格式完全不同,要各學一套
  • B. SDK 模式必須先啟動一台獨立伺服器
  • C. Proxy 模式只能給單一應用使用
  • D. 兩者呼叫格式相同,差別在「跑在程式裡」還是「跑成獨立服務」

一句話說明

LiteLLM 把 100+ 家 LLM 供應商的 API 全部統一成同一種格式,換模型只要改一個字串。


你為什麼會需要它

假設你的 AI 專案這樣長大:

  1. 一開始用 OpenAI 的 gpt-4o,程式照著 OpenAI SDK 寫。
  2. 老闆說 Claude 比較會寫程式,改用 Anthropic —— 你發現 Anthropic 的 SDK 長得完全不一樣,回傳結構也不一樣,一堆地方要改。
  3. 過幾週又想試 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)

這段代碼做了什麼

  1. 從 litellm 匯入 completion 這個函式(你唯一需要記住的入口)。
  2. 呼叫它,告訴它「用哪個模型」(model)、「對話內容是什麼」(messages)。
  3. 從回傳結果裡把 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 回覆。
  • [ ] 把範例的 modelopenai/gpt-4o 改成另一家(如 anthropic/...),其他程式不動,確認一樣能跑 —— 這就驗證了「統一閘道」。
  • [ ] 印出完整 response,找到 choices[0].message.contentusage.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 題,包含情境題與錯誤診斷題。

1. 情境判斷 情境題

你的服務目前用 openai/gpt-4o 跑得好好的,程式裡已經組好 messages、 也用 response.choices[0].message.content 解析回覆。 老闆要你「試試 Gemini 看效果如何」,希望改動越小越好。
  • A. 安裝 Google 官方 SDK,重寫呼叫與解析邏輯
  • B. 只把 model 改成 gemini/gemini-2.0-flash 並設好 GEMINI_API_KEY,其餘不動
  • C. 把 messages 的格式改成 Gemini 專用格式
  • D. 一定要先啟動 LiteLLM Proxy Server 才能換

2. 選擇正確的存取方式 情境題

你想做一個「打字機效果」的聊天介面,希望模型的回覆一個字一個字 即時顯示,而不是等整段生成完才出現。你在 completion() 加了 stream=True。
  • A. 直接讀 response.choices[0].message.content
  • B. 用 response.usage 逐字取出
  • C. 用 for chunk in response 迴圈收,讀 chunk.choices[0].delta.content
  • D. 呼叫 response.stream() 方法

3. 需求:可重現的輸出 情境題

你在寫測試,希望同樣的 prompt 每次跑出來的結果盡量一致、 可重現,減少隨機性。應該調整哪個參數?
  • A. 把 temperature 設成 0
  • B. 把 max_tokens 設成 0
  • C. 把 temperature 設成 1.0
  • D. 把 stream 設成 True

4. 找出程式的問題 錯誤診斷

from litellm import completion response = completion( model=”openai/gpt-4o”, messages=[{“role”: “user”, “content”: “hi”}], api_key=”sk-proj-abc123realkey…”, )
  • A. model 字串格式錯誤,不該有斜線
  • B. API key 硬編碼在程式裡,一旦 commit 進 git 就會外洩帳號
  • C. messages 少了 system 訊息,無法執行
  • D. completion 不能傳 api_key 參數

5. 診斷潛在崩潰 錯誤診斷

response = completion(model=”openai/gpt-4o”, messages=m) text = response.choices[0].message.content print(text.upper())
  • A. 完全沒問題,content 一定是字串
  • B. 應該讀 delta.content 而不是 message.content
  • C. content 有可能是 None(例如模型只回 tool call),None.upper() 會拋錯
  • D. choices 不是清單,不能用 [0]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *