Skip to content

About

建立 OpenAI 相容格式 API 聚合服務,具備多渠道轉發、金鑰輪詢、故障轉移,簡易設定功能。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

206 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡ API Gateway

輕量的 LLM API 聚合工具,採用 OpenAI 格式路由,具有多 Key 輪詢、故障轉移、Model 別名對應、SSE 串流功能。

功能

  • 多 Key 輪詢 — 每個 key 有健康分數(errorCount)同分的列隊輪詢、低分的退為備援
  • Key 故障轉移 — 429/5xx/網路錯誤 → 退避降級,成功後逐步恢復
  • Provider 降級 — Fallback Chain 依序嘗試備援 Provider
  • Model 別名路由 — 依 context window 自動選擇最適合的別名
  • 端點自動派生 — endpoint_fallbacks 讓單一 model 名稱自動對應各端點的 model 別名
  • SSE 串流 — OpenAI 標準契約:省略 stream 回 JSON,stream:true 才回 SSE;透傳上游串流,自動改回 client 請求的 model 名稱
  • 非 Chat 端點 — embeddings、images/generations、images/edits、images/variations、audio/speech、audio/transcriptions、audio/translations、files、responses、messages(Anthropic 原生 x-api-key + opencode 轉譯)
  • 請求頻率限制 — 可設定 RPM(rate_limit)與 TPM(tpm_limit)
  • Circuit Breaker — 連續 5 次 5xx 自動跳過該 provider 30 秒,成功後立即關閉
  • Model Lockout — 同一 provider/model 連續失敗達 threshold(預設 3)次後暫時停用,避免一直打到壞 model 或塞車的 tier
  • Quota 額度降級 — 429/403 且訊息含 quota/credit/billing 特徵時,該 key 長期降級(預設 1 小時,quota_backoff 可設),不讓短 cooldown 後又去打額度耗盡的 key
  • 管理後台 — GET /console 使用 client-token 登入,可檢視/編輯 config、Log
  • 運行儀表板 — /console 的 Status 顯示各 provider 健康度,並彙總成功/失敗次數、平均延遲、錯誤率
  • 配置檔熱重啟 — 修改 config 檔 1 秒後自動重啟
  • 決策模型路由 — 帶有快取機制的 Classifier 請求路由

log.json 預設保留 7 天(檔名可由 log.path 指定),清理機制由 /health 每小時清理,並在每寫入 200 筆(且距上次清理超過 10 分鐘)時觸發,避免資料無限增長。


執行環境

Runtime 支援 啟動方式
Node.js 18+ ✅ npm start 或 node src/index.js
Bun ✅ npm run bun 或 bun run src/index.js

測試

npm test         # 單元測試

測試位於 test/ 目錄,由 npm test(node --test test/*.test.js)執行:

  • lib.test.js — 單元測試:Config 解析(JSONC、自動修正)、Model 別名解析與 Endpoint Fallback、Chat 請求驗證、Token 估算、Chat↔Responses 轉換(tools、tool_choice、response_format、usage)、Utility 函數(uptime、key masking、SSE rewrite 等)
  • integration.test.js — 整合測試:啟動真實 gateway(subprocess)+ mock upstream,黑箱驗證路由 / auth / SSE rewrite / 錯誤處理 / 各 provider 轉發

核心邏輯提取在 src/lib.js,src/index.js 透過 delegation 呼叫。

快速開始

cp src/config.example.json src/config.json   # 填入 Client Token 與 API keys
npm start

Client Token 非必要但是建議使用,將會是用戶端 API 調用的 header auth 以及 /console 頁面的登入密碼。

PM2 部署 (選用)

npm install -g pm2
pm2 start src/index.js --name api-gateway --node-args="--max-old-space-size=256" --max-memory-restart 300M --exp-backoff-restart-delay 10000 --kill-timeout 10000
pm2 save && pm2 startup

健康檢查

具有 log 清理機制,建議排程 5 分鐘訪問一次。

curl http://localhost:3000/health

設定

手動編輯 config.json 或訪問 /console 路由可進入直接編寫 config.json 設定檔,存檔將會自動重啟生效。

所有欄位說明請參閱 src/config.example.json。支援 config.json / config.jsonc(含 // 與 /* */ 註解),各參數值可由同名稱環境變數覆寫。

圖片預處理

Gateway 會將請求中的遠端 image_url 預先抓回並轉換為 base64 data URI,避免上游不支援 URL 圖片。

  • 預設白名單來自既有 provider base URL 的根域名
  • 可手動覆寫:config.json 加入 allowed_image_origins
  • 只允許 HTTPS,且會限制單檔 8 MB
// config.json
"allowed_image_origins": [
  "https://openai.com",
  "https://cdn.openai.com"
]

支援的 Provider

相容 OpenAI Chat Completions API:

類型 Provider
Chat / Embedding openai、mistral、cerebras、deepseek、xai、groq、together、openrouter、orcarouter、cohere、perplexity、huggingface、pollinations、literouter、llm7、nvidia、gpt4free、agnes-ai、sea-lion、kilo、replicate、baseten、parallel、opencode、anthropic、vyceai、morph、aihorde、aihubmix、apinex、navy、ollama、hermes、tokenharbor、amd、bazaarlink、flatkey、tokenrouter
TTS / STT cartesia、elevenlabs(內建 OpenAI ↔ 目標格式轉換)

