AI 互動教室 ‹ 學 LLM 應用開發
下載 .py 開啟實戰 notebook ↗ 留言回報
LITELLM GATEWAY · 模型閘道

LiteLLM:一個網址、一把 key,
打遍八家模型

你寫過打 OpenAI API 的程式嗎?那你已經會用 LiteLLM 了。它是一個長得跟 OpenAI 一模一樣的入口, 背後卻接著 NVIDIA、Google、Groq、Cloudflare、OpenRouter……八家供應商。 程式碼寫死 model="nemotron-3.5-lightning",每一發請求會被分到這顆模型的兩個來源之一 (NVIDIA NIM/OpenRouter),哪家慢、哪家限流就換家——你的程式完全無感。先按幾次看看:

你的程式
openai SDK
LiteLLM
一個網址・一把 key
把 model 換成別的字串,亮起來的來源就會變。

右欄的 notebook 會真的打這個 gateway——課程提供一把教學用 key(只開免費模型, 課後會撤銷),不用申請任何帳號。每一節讀完就到 notebook 的同號章節動手。

01 · 為什麼要一個閘道

免費額度池化、模型名穩定、金鑰收斂

免費方案的共同特性是單家限流都很小:分鐘級 RPM、日配額都低,稍微跑個批次就 429。 gateway 把同一顆模型在不同供應商的免費額度掛在同一個名字下,一家撞牆就換下一家。 但池化只是第一個好處:

你寫的gateway 幫你做的
model="nemotron-3.5-lightning"同一顆 30B-A3B 輕量推理模型、兩個來源(NIM/OpenRouter)隨機分流,429/5xx 自動重試換家——本系列全程用它
model="nemotron-3-ultra"550B 旗艦,三個來源備援(想得慢,當對照組)
model="gemini-3.5-flash"指名單一供應商(需要特定能力時用,例如看圖)
一把 virtual key八把上游金鑰只存在 gateway;每把子 key 可設預算、限模型、看用量、隨時撤銷
一份程式碼上游漲價、換家、出新模型,只改 gateway 設定,所有程式立刻生效

連線只要兩行設定,SDK 是官方 openai 套件、一行都沒改:

from openai import OpenAI client = OpenAI( base_url="https://litellm.itsmygo.uk/v1", # 指到 gateway api_key="sk-FiIRnuzLH7ypgf29LTpHNw", # 教學用 virtual key ) models = sorted(m.id for m in client.models.list()) # 8 個模型名
到 notebook 的 0️⃣–1️⃣ 節:連上去、列出模型
02 · 第一次對話

回應物件裡藏了什麼,以及一個空字串的坑

client.chat.completions.create(model=..., messages=[...]) 拿回一個 ChatCompletion:回答在 choices[0].message.contentusage 是 token 帳單,model 是實際回應的模型。 notebook 裡有一個可以換模型、改問題的小面板——同一段程式碼,換的只是那個字串。

然後是這個 gateway 上最常見的「沒報錯卻沒答案」:nemotron-3.5-lightning推理型模型, 先在心裡想、再開口,而且想得不少(一句自我介紹先想 600 多個 token)。max_tokens=20 問 1+1, 實測回來的 content 是 "Here's a thinking process: 1. Analyze User Input…"—— 那不是答案,是被切斷的思考過程被當成 content 吐出來,finish_reason='length'。 給到 4096,答案 1+1=2 在 content,思考在非標準欄位 reasoning_contentreasoning_tokens 只有部分來源回報(OpenRouter 會、NIM 是 None)—— 同一個模型名、不同上游的痕跡。結論:對推理型模型 max_tokens 要裝得下思考+答案(本系列一律 4096)。

到 notebook 的 2️⃣–3️⃣ 節:發話、踩坑
03 · 串流與向量

兩個同一個入口就能用的能力

串流stream=True):回傳的不是一個物件而是一串 chunk, 每個 delta.content 是新增的幾個字。notebook 會把每個 chunk 的到達時間畫成階梯圖, 推理型模型的圖常有個特徵:前面一段是平的(它在想,思考過程不會串流出來), 想完文字才一口氣湧出——有時幾秒、有時不到一秒,看落到哪個來源。做聊天介面時,那段空白就是該放「思考中…」的地方。

向量client.embeddings.create):同一把 key、同一個入口, 模型換成 qwen3-embedding-0.6b,任何一段文字變成 1024 個數字。 意思相近的句子方向相近:實測「貓咪喜歡曬太陽」vs「小貓在窗邊打盹」餘弦相似度 0.54, vs「今天股市大跌」只有 0.21。這個模型回傳的已經是單位向量,內積就是 cosine。 這是後面 Qdrant 與 RAG 兩課的地基。

到 notebook 的 4️⃣–5️⃣ 節:串流階梯圖、相似度熱圖
04 · 並發與可觀察性

同時發 12 個,親眼看見輪替

批次推論的標準寫法是 AsyncOpenAI + asyncio.gather: 12 發同時出去,牆鐘時間 ≈ 最慢那一發,不是 12 倍(實測序跑要 55–90 秒、並發約 15–20 秒)。 但你怎麼知道 gateway 真的在換家?LiteLLM 每個回應都帶一個 header x-litellm-model-api-base,用 with_raw_response 讀出來,「隨機輪替」就從黑盒變成一張分佈圖。

