生活分享

統一 API 層:OpenRouter 與 LiteLLM 換模型不改程式

OpenAI 相容端點是供應商提供的 REST 介面,形狀和 OpenAI 的 Chat Completions 端點相同,程式只要換 base_url、金鑰與 model 字串就能連到別家模型,不必重寫呼叫邏輯。這篇示範同一段 Python 用 openai 套件連上 OpenRouter 與 Groq 兩個相容端點,再用 LiteLLM 的 completion() 換三個 model 字串連到三家供應商,並比較 OpenRouter 這個託管閘道,跟 LiteLLM 的 SDK 與自架 Proxy,在「相容」範圍上的限制。

閱讀時間約 10 分鐘

原創插圖:一張程式碼卡片中間分出兩條線,分別接到寫著 base_url 與 model 字串的不同端點方塊,象徵同一段程式換端點、不換寫法。
圖片:Mokaair (© Mokaair)
本篇目錄
  1. 什麼是 OpenAI 相容端點
  2. 換 base_url 與 model 字串:同一支 openai 用戶端打兩家
  3. LiteLLM:把「換供應商」收進一個函式
  4. 託管閘道與自架 Proxy:OpenRouter 與 LiteLLM 的另一種模式
  5. 相容解決什麼、不解決什麼

「OpenAI 相容」指的是供應商把自己的推論服務包成和 OpenAI Chat Completions 端點同樣形狀的 REST 介面;只要程式呼叫的是這個形狀,換一家供應商通常只需要換 base_url、金鑰與 model 字串,其餘程式碼不用動。這篇說明 OpenAI 相容端點的意思與能相容到什麼程度,再用 openai 套件與 LiteLLM 兩種做法實際切換供應商。

讀完這篇,你會有一段 Python 程式碼,用 openai 套件的用戶端連上兩個不同的 OpenAI 相容端點;也會有另一段程式,用 LiteLLM 的 completion() 函式只換 model 字串就連到三家供應商,還會知道「相容」指請求與回應的形狀相同,不是每個參數都通用。動手前需要能執行 Python(openai 套件官方文件寫最低支援 3.10)、用 pip 或 uv 裝好 openai 與 litellm 兩個套件,以及要呼叫那幾家供應商各自的 API 金鑰,金鑰一律放進環境變數,不寫進程式碼。

什麼是 OpenAI 相容端點

OpenAI 在 Chat Completions 端點定義了一套請求與回應的 JSON 形狀:請求帶 model、messages 等欄位,回應在 choices 裡放 message.content。不少供應商把自己的推論服務包成同一種形狀,讓原本寫給 OpenAI 的程式改個設定就能連過去。openai 官方套件的說明也寫,用戶端的 base_url 可以直接被覆寫,或改讀 OPENAI_BASE_URL 這個環境變數,程式完全不用動。

「相容」指的是形狀,不是每一個參數。OpenRouter 的 API 參考寫得很直接:如果選到的模型不支援某個請求參數,例如非 OpenAI 模型不支援 logit_bias、OpenAI 模型不支援 top_k,那個參數會被忽略,其餘的參數照樣轉送到底層那家供應商的 API。Groq 官方文件把自己寫成「大致相容」,同時明講 logprobs、logit_bias、top_logprobs 與 messages[].name 這幾個欄位目前不支援,帶了會直接收到 400 錯誤,不是默默忽略。同一個「相容」,兩家處理方式並不一樣,實際能用哪些參數,還是得查供應商自己的文件。

換 base_url 與 model 字串:同一支 openai 用戶端打兩家

openai 這個 Python 套件本來是為 OpenAI 自己的 API 寫的,但它的用戶端建構式接受 base_url 這個參數,把網址換成任何一個 OpenAI 相容端點,用戶端就會去打那個網址而不是 api.openai.com。下面的程式先連 OpenRouter:官方 quickstart 寫 base_url 要填 https://openrouter.ai/api/v1,請求送到 /api/v1/chat/completions 這個端點,金鑰放進 Authorization 標頭當 Bearer token;文件另外列了 HTTP-Referer 與 X-OpenRouter-Title 兩個選用標頭,設了應用程式就能出現在 OpenRouter 的排行榜上,不設也能正常呼叫。