ollama 為雲端服務(https://ollama.com/v1,key 在 Ollama Cloud 申請)。

  • 額外支援 Workers-AI(自動判斷 https://api.cloudflare.com/client/v4/accounts URL):chat / embeddings 原生 OpenAI 相容;image / TTS / STT 自動轉成 Workers AI /ai/run/{model} 格式(image 回應轉為 b64_json、TTS 回應轉為二進位音檔、STT 回應轉為 {text})

在 providers 加入:

// config.json
"providers": {
  "xxx-cf-workers": {
    "apiKeys": ["cfut_xxx"],
    "baseUrl": "https://api.cloudflare.com/client/v4/accounts/accountID-xxx/ai",
    "pathPrefix": "/v1",
    "rpm": 20
  }
},

"models": {
  "image": [
    { "provider": "xxx-cf-workers", "model": "@cf/black-forest-labs/flux-1-schnell" }
  ],
  "tts": [
    { "provider": "xxx-cf-workers", "model": "@cf/myshell-ai/melotts" }
  ],
  "stt": [
    { "provider": "xxx-cf-workers", "model": "@cf/openai/whisper" }
  ]
}

TTS (Text-to-Speech)

/v1/audio/speech 端點內建 Cartesia 與 ElevenLabs 的格式轉換。非 OpenAI 相容的 TTS provider 無需手動適配,Gateway 會自動將 OpenAI 請求轉成目標 provider 格式:

// config.json
"providers": {
  "cartesia": ["sk_car_..."],
  "elevenlabs": ["xi-api-key..."]
},
"models": {
  "tts-1": [
    { "provider": "cartesia", "model": "sonic-3.5" },
    { "provider": "elevenlabs", "model": "eleven_multilingual_v2" }
  ]
}

client 送標準 OpenAI TTS 請求即可,Gateway 依 model 別名自動轉發。

STT (Speech-to-Text) / Translation

/v1/audio/transcriptions 與 /v1/audio/translations 端點同樣支援 Cartesia 與 ElevenLabs,自動處理 multipart 欄位名稱與模型值轉換。transcriptions 輸出原始語言文字,translations 固定輸出英文(OpenAI 規格)。

"models": {
  "tts-1": [
    { "provider": "cartesia", "model": "sonic-3.5" },
    { "provider": "elevenlabs", "model": "eleven_multilingual_v2" }
  ],
  "whisper-1": [
    { "provider": "cartesia", "model": "ink-whisper" },
    { "provider": "elevenlabs", "model": "scribe" }
  ]
}

手動新增 Provider

任何 OpenAI-compatible 的 /chat/completions 端點,都能直接在 config.json 的 providers 以物件形式加入:

"providers": {
  "my-proxy": {
    "apiKeys": ["sk-xxxx"],    // 必填:至少一把 key(keyless 端點尚不支援)
    "baseUrl": "https://xxx",  // 必填:target url,僅接受 http/https,否則啟動時跳過並告警
    "pathPrefix": "/v1",       // 選填:端點路徑前綴,預設 /v1(最終為 baseUrl + pathPrefix + /chat/completions)
    "rpm": 20                  // 選填:每把 key 的帳號級 RPM;省略時套用保守預設 10,避免無限速被 ban
  }
}

再於 models 把別名指向它即可:

"models": {
  "my-model": [{ "provider": "my-proxy", "model": "upstream-model-name" }]
}

Client API 使用

相容 OpenAI Chat Completions API:

curl http://localhost:3000/v1/chat/completions \
  -H "Authorization: Bearer $CLIENT_TOKEN" \
  -d '{"model":"openai","messages":[{"role":"user","content":"Hello"}],"stream":true}'
  • model 可為 config 中定義的別名或真實模型名稱
  • 陣列中的目標依序嘗試:第一個目標所有 Key 失敗 → 自動換下一個
  • 回應含 X-Request-Id header;非串流成功回應目前不附 X-Provider / X-Upstream-Model(僅 SSE 透傳路徑與 endpoint 轉換路徑會帶)

Model 別名範例

{
  "models": {
    "openai": [
      { "provider": "mistral",          "model": "mistral-small-latest" },
      { "provider": "cerebras",         "model": "gpt-oss-120b" }
    ]
  }
}

端點自動派生

Client 送任何不在 models 中的 model 名稱(例如 "openai"),Gateway 會依端點路徑自動從 endpoint_fallbacks 查到對應的 model 別名再解析:

{
  "endpoint_fallbacks": {
    "/v1/chat/completions":      "gpt-4o",
    "/v1/images/generations":    "dall-e-3",
    "/v1/images/edits":          "dall-e-3",
    "/v1/images/variations":     "dall-e-3",
    "/v1/audio/speech":          "tts-1",
    "/v1/audio/transcriptions":  "whisper-1",
    "/v1/audio/translations":    "whisper-1",
    "/v1/embeddings":            "text-embedding-3-small",
    "/v1/files":                 "file-store"
  },
  "models": {
    "_note": "key = client 送的 model 名稱;value = provider/model 的 fallback 鏈,依序嘗試",
    "gpt-4o": [
      { "provider": "openrouter", "model": "nvidia/nemotron-3-ultra-550b-a55b:free" },
      { "provider": "openrouter", "model": "google/gemma-4-31b-it:free" },
      { "provider": "mistral", "model": "mistral-small-latest" }
    ],
    "dall-e-3":      [{ "provider": "together", "model": "black-forest-labs/FLUX.1-schnell-free" }],
    "tts-1":         [{ "provider": "cartesia", "model": "sonic-3.5" }],
    "whisper-1":     [{ "provider": "nvidia", "model": "canary-1" }],
    "text-embedding-3-small": [{ "provider": "sea-lion", "model": "aisingapore/SEA-LION-ModernBERT-Embedding-600M" }],
    "file-store":    [{ "provider": "nvidia", "model": "" }]
  }
}

流程範例:client 送 model:"openai" 到 /v1/images/generations

  • resolveModel("openai") → 不在 models 中,回傳 null
  • 查 endpoint_fallbacks["/v1/images/generations"] → "dall-e-3"
  • resolveModel("dall-e-3") → [{ provider: "together", model: "black-forest-labs/FLUX.1-schnell-free" }]

client 只認得一個 model 名稱,gateway 依端點決定實際路由。如果 client 送了 models 中已存在的 model(如 nvidia/nemotron-3-ultra-550b-a55b:free),則直接命中,不走 defaults。

圖片辨識自動路由

請求含圖片(image_url)時,Gateway 會自動將 model 切換到 vision 別名(若存在於 models 中):

"models": {
  "vision": [
    { "provider": "openrouter", "model": "google/gemma-4-31b-it:free" },
    { "provider": "openrouter", "model": "nvidia/nemotron-nano-12b-v2-vl:free" },
    { "provider": "mistral", "model": "mistral-small-latest" }
  ]
}

Client 端不需要知道哪些 provider 支援 vision,只要附圖,Gateway 自動優先調用支援 vision 的 provider,失敗則 fallback 到一般 chat chain。

單目標端點覆寫

models 別名的單一目標可加 endpoint 欄位,強制該目標走指定上游端點,例如 client 發送請求的端點 /chat/completions,設定好目標端點,將自動轉換到 /v1/responses

跨別名 Fallback

單一模型目標可加 fallback(指向其它別名,可陣列)。當該別名的所有 key/上游都失敗(4xx/5xx,非限流等待)時,Gateway 在同一次請求內展開 fallback 別名繼續嘗試,client 連線保持到 TIMEOUT_MS 為止:

// 以調用 opencode 上游為例,此模型 (opencode-free) 在自動 endpoint 轉換後會使用 /v1/responses 做轉發
// 調用失敗後,fallback 到 auto-openai 模型別名,可以多筆使用
"models": {
  "opencode-free": [
    { "provider": "opencode", "model": "muse-spark-1.2-contributor-free", "endpoint": "/v1/responses", "fallback": "auto-openai" }
  ]
}

智慧路由 Tier

smart_route 區塊內的文字生成模型,轉發時會依照可乘載 token 量來做渠道選擇,(lite→heavy 依 max_tokens 排序):

"smart_route": {
  "openai": [
    { "alias": "openai-lite", "max_tokens": 4000 },
    { "alias": "openai",      "max_tokens": 32000 },
    { "alias": "openai-max",  "max_tokens": 128000 }
  ]
}

圖像編輯與變體

/v1/images/edits(編輯)與 /v1/images/variations(變體)為 multipart 端點,raw body 直接 forward 到上游。model 由 multipart body 中的 model 欄位決定,未指定時透過 endpoint_fallbacks 指定 model 別名:

"/v1/images/edits": "image",
"/v1/images/variations": "image"

model 別名與 images/generations 共用同一 image 鏈即可。

Files API

/v1/files 支援:

Method 路徑 用途
GET /v1/files 列出檔案
GET /v1/files/:id 查詢檔案
GET /v1/files/:id/content 下載檔案內容
POST /v1/files 上傳檔案(multipart)
DELETE /v1/files/:id 刪除檔案

需在 endpoint_fallbacks 指定檔案儲存的上游 provider:

"/v1/files": "nvidia"

決策模型

/v1/classifier 帶有快取機制的零樣本文字分類服務(Jev 決策模型,只分類不生成),回傳最貼切的 label 與信心分數。

預設為 classifier.dev 上游,api_key 留空即可免費用,或更換 base_url自建相容端點。

curl http://localhost:3000/v1/classifier \
  -H "Authorization: Bearer $CLIENT_TOKEN" \
  -d '{"texts":["the checkout button does nothing"],"labels":["bug","feature","praise"]}'

Repobeats analytics

About

建立 OpenAI 相容格式 API 聚合服務,具備多渠道轉發、金鑰輪詢、故障轉移,簡易設定功能。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Sponsor this project

Used by

Contributors

Languages