同時盯著每一發的秒數:同一顆模型在不同來源的延遲不一樣——實測多數 2–5 秒,偶爾一發要等 10–30 秒。 失敗的也算進統計(紅色長條)。看見失敗與慢,本身就是可觀察性: 一家慢了、倒了,另一家照跑,你的程式碼一個字不用改,這正是 gateway 存在的理由。

到 notebook 的 6️⃣ 節:12 發並發、輪替分佈圖
05 · 實戰

換你動手

挑戰在 notebook 末節,由淺到深:

LEVEL 1

加一則 system 訊息「你只會用文言文回答」,看同一個問題的回答風格怎麼變。

LEVEL 2

把相似度熱圖的四句話換成你自己的(三句同主題、一句離題),先猜熱圖長相再跑;再換成 2048 維的 nemotron-3-embed-1b 比較。

LEVEL 3

nemotron-3-ultra(550B、三個來源)發 12 發,比較延遲與分佈跟 lightning 的差別;再算各來源的平均秒數——哪家最快、哪家最飄?

卡住了?每一題在 notebook 末節都有折疊解答——先自己做,再打開對照。

離開這堂課前記住兩件事:任何認得 OPENAI_BASE_URL / OPENAI_API_KEY 的工具(curl、LangChain、Open WebUI、aider)兩個變數指過來就能用; 正式專案請到 gateway 管理介面自己發一把 key,別用教學用的。

06 · 驗收

情境測驗

離開前試試看:下面的情境都真的會遇到。每題選一個你認為的最佳做法,選了馬上看得到解釋。

Q1 情境題

你手上有一支用官方 openai SDK 打 OpenAI API 的程式,現在想改走 LiteLLM gateway 用免費模型。應該怎麼做?

gateway 的入口長得跟 OpenAI API 一模一樣,官方 SDK 只要兩行設定(base_urlapi_key)就切過去。A 能動,但 litellm 套件是另一套用法,沒必要重寫;C 正是 gateway 要幫你消掉的苦工(限流換家它自動做);D 搞混了——model 永遠是模型名字串,來源選擇是 gateway 的事。

Q2 錯誤診斷

nemotron-3.5-lightning 問「1+1 等於幾」,max_tokens=20,沒報錯,但拿到這種回應。最可能的原因是?

content = "Here's a thinking process: 1. Analyze User Input…" finish_reason = 'length'

推理型模型的輸出=思考+答案,max_tokens 要裝得下兩者——finish_reason='length' 就是被截斷的鐵證。修法:調大 max_tokens(本系列一律 4096),答案就會出現在 content、思考搬去 reasoning_content。A 看 model 欄位可排除;B 的額度問題會直接回 4xx 錯誤,不會「成功但被砍」;D——給足 token 它答得出 1+1=2。

Q3 錯誤診斷

你用 stream=True 接推理型模型:送出後好幾秒完全沒有 chunk 到達,然後文字一口氣湧出。最可能的原因是?

這正是串流階梯圖「前段是平的」的原因:推理型模型的思考不會串流出來。A、C 症狀相似但每次都發生就不是網路或排隊;D 不成立——後面有逐字湧出就是串流在動。做聊天介面時,這段空白就是該顯示「思考中…」的地方。

Q4 情境題

你要對 300 筆客訴各做一次摘要。實測序跑 12 筆要 55–90 秒,全部跑完等不下去。最佳做法是?

批次推論的標準解就是並發:12 發同時出去約 15–20 秒,不是 12 倍時間,而且 gateway 的多來源輪替正好吃得下這種併發。B 能執行但有副作用——長輸入容易超限、輸出對不回哪一筆;C 方向相反,550B 只會更慢;D 做得到但等於自己土砲 asyncio 已經給你的東西。

Q5 情境題

你想驗證 gateway 真的在 NVIDIA NIM 與 OpenRouter 之間輪替,而不是嘴上說說。應該怎麼做?

LiteLLM 每個回應都帶 x-litellm-model-api-base,讀出來統計,「隨機輪替」就從黑盒變成一張分佈圖——這正是課裡 12 發並發那格做的事。A 不行:兩個來源掛的是同一個模型名,model 欄位看不出來源;B 不可靠;C 做得到但繞遠路,而且教學 key 的上游後台不在你手上。

HANDS-ON · MOLAB

實作在 molab 跑(免費)

molab 的登入狀態進不了內嵌框架(瀏覽器的跨站 cookie 保護), 所以 notebook 要在新分頁執行——把它跟本頁並排開,左邊教學照樣對照。

  1. 登入 molab(GitHub / Google)
  2. 開啟課程 notebook,Fork 成自己的副本即可編輯
  3. 從第一格往下全部執行(首次安裝套件約 1 分鐘)——免費 CPU 環境即可,不需要 GPU

不想用 molab?下載 litellm-basics_ext.py 後在自己電腦 uvx marimo edit --sandbox litellm-basics_ext.py,依賴會自動安裝。