模型 / 資料集
mozilla-ai/any-llm avatar
mozilla-ai/any-llm

any-llm:把多家 LLM 供應商收斂成一個 completion 呼叫

Communicate with an LLM provider using a single interface

2,195 個 Star224 個 ForkPythonApache-2.0

秒懂

它是什麼?
Mozilla AI 出的 Python SDK,用 provider 加 model 兩個參數取代各家 SDK 的呼叫差異。它靠官方 SDK 做後端,代價是安裝時要挑 extras,而 OpenAI 相容端點則走另一條路。
適合誰用?
如果你在 Python 3.11 以上的環境裡同時接兩家以上供應商,而且不想讓 litellm 之類的代理層進到呼叫路徑,any-llm 值得先裝 extras 跑一次 completion 與 responses 兩條路徑。若你只需要一家供應商,官方 SDK 的型別與錯誤處理更貼近上游,換過來只是多一層轉接。
可以商用嗎?
可以。Apache-2.0 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
還在維護嗎?
有在維護。儲存庫在最近一天內有新的提交。
用什麼語言寫的?
主要是 Python(依據 GitHub 的語言統計)。

以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。

開源專案深度解析

它解決的是呼叫形狀不一致,不是模型能力差異

多供應商專案真正的痛點不在模型回答得好不好,而在呼叫形狀。OpenAI、Anthropic、Mistral 各自的 SDK 有不同的參數名、不同的回應物件、不同的錯誤型別。你把 provider 從 A 換到 B,改的往往不是一行字串,而是整段取值路徑。any-llm 的定位就是把這一層收斂掉:README 的 Quickstart 裡,completion 呼叫只帶 model、provider、messages 三個參數,回應則用 response.choices[0].message.content 取值,這個取值路徑與 OpenAI 的形狀一致。

它的目標讀者是需要在同一份程式碼裡切換供應商的 Python 開發者,尤其是做 agent、評測或內部工具的人。README 提到它驅動自家的 any-agent,也提到從 LiteLLM 過來的使用者可以沿用原本的環境變數。這兩個線索說明它服務的是已經有多供應商需求、而不是剛開始試用單一 API 的團隊。

它不處理的事也要講清楚:README 沒有提到它會統一不同供應商的定價、速率限制或 token 計算方式,這些仍是各家自己的規則。預算管理、API key 管理與用量分析被指向另一個專案 mozilla-ai/otari,不在這個 SDK 的範圍內。

provider 與 model 兩個參數,背後接到官方 SDK

機制上,any-llm 不是自己寫 HTTP 客戶端去打每一家的 REST 端點。README 在 Why choose any-llm 一節寫的是 leverages official provider SDKs,也就是各供應商的官方套件仍是實際發送請求的那一層。any-llm 站在上面做參數與回應的對映。這個選擇直接決定了它的相容性邊界:官方 SDK 支援什麼,它才可能支援什麼;官方 SDK 改版,它得跟著改。

參數設計上,README 建議分開傳 provider 與 model,例如 provider="mistral"、model="mistral-small-latest"。另一種寫法是把兩者併成 provider:model 字串,例如 model="mistral:mistral-small-latest",註解標明格式是 provider_id:model_id。從 LiteLLM 過來的對照範例也顯示同樣的差異:原本是 model="openai/gpt-4o",改用 any-llm 後變成 model="openai:gpt-4o",分隔符從斜線換成冒號。這個細節在批次改寫既有程式碼時最容易漏掉。

回應物件方面,README 說非串流的 responses 呼叫會回傳 OpenAI 相容的 Responses 物件別名,範例用 result.output_text 取值。也就是說,any-llm 選擇讓輸出形狀向 OpenAI 靠攏,而不是自創一套中立格式。對已經熟悉 OpenAI 物件的團隊來說遷移成本低,但對預期拿到完全中立抽象的人來說,這是一個明確的設計取向。

安裝要挑 extras,金鑰沿用既有環境變數