openai 套件:同一段程式換兩個 OpenAI 相容 base_url(需要 openai 套件) · python
import os

from openai import OpenAI

question = [{"role": "user", "content": "用一句話說明 API 金鑰是什麼"}]

# 官方 quickstart:base_url 指到 openrouter.ai,金鑰放 Authorization 標頭
openrouter = OpenAI(
  base_url="https://openrouter.ai/api/v1",
  api_key=os.environ["OPENROUTER_API_KEY"],
  timeout=30.0,
)
reply = openrouter.chat.completions.create(
  extra_headers={
    "HTTP-Referer": os.environ.get("SITE_URL", ""),
    "X-OpenRouter-Title": os.environ.get("SITE_NAME", ""),
  },
  model="anthropic/claude-sonnet-5",
  messages=question,
)
print("OpenRouter:", reply.choices[0].message.content)

# 官方文件:base_url 換成 api.groq.com,金鑰改讀 GROQ_API_KEY
groq_client = OpenAI(
  base_url="https://api.groq.com/openai/v1",
  api_key=os.environ["GROQ_API_KEY"],
  timeout=30.0,
)
reply = groq_client.chat.completions.create(
  model="openai/gpt-oss-120b",
  messages=question,
)
print("Groq:", reply.choices[0].message.content)

同一支用戶端換第二次連線時,只有 base_url、金鑰讀的環境變數,以及 model 字串三個地方不一樣:Groq 官方文件寫,要用 OpenAI 相容的用戶端連 Groq,base URL 換成 https://api.groq.com/openai/v1、金鑰改讀 GROQ_API_KEY 就好;範例裡的 openai/gpt-oss-120b 是 Groq 模型頁 MODEL ID 欄位上的代號,那一頁把它寫成 OpenAI 的旗艦模型。兩段呼叫都設了 timeout,避免網路異常時程式卡住不動;這裡用到的 anthropic/claude-sonnet-5 是 OpenRouter 目錄裡的代號,如果想繞過 OpenRouter、直接向 Anthropic 申請金鑰,站上《第一次呼叫 Claude API:金鑰、費用與十行 Python》已經走過一遍,這裡不重複。

LiteLLM:把「換供應商」收進一個函式

OpenRouter 是別人已經架好的閘道,帳號、金鑰、儲值都在 openrouter.ai 那一端,站上《OpenRouter:一把金鑰用遍各家模型》整理過,這裡不重複。LiteLLM 走另一條路:它是一個 Python 套件,官方文件把它寫成「OpenAI 用戶端的直接替代品」,重點是 completion()、embedding() 這些函式,直接匯入自己的程序裡呼叫,不需要另外連到誰架的伺服器;安裝指令是 uv add litellm。

LiteLLM 的 model 字串自己帶著供應商:官方文件示範每一家供應商時,都把供應商名稱寫在最前面、用斜線隔開,例如 model="openai/gpt-5.6-terra",並在同一段範例裡設好對應的環境變數(OPENAI_API_KEY、ANTHROPIC_API_KEY);透過 OpenRouter 轉接時要多包一層,文件寫送 model=openrouter/ 加上你的 OpenRouter 模型,請求就會送到 OpenRouter,範例是 model="openrouter/google/palm-2-chat-bison",金鑰讀 OPENROUTER_API_KEY,OPENROUTER_API_BASE 是選用欄位,不設定時預設就是 https://openrouter.ai/api/v1。下面同一段迴圈換了三次 model 字串,其他呼叫方式完全沒變;google/gemini-3.8-flash 一樣是 OpenRouter 上的代號,要直接向 Google 申請金鑰、建立第一支呼叫,見《AI Studio 與第一個 Gemini API 呼叫》。

litellm 套件:completion() 換三個 model 字串(需要 litellm 套件) · python
import os

from litellm import completion

question = [{"role": "user", "content": "用一句話說明 API 金鑰是什麼"}]

# 三個字串分屬三家供應商,completion() 的呼叫方式完全相同
model_ids = [
  "openai/gpt-5.6-terra",
  "anthropic/claude-sonnet-5",
  "openrouter/google/gemini-3.8-flash",
]

# 金鑰不寫進程式:LiteLLM 從環境變數讀,先確認三把都設好了
for name in ("OPENAI_API_KEY", "ANTHROPIC_API_KEY", "OPENROUTER_API_KEY"):
  if name not in os.environ:
    raise SystemExit(f"請先設定環境變數 {name}")

for model_id in model_ids:
  reply = completion(model=model_id, messages=question, timeout=30)
  print(model_id, "->", reply.choices[0].message.content)

三次呼叫用的是同一個 completion() 函式、同一份 messages,差別只有 model 這一個字串;官方文件寫,LiteLLM 把各家的錯誤對應成 OpenAI 的例外型別,例如 litellm.AuthenticationError、litellm.RateLimitError。第二個字串和第一段程式裡的 anthropic/claude-sonnet-5 同形不同意:這裡是 LiteLLM 前綴加 Anthropic 自己的代號、讀 ANTHROPIC_API_KEY,那裡是 OpenRouter 目錄裡的代號。官方文件也寫,completion() 預設遇到不支援的 OpenAI 參數會直接丟出例外,要自己在呼叫時加 drop_params=True,或整體設定 litellm.drop_params = True 才會改成忽略,而且只會捨棄不支援的 OpenAI 參數;這點放進下面的提醒框。

託管閘道與自架 Proxy:OpenRouter 與 LiteLLM 的另一種模式

前面兩段程式都是「自己的程序直接連出去」:一段連到 OpenRouter 這個別人架好的閘道,一段是 LiteLLM 在自己的程序裡轉接。LiteLLM 其實還有第三種形態,官方文件把它稱為 Proxy Server,是一個要自己架設的閘道伺服器,架起來以後它自己就是一個 OpenAI 相容端點。官方文件把它寫成「給平台團隊用的自架閘道,用來管理整個組織的 存取」,功能包含依金鑰設定花費上限、集中記錄與快取,還有管理介面能看用量。

架起來之後,呼叫方式反而回到最一開始那個樣子:官方文件的範例直接用 openai 套件的用戶端,把 base_url 指到自己架的位址,範例寫的是 http://0.0.0.0:4000,api_key 填的是 anything 這個字串,實際的存取控制由 Proxy 自己的虛擬金鑰管。這樣看下來,OpenRouter 與 LiteLLM 的 Proxy 是同一種角色的兩種做法:一種別人架好、一種自己架自己維護,換來的是能自己設定每把金鑰的預算與存取規則;怎麼選要看團隊有沒有人力顧那台伺服器。

流程圖:你的程式 → 換三個值 → 託管閘道 → 自架閘道 → 到供應商
由左到右:程式先選好要用哪一支用戶端或函式庫,接著只換 base_url、金鑰與 model 字串;第三、四格是兩種常見的中介做法,OpenRouter 是別人已經架好的託管閘道,LiteLLM 可以在自己程序裡呼叫、也能自架成閘道;最後都送到供應商自己的伺服器。查證於 2026 年 9 月。 · 圖片:Mokaair (© Mokaair)

相容解決什麼、不解決什麼

換 base_url 與 model 字串解決的是「程式不用為每家供應商重寫一份呼叫邏輯」,但解決不了其他幾件事。價格、免費額度、速率限制是供應商自己訂的,換一個相容端點不會讓它們變得一樣,這篇不比價,系列另一篇《成本、品質、延遲:多模型流程怎麼取捨》會專門整理怎麼在三者之間取捨。同樣地,相容層幫忙轉接的是單一次請求,請求裡帶了工具呼叫(tool calling)之類的功能,底層模型本身支不支援仍然是那個模型自己的事。

要確定某個模型、某個供應商實際支援哪些參數,LiteLLM 官方文件提供一個 get_supported_openai_params() 函式,帶入 model 與供應商名稱就能查到一份清單;OpenRouter 則是在 API 參考的註解裡示範,用 supported_parameters 篩出支援工具呼叫的模型。這篇只示範兩個直連的端點與一段 LiteLLM 程式,還沒有真的依價格或失敗與否切換供應商,那部分屬於系列另一篇《模型路由與級聯:便宜先試、貴的兜底》要講的內容,這裡不重複。

