llmgateway 自架評測:AGPLv3 核心與 ee/ 商業目錄的雙軌授權,對採用決策意味著什麼
Route, manage, and analyze your LLM requests across multiple providers with a unified API interface.
秒懂
- 它是什麼?
- theopenco/llmgateway 是一個 TypeScript 撰寫的 LLM API 閘道,提供 OpenAI 相容介面、多供應商路由與用量分析。這篇文章拆解它的倉庫結構、部署指令與授權邊界,並指出文件沒有說清楚的地方。
- 適合誰用?
- llmgateway 適合已經在用多個 LLM 供應商、想把金鑰集中管理並取得統一用量數據的團隊;如果你的需求只是單一供應商加上簡單的快取,直接寫一層薄客戶端會比引入整個閘道便宜。決定自架之前,先確認三件事:你的使用情境是否落在 ee/ 目錄的商業功能範圍內、AGPLv3 對你散布服務的方式有什麼影響、以及 30 天資料保留上限夠不夠。
- 可以商用嗎?
- 請先確認。這個儲存庫使用的授權不在我們自動分類的範圍內,商用前請閱讀儲存庫中的 LICENSE 檔案。
- 還在維護嗎?
- 有在維護。儲存庫最近一次提交在 1 天前。
- 用什麼語言寫的?
- 主要是 TypeScript(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。
開源專案深度解析
它解決的是金鑰與帳單散落各處的問題
當一個團隊同時打 OpenAI、Anthropic 與 Google Vertex AI,麻煩通常不在呼叫本身,而在三件事:每家的金鑰各自放在不同的環境變數裡、用量與成本分散在三個後台、換模型時要改程式碼而不只是改設定。llmgateway 的定位就是把這三件事收斂到一層中介。README 對自己的描述是「an open-source API gateway for Large Language Models (LLMs)」,並列出四個目標:路由到多個供應商、集中管理供應商金鑰、追蹤 token 用量與成本、分析效能指標。
目標讀者是已經度過單一供應商階段的工程團隊。如果你只呼叫一家、每月帳單固定、也沒有跨模型比較的需求,這層閘道帶來的維運面(PostgreSQL、Redis、多個對外埠)會大於它省下的工。反過來說,當你開始需要回答「上個月哪個模型的單位成本最高」這種問題,而答案散在三個供應商後台時,集中式閘道的價值才出現。
倉庫切分:apps 底下六個應用與一個閘道本體
從資料夾結構可以看出這不是單一服務,而是一組應用。`apps/gateway` 是真正處理 LLM 請求路由的部分,`apps/api` 是 Hono 寫的後端,`apps/ui` 是 Next.js 儀表板。另外還有三個面向不同使用者的前端:`apps/playground`(README 稱之為 Lounge,消費者端聊天應用)、`apps/code`(Dev Plans 與編碼工具)、`apps/airside`(自助式供應商入口)。`packages/db` 放 Drizzle ORM 的 schema 與 migration,`packages/models` 放模型與供應商定義,`packages/shared` 放共用型別。
這個切分方式本身就是一項判斷依據。`packages/models` 獨立成一個套件,意味著新增供應商或模型屬於資料層的變更,而不是散落在路由邏輯裡;`packages/db` 用 Drizzle 而非直接寫 SQL,代表 schema 演進有 migration 可循。相對地,`apps/playground`、`apps/code`、`apps/airside` 這些應用對只想自架閘道的團隊是多餘的,但它們與閘道共用同一個映像檔,這點在部署章節會再談。
統一介面的代價:OpenAI 格式是相容層,不是抽象層
README 把「Unified API Interface」描述為「Compatible with the OpenAI API format for seamless migration」,並附上一段實際的 curl 範例:對 `https://api.llmgateway.io/v1/chat/completions` 發 POST,帶 `Authorization: Bearer $LLM_GATEWAY_API_KEY`,body 裡指定 `model` 為 `gpt-4o` 與一組 `messages`。
這裡有一個容易被忽略的設計選擇。相容 OpenAI 格式能讓既有程式碼幾乎不改就接上,代價是介面被 OpenAI 的語意綁住。供應商之間真正不同的地方,例如 Anthropic 的 system prompt 處理方式、各家 tool calling 的細節、Vertex AI 的認證流程,在相容層之下要嘛被抹平、要嘛需要額外的欄位約定。`packages/models` 的模型定義因此不只是清單,而是承載這些差異的地方。文件沒有交代這些差異如何被正規化,只給了最單純的 chat completion 範例。要評估它能不能承接你的實際 prompt 結構,得直接讀 `packages/models` 的內容,而不是看 README。
自架部署:兩個密鑰與一個不能綁定的目錄
自架路徑分成兩種。第一種走倉庫附的腳本,README 給的指令是先產生兩個密鑰再執行腳本:
export LLM_GATEWAY_SECRET="$(openssl rand -base64 32 | tr -d '\n')" export GATEWAY_API_KEY_HASH_SECRET="$(openssl rand -base64 32 | tr -d '\n')" ./scripts/run-unified-container.sh
第二種是一次性的 docker run,映像檔為 `ghcr.io/theopenco/llmgateway-unified:latest`,對外開 3002、3003、3005、3006、3007、4001、4002 共七個埠,並掛載兩個具名 volume:`llmgateway_postgres:/var/lib/postgresql/data` 與 `llmgateway_redis:/var/lib/redis`。
README 在這裡放了一個明確的警告,值得照抄:不要用 bind mount 把主機目錄直接掛到 `/var/lib/postgresql/data`,因為容器內的 PostgreSQL 初始化需要在該目錄設定權限,這會依主機檔案系統與擁有者而失敗。這條警告是文件裡少見的具體踩坑說明,也側面說明官方推薦的是具名 volume 或 Docker 管理的 volume。
七個埠同時對外是自架時要面對的現實:這不是一個單一服務,而是一組應用共用映像檔。若你只需要閘道與 API,這些埠的暴露面需要另外收斂,但 README 沒有提供只啟動部分服務的方式。這是我認為文件最薄的一塊。
雙軌授權:AGPLv3 核心與 ee/ 商業目錄的分界線
授權是這個專案最需要停下來看清楚的地方。README 寫明是 dual license:核心功能採 AGPLv3,`ee/` 目錄下的商業功能需要 Enterprise 授權,而 multi-organization administration 另外需要 white-label 授權。倉庫的 license 欄位顯示為 NOASSERTION,與這個雙軌結構一致,也代表自動化工具無法替你判定授權歸屬。
README 列出的 Enterprise 功能包括進階帳務與訂閱管理、延長資料保留(unlimited 對比 30 天)、自訂供應商金鑰設定、團隊與組織管理、優先支援,並補上一句「And more to be defined」。最後這句是實務上的風險點:商業功能的範圍尚未固定,現在不在 ee/ 目錄裡的功能,未來有可能被移進去。
資料保留的差異尤其具體。非企業路徑是 30 天,企業路徑是不限。如果你的用途涉及稽核、法規留存或跨年度的成本分析,30 天就是硬邊界,而這個邊界不在程式碼層,在授權層。
AGPLv3 的意義在於網路服務條款:若你把修改後的版本以網路服務形式提供給他人使用,通常需要提供對應原始碼。這是採用前必須與法務確認的事項,本文不提供法律意見,只指出 README 把這條線畫在 `ee/` 目錄上,而 `ee/LICENSE` 需要另外索取。
開發流程與升級節奏:每週一個 minor 版本
開發環境的入口是 `pnpm i && pnpm run setup`,README 說明這一步會安裝依賴、啟動 Docker 服務、同步資料庫 schema 並寫入初始資料;接著 `pnpm dev` 啟動開發伺服器,`pnpm build` 產生正式版。README 另外提醒 WSL2 使用者要確認 Docker Desktop 已開啟 WSL 整合。
版本節奏可以從 release 記錄讀出來:v1.14.0、v1.15.0、v1.16.0 分別落在 2026 年 8 月 24 日、8 月 31 日、9 月 7 日,間隔都是七天。倉庫最後一次 push 是 2026 年 9 月 9 日。每週一個 minor 版本對自架者意味著兩件事:上游修補來得快,但如果你打算 pin 住版本,就得每週評估一次是否跟進。
`pnpm run setup` 會同步 schema 這件事也值得注意。它對首次啟動很方便,但在已經有資料的環境裡,schema 同步的行為需要先讀 `packages/db` 的 migration 內容再決定要不要跑。README 沒有區分「全新安裝」與「既有環境升級」兩種情境,這是自架者要自己補上的判斷。
什麼情況下不該用它:與 LiteLLM 的取向差異
同類工具裡最常被拿來對比的是 LiteLLM。兩者都提供 OpenAI 相容介面與多供應商路由,差別在重心。LiteLLM 以 Python 套件形式存在,可以只用 `pip install` 就在既有 Python 服務內當函式庫呼叫,要完整代理才另外起服務;llmgateway 從倉庫結構看是一個完整的應用集合,`apps/gateway`、`apps/api`、`apps/ui` 加上 PostgreSQL 與 Redis,自架就是部署一整套系統。
這個差異決定了適用邊界。如果你的服務是 Python,而且你要的只是「同一個函式簽名打不同供應商」,把 LiteLLM 當套件用會少掉一整個資料庫與快取層。如果你的團隊是多語言、需要一個與語言無關的 HTTP 端點、而且需要儀表板給非工程角色看用量,llmgateway 的整套架構才划算。
另一個要誠實面對的限制是測試證據。倉庫沒有提供可引用的效能或吞吐數據,README 也沒有 benchmark 段落。它宣稱能做效能監控與模型比較,但那些數字來自你自己部署後的實際流量,不是專案保證的結果。把它當成量測工具而不是效能保證,期待才不會落空。
編輯結論
llmgateway 適合已經在用多個 LLM 供應商、想把金鑰集中管理並取得統一用量數據的團隊;如果你的需求只是單一供應商加上簡單的快取,直接寫一層薄客戶端會比引入整個閘道便宜。決定自架之前,先確認三件事:你的使用情境是否落在 ee/ 目錄的商業功能範圍內、AGPLv3 對你散布服務的方式有什麼影響、以及 30 天資料保留上限夠不夠。這三點在 README 裡都有線索,但沒有完整答案,需要向 contact@llmgateway.io 索取 ee/LICENSE 全文與商業條款後再判斷。
社群筆記