安裝指令在 README 裡是 pip install 'any-llm-sdk[mistral,ollama]' 這種形式,也可以只裝單一供應商,例如 pip install 'any-llm-sdk[openai]',或用 pip install 'any-llm-sdk[all]' 一次裝齊。套件名稱是 any-llm-sdk,與匯入名稱 any_llm 不同,這一點在寫 requirements 或 pyproject 時要留意。Python 版本要求是 3.11 或更新,README 的徽章與 Requirements 段落都寫明了。

金鑰走環境變數,README 列出的名稱是 OPENAI_API_KEY、ANTHROPIC_API_KEY、MISTRAL_API_KEY 等,並在範例裡用 assert os.environ.get('MISTRAL_API_KEY') 先擋一次。也可以改成在程式碼中直接傳入,AnyLLM.create 的範例就是 api_key="your-mistral-api-key"。從 LiteLLM 遷移的說明特別指出 API keys 與環境變數可以原封不動沿用,這對已經在 CI 或部署環境設好變數的團隊是省事的地方。

選 extras 這件事本身就是一個限制。你不會裝到不需要的供應商套件,但反過來說,任何時候要新增一家供應商,就得回頭改安裝設定並重新部署。若你的部署流程把依賴鎖得很死,這個步驟不能省略。README 另外提到,如果你用的是沒有被列出的 OpenAI 相容閘道或本地伺服器,不需要為它加一個 provider 條目,而是走 Custom OpenAI-compatible Endpoints 那條路徑。

completion 與 AnyLLM.create 的差別在連線重用

README 把兩種用法分得很清楚。直接呼叫 any_llm.completion 適合腳本、notebook 與單次請求,它的連線處理是每次呼叫建立新 client,也就是無狀態。AnyLLM 類別則用 AnyLLM.create("mistral", api_key=...) 取得實例,之後對該實例呼叫 llm.completion(...),連線處理是重用 client,README 在表格裡標為 connection pooling,並建議用在正式環境與需要多次請求的應用。

這個分野不只是風格問題。如果你的服務每分鐘要打數十次以上,每次呼叫重建 client 意味著重複的連線握手與資源配置,這在多供應商輪替的場景下會被放大。反過來說,一次性腳本用 AnyLLM.create 只是多寫幾行,沒有實質好處。README 明確寫兩者在功能上相同,都支援串流、工具呼叫與 responses API,差別只在連線生命週期。

要注意的是,這個表格是文件自己的說法,我沒有實際量測兩者的差異。它描述的是架構上的預期行為,不是 benchmark 數字。真正要判斷你的服務是否受影響,得看你的呼叫頻率與部署方式。

responses 路徑與 completion 路徑不是同一件事

除了 completion,any-llm 另外提供 responses 與 aresponses,對應的是有實作 OpenAI 風格 Responses API 的供應商。README 的範例是 responses(model="gpt-4o-mini", provider="openai", input_data=[...]),輸入用 input_data 而不是 messages,每一則訊息的 content 是一個陣列,裡面再放 {"type": "text", "text": "..."} 這樣的物件。取值則用 result.output_text。

這代表兩條路徑的參數形狀不同,不能互換。你在 completion 裡傳 messages,在 responses 裡傳 input_data;前者的回應要往下鑽到 choices[0].message.content,後者直接讀 output_text。文件把 responses 限定在「有實作該 API 的供應商」,所以並非每個 provider 都走得通。如果你的程式碼需要在多供應商間切換,而其中一家沒有 Responses API,那條路徑就只對部分供應商成立。

這一點在評估時常被低估:統一的介面是 per-API 的統一,不是跨 API 的統一。你選了 responses,就等於接受它的供應商集合比 completion 小。

什麼情況下不該用它

第一個明確的邊界是單一供應商。如果你整個系統只打 OpenAI,直接用它官方的 SDK 會拿到最完整的型別、最新的功能與最貼近上游的錯誤訊息。any-llm 在這一層之上做對映,功能跟進必然有時間差,錯誤型別也可能被包裝過。多一層抽象要換到好處,前提是你真的有多家。

第二個邊界是供應商不在支援清單內。README 指向一份 supported providers 清單,並把 provider_id 對應到該清單的名稱。若你要接的服務不在裡面,又不符合 OpenAI 相容端點的形式,那就得等上游支援,或自己在外面包一層。這不是設定能解決的問題。

第三個是對中立資料結構的期待。回應物件向 OpenAI 形狀靠攏,取值路徑固定成 choices[0].message.content 或 output_text。如果你的系統本來就圍繞某家供應商的回應格式設計,這個對映反而是多餘的轉換。

第四個是預算與多租戶管理。這些被 README 明確導向 otari 這個獨立專案,期待在 SDK 內解決的話會落空。

LiteLLM 是最近的對照組,差別在是否引入代理層

README 自己把 LiteLLM 當成主要參照對象,甚至給了遷移對照:from litellm import completion 改成 from any_llm import completion,模型字串從 openai/gpt-4o 改成 openai:gpt-4o,並強調 no proxy, no extra config。這句是它對自身定位最直接的說明。

兩者都在做多供應商的統一呼叫,差別在實作路線。any-llm 的敘述是建立在各供應商官方 SDK 之上,而 LiteLLM 在社群認知裡常被當成可以獨立部署的代理服務來用。如果你的架構本來就需要一個集中式的代理來處理路由、記錄或跨語言呼叫,那 any-llm 這種純函式庫形式並不對應那個需求,你得另外找元件。反過來說,如果你只是想在 Python 程式內切換供應商,不想多維運一個服務,any-llm 的形式更貼近。

遷移成本上,README 說 API keys 與環境變數可以沿用,主要工作量在改 import 與模型字串的分隔符。文件另外指向 Supported Providers 頁面來對映既有的模型字串,這一步建議先做完再動程式碼,因為分隔符的錯誤不會在安裝階段被發現,而是在第一次呼叫時才炸。

版本節奏與授權:先確認你的依賴鎖定策略

從 release 記錄看,1.27.1 在 2026-09-04 發布,1.27.0 在 2026-09-03,1.26.0 在 2026-08-17,主線分支為 main,最後推送時間是 2026-09-09。改版頻率不低,這對多供應商 SDK 是正常的,因為上游官方套件一動,它就得跟。實務上的含意是你的依賴鎖定要能配合這種節奏:如果 CI 每次都抓最新版,上游 SDK 的破壞性變更可能會穿透過 any-llm 傳到你的程式碼。

授權是 Apache-2.0。這是一個寬鬆授權,允許商用與修改,通常會要求保留著作權聲明與授權條款,並包含專利授權條款。具體條文與你的使用情境是否相符,仍應由法務確認,這裡不做法律建議。

維護成本上,README 沒有給出棄用政策或支援週期,也沒有說明舊版分支的維護承諾。這意味著升級時你得自己讀 release notes 判斷影響範圍。專案本身沒有被歸檔,主線仍在更新,這是可以觀察到的事實。

要驗證的第一件事是你打算用的 provider 是否在支援清單內,第二件是它走 completion 還是 responses 介面,第三件是把 provider:model 字串格式對回你現有的模型命名。這三項都能在裝好 extras 後用一次呼叫確認,不需要讀完整份文件。

編輯結論

如果你在 Python 3.11 以上的環境裡同時接兩家以上供應商,而且不想讓 litellm 之類的代理層進到呼叫路徑,any-llm 值得先裝 extras 跑一次 completion 與 responses 兩條路徑。若你只需要一家供應商,官方 SDK 的型別與錯誤處理更貼近上游,換過來只是多一層轉接。要驗證的第一件事是你打算用的 provider 是否在支援清單內,第二件是它走 completion 還是 responses 介面,第三件是把 provider:model 字串格式對回你現有的模型命名。

官方來源

  1. License: Apache-2.0
  2. mozilla-ai/any-llm on GitHub
  3. Project website
  4. README
  5. Releases
社群筆記

社群筆記