整理自 openrouter.ai、docs.litellm.ai 與 console.groq.com 官方文件,查證於 2026 年 9 月。
做法你在程式裡呼叫的東西model 字串怎麼寫「相容」範圍由誰的文件定義
openai 套件直連openai 套件的 OpenAI(...) 用戶端,base_url 指到該供應商供應商自己的原生代號,例如 openai/gpt-oss-120b那家供應商自己的 API 文件
OpenRouter同一支 openai 用戶端,base_url 指到 openrouter.ai供應商名稱+斜線+模型,例如 anthropic/claude-sonnet-5OpenRouter 的 API 參考
LiteLLM SDK從 litellm 匯入的 completion() 函式供應商前綴+原生代號,例如 anthropic/claude-sonnet-5(與 OpenRouter 那一列同形不同意)LiteLLM 的 Input Params 文件頁,它列出各供應商支援哪些 OpenAI 參數
LiteLLM Proxyopenai 套件的用戶端,base_url 指到自己架的伺服器自己在 config.yaml 裡取的 model_name架設者自己寫的 config.yaml

常見問題

OpenAI 相容是不是代表所有參數都能直接搬過去用?

不是。相容指的是請求與回應的 JSON 形狀一樣,不是每一個參數都通用。官方文件寫,OpenRouter 遇到模型不支援的參數會直接忽略、其餘照送;LiteLLM 預設遇到不支援的 OpenAI 參數會丟出例外,要自己開啟才會改成忽略。實際能用哪些參數,還是要查那個模型自己的文件。

OpenRouter 和 LiteLLM 是同一種東西嗎?

不是。OpenRouter 是別人已經架好、直接連線就能用的託管端點,帳號、金鑰、儲值都在對方那一端。LiteLLM 是一個 Python 套件,completion() 這些函式是在你自己的程序裡執行;它另外還有一個 Proxy 模式,需要自己架一台伺服器,架起來之後同樣變成一個 OpenAI 相容端點。

換供應商時,程式碼真的只需要改 base_url 和 model 嗎?

以這篇示範的兩個呼叫來說是的:openai 套件的用戶端只換了 base_url、金鑰讀的環境變數,和 model 字串三個地方,其餘程式碼沒有變。要注意的是不同供應商的 model 字串寫法不一樣:OpenRouter 用的是「供應商/模型」這種格式,Groq 則是填它模型頁表格 MODEL ID 欄位上的代號,兩邊不一定長得一樣。

LiteLLM 的 model 字串為什麼要加供應商前綴?

官方文件示範每一家供應商時,都把供應商名稱寫在 model 字串最前面、用斜線隔開,例如 openai/gpt-5.6-terra、anthropic/claude-sonnet-5,並在同一段範例裡設好對應的環境變數;OpenRouter 那一頁還明講,送 openrouter/ 加上你的 OpenRouter 模型,請求就會送到 OpenRouter。這篇的範例都照這個寫法。要注意 anthropic/claude-sonnet-5 這種字串在 LiteLLM 與在 OpenRouter 同形不同意:前者是 LiteLLM 前綴加 Anthropic 自己的代號,後者是 OpenRouter 目錄裡的代號。

要自己架 LiteLLM 的 Proxy,還是直接用 OpenRouter 比較好?

這篇沒有幫你決定,兩者是不同的取捨。OpenRouter 不用自己維運伺服器,能設定的就是對方那一端提供的項目;LiteLLM 的 Proxy 需要自己架設與維運,換來的是官方文件列出的那些自架功能,例如每把虛擬金鑰各自的預算、集中記錄與快取。要哪一種看團隊有沒有人力顧到自架的那台伺服器。

回總目錄

  • 生活分享

    Claude Code、Codex 搭本機模型:兩種接法怎麼選

    Claude Code 與 Codex 搭配本機模型有兩種接法:代理照常連雲端、把大量雜務交給腳本或 MCP 工具去問本機模型,或是把代理的模型整個換成本機模型。這篇用資料能不能出門、上下文開得夠不夠長、工作的類型三個問題幫你選,並對照 Ollama、LM Studio、Anthropic 與 OpenAI 的官方文件,分清楚本機權重、Ollama 的 cloud 標籤與供應商端點是三種不同的東西。

最新旅遊情報攻略

資料來源

生活分享