
LiteLLM 啟動與接口測試排錯記錄本文記錄my-litellm-service第一次在本地啟動 LiteLLM Proxy并通過 OpenAI 兼容接口調(diào)用 Gemini 時遇到的問題、排查過程和最終解決方式。這次排錯涉及的內(nèi)容比較多Python 依賴、uv環(huán)境、FastAPI 版本、Redis 網(wǎng)絡(luò)路徑、Tailscale、LiteLLM 網(wǎng)關(guān)認(rèn)證、健康檢查、模型輸出 Token以及 Gemini 的 thinking 和 429 限流。1. LiteLLM Proxy 啟動方式當(dāng)前項(xiàng)目不是通過python main.py啟動 LiteLLM。LiteLLM Proxy 是第三方包提供的命令行程序入口來自虛擬環(huán)境中的.venv/bin/litellm推薦啟動命令cd/home/gateman/projects/github/my-litellm-service uv run --env-file .env\litellm\--configconfig.yaml\21|tee-a/var/log/my-litellm-service/litellm.log這里的--env-file .env只負(fù)責(zé)把環(huán)境變量注入 LiteLLM 進(jìn)程例如OPENAI_API_KEY_FREE_1... LITELLM_MASTER_KEY... REDIS_HOST... REDIS_PASSWORD...它不會修改當(dāng)前 shell 的環(huán)境變量。之后使用curl的終端仍需要單獨(dú)執(zhí)行set-asource.envseta否則下面的變量可能為空或仍然是舊值$LITELLM_MASTER_KEY這是本次排錯中非常關(guān)鍵的一點(diǎn)uv --env-file .env → LiteLLM 進(jìn)程 source .env → 當(dāng)前 shell 和 curl2. 第一個問題缺少 LiteLLM Proxy 依賴最初的依賴聲明是litellm1.74.0,2.0.0啟動 Proxy 時出現(xiàn)ModuleNotFoundError: No module named backoffLiteLLM 的基礎(chǔ)包和 Proxy 所需依賴不是完全相同的集合?;A(chǔ)包可以用于 SDK 調(diào)用但啟動完整 Proxy 還需要額外依賴。因此將依賴修改為litellm[proxy]1.74.0,2.0.0然后重新解析和同步環(huán)境uv lock uvsync--devlitellm[proxy]會額外安裝 Proxy 所需的依賴?yán)鏱ackoff、Proxy 運(yùn)行組件、Redis 相關(guān)組件和 Web 服務(wù)組件。3. 第二個問題LiteLLM 與 FastAPI 版本不兼容安裝 Proxy extra 后LiteLLM 可以繼續(xù)啟動但出現(xiàn)了ImportError: cannot import name get_flat_dependant from fastapi.dependencies.utils檢查實(shí)際版本LiteLLM 1.97.0 FastAPI 0.141.1LiteLLM Proxy 代碼仍然導(dǎo)入get_flat_dependant而較新的 FastAPI 已經(jīng)移除了這個接口。問題不是缺少 Python 文件而是兩個包的版本接口不兼容。最后將 FastAPI 固定到仍然提供該接口的版本fastapi0.136.3,0.137.0然后重新執(zhí)行uv lock uvsync--dev驗(yàn)證.venv/bin/python-c\from fastapi.dependencies.utils import get_flat_dependant; print(compatible)LiteLLM 隨后可以正常進(jìn)入Application startup complete. Uvicorn running on http://0.0.0.0:4000這里得到的經(jīng)驗(yàn)是使用 LiteLLM Proxy 時不能只看 LiteLLM 自己的版本還要檢查它的 Proxy extra 對 FastAPI、Starlette 和 Uvicorn 的兼容約束。4. 日志輸出到指定文件直接啟動 LiteLLM 時日志默認(rèn)輸出到終端。為了保存日志使用21|tee-a/var/log/my-litellm-service/litellm.log第一次執(zhí)行時出現(xiàn)/var/log/my-litellm-service/litellm.log: No such file or directory原因是目標(biāo)目錄還不存在。先創(chuàng)建并授權(quán)sudomkdir-p/var/log/my-litellm-servicesudochowngateman:gateman /var/log/my-litellm-servicesudochmod750/var/log/my-litellm-service之后重新啟動即可uv run --env-file .env\litellm--configconfig.yaml\21|tee-a/var/log/my-litellm-service/litellm.logLiteLLM 是前臺服務(wù)啟動命令不返回 shell 是正?,F(xiàn)象不是卡死??吹较旅娴娜罩揪驼f明服務(wù)已經(jīng)啟動Application startup complete. Uvicorn running on http://0.0.0.0:40005. Redis 緩存配置與連接問題當(dāng)前config.yaml啟用了 LiteLLM 原生 Redis Response Cachelitellm_settings:cache:truecache_params:type:redishost:os.environ/REDIS_HOSTport:os.environ/REDIS_PORTpassword:os.environ/REDIS_PASSWORDsupported_call_types:[chat_completion]ttl:3600LiteLLM 會自動創(chuàng)建 Redis 客戶端、查詢緩存、寫入響應(yīng)和處理 TTL不需要我們再編寫一套緩存讀寫代碼。5.1 Redis 的部署位置Redis 實(shí)際部署在 Tencent K3s 集群中的 OCIfree-arm-vm節(jié)點(diǎn)free-arm-vm └── Redis Pod通過集群檢查確認(rèn)free-arm-vm Ready Redis Pod Running Redis Service 6379Redis 的實(shí)際 Tailscale 地址是100.105.130.05.2 一開始使用了錯誤的地址曾經(jīng)把 Redis 配置成REDIS_HOST100.104.150.19這個地址實(shí)際上是 NUC 節(jié)點(diǎn)不是 Redis 所在的 OCI 節(jié)點(diǎn)。后來改回REDIS_HOST100.105.130.0 REDIS_PORT63795.3 為什么本地連接一開始超時從 Main PC 測試100.105.130.0:6379 → timeout檢查路由發(fā)現(xiàn)Main PC 當(dāng)時沒有 Tailscale 路由把100.105.130.0當(dāng)成普通局域網(wǎng)地址發(fā)送到家庭網(wǎng)關(guān)。后來在 Main PC 安裝并啟用 Tailscaletailscaledactive 開機(jī)啟動enabled Tailscale IP100.121.12.126現(xiàn)在本地 LiteLLM 才具備訪問 OCI Redis Tailscale 地址的網(wǎng)絡(luò)條件。5.4 Kong/KIC 與 Redis 的關(guān)系KIC 負(fù)責(zé)將 Kubernetes 配置同步到 KongKong Proxy Service 才負(fù)責(zé)實(shí)際網(wǎng)絡(luò)轉(zhuǎn)發(fā)。但部署記錄中的低延遲方案不是繞經(jīng) Tencent 節(jié)點(diǎn)而是LiteLLM → Tailscale → 100.105.130.0:6379 → Redis Pod on free-arm-vm如果 LiteLLM 也部署在 K3s 集群內(nèi)部則應(yīng)該使用 Redis Service DNS如果 LiteLLM 在集群外且已加入 Tailscale則使用100.105.130.0。Redis 不應(yīng)直接暴露到公網(wǎng)。公網(wǎng)入口應(yīng)該給 LiteLLM API 使用Redis 繼續(xù)走 K3s 內(nèi)部網(wǎng)絡(luò)或 Tailscale。6.Setting Cache on Proxy不等于 Redis 已連接啟動時看到Setting Cache on Proxy只表示 LiteLLM 正在初始化緩存功能。如果 Redis 不可達(dá)日志可能繼續(xù)出現(xiàn)Timeout connecting to server Error connecting to Sync Redis client這時可能出現(xiàn)LiteLLM Proxy啟動成功 Redis 配置已開啟 Redis 連接失敗 緩存不可用或降級后來 Tailscale 配置完成后啟動日志不一定每次都打印Setting Cache on Proxy但這不表示緩存被關(guān)閉。是否開啟應(yīng)看config.yaml是否可用則要看 Redis 連接結(jié)果或?qū)嶋H緩存命中。當(dāng)前 Redis 是精確響應(yīng)緩存不是語義緩存。只有請求的模型、Prompt、消息順序和相關(guān)參數(shù)完全一致時才可能復(fù)用響應(yīng)。語義相近但文字不同的請求不會自動命中。7. LiteLLM 的兩類 API Key本項(xiàng)目同時使用兩把不同用途的 KeyOPENAI_API_KEY_FREE_1Gemini API Key LITELLM_MASTER_KEYLiteLLM 網(wǎng)關(guān)訪問 Key調(diào)用鏈路是客戶端 使用 LITELLM_MASTER_KEY ↓ LiteLLM Proxy 使用 OPENAI_API_KEY_FREE_1 ↓ Gemini API因此客戶端調(diào)用 LiteLLM 時必須攜帶Authorization: Bearer $LITELLM_MASTER_KEY不能把 Gemini API Key 直接當(dāng)作客戶端訪問 LiteLLM 的 Key。7.1 占位 Master Key 導(dǎo)致的錯誤最初.env中雖然存在LITELLM_MASTER_KEY但它仍然是占位值replace-with-private-master-key這會導(dǎo)致 LiteLLM 報(bào)Malformed API Key passed in.后來生成真實(shí)的sk-...Key 并寫入.env。修改后必須重啟 LiteLLM因?yàn)?LiteLLM 只在進(jìn)程啟動時讀取環(huán)境變量。7.2curl命令末尾多寫字符還遇到過這樣的命令-HAuthorization: Bearer$LITELLM_MASTER_KEY1末尾的1會被拼接到 Header 值中導(dǎo)致 Key 失效。正確寫法是-HAuthorization: Bearer$LITELLM_MASTER_KEY8./health和/v1/models返回 500 的原因匿名訪問curlhttp://127.0.0.1:4000/health日志首先出現(xiàn)No api key passed in.隨后 LiteLLM 的異常處理器又嘗試導(dǎo)入可選的 Prisma 依賴ModuleNotFoundError: No module named prisma最終客戶端看到的是{type:internal_server_error}這個 500 的首要原因不是 Redis也不是 MySQL而是認(rèn)證失敗Prisma 錯誤是錯誤處理路徑中的二次異常。正確的調(diào)用方式是set-asource.envsetacurlhttp://127.0.0.1:4000/v1/models\-HAuthorization: Bearer$LITELLM_MASTER_KEY最終成功返回{data:[{id:gemini-3.7-flash}],object:list}這里也再次證明uv run --env-file .env給 LiteLLM 加載環(huán)境變量并不會自動給另一個終端里的curl加載環(huán)境變量。9. 模型別名和真實(shí)模型名稱LiteLLM 配置中可以給模型定義別名model_list:-model_name:gemini-3.6-flash-freelayerlitellm_params:model:gemini/gemini-3.6-flashapi_key:os.environ/OPENAI_API_KEY_FREE_1客戶端請求使用的是gemini-3.6-flash-freelayer真正交給 Gemini Provider 的模型是gemini/gemini-3.6-flashfreelayer只是項(xiàng)目自定義別名不會自動讓賬號進(jìn)入 Gemini 免費(fèi)層。免費(fèi)額度和限流策略由 Gemini API Key 對應(yīng)的賬號決定。LiteLLM 可能在模型尚未被真正調(diào)用前就成功啟動即使底層模型名稱寫錯實(shí)際請求時仍可能返回模型不存在或 404。因此模型別名加載成功不代表上游模型調(diào)用已經(jīng)驗(yàn)證成功。10.max_tokens與 Gemini thinking第一次請求使用max_tokens:128返回finish_reason: length content: 很短或不完整原因是 Gemini 3.x 的 thinking/reasoning token 也會占用輸出額度。后來把額度提高到max_tokens:1024模型正常返回finish_reason: stop實(shí)際 Token 統(tǒng)計(jì)類似{completion_tokens:553,reasoning_tokens:526,text_tokens:27}這說明max_tokens不是單純的“可見文字上限”而是包含模型推理過程在內(nèi)的輸出預(yù)算。對于一句簡單回答128 可能仍然太小1024 可以讓模型有足夠空間完成 thinking 和正文。響應(yīng)中的thought_signatures:[...]是 Gemini Provider 的思考簽名元數(shù)據(jù)不是亂碼??蛻舳送ǔV恍枰x取curl...|jq-r.choices[0].message.content11. LiteLLM 的模型成本警告啟動時還出現(xiàn)過model... not in built-in cost map cache cost fields will default to 0這表示當(dāng)前 LiteLLM 內(nèi)置價(jià)格表沒有識別某個內(nèi)部模型標(biāo)識。它影響的是緩存成本統(tǒng)計(jì)不影響Proxy 啟動Gemini 請求Redis 連接OpenAI 兼容響應(yīng)如果以后需要精確統(tǒng)計(jì)緩存成本可以補(bǔ)充模型價(jià)格信息當(dāng)前階段可以先忽略這條警告。12. 最終驗(yàn)證命令12.1 查看模型列表set-asource.envsetacurlhttp://127.0.0.1:4000/v1/models\-HAuthorization: Bearer$LITELLM_MASTER_KEY12.2 調(diào)用 OpenAI 兼容聊天接口curlhttp://127.0.0.1:4000/v1/chat/completions\-HAuthorization: Bearer$LITELLM_MASTER_KEY\-HContent-Type: application/json\-d{ model: gemini-3.6-flash-freelayer, messages: [ {role: user, content: 你好請用一句話介紹你自己。} ], max_tokens: 1024 }12.3 只顯示模型正文curlhttp://127.0.0.1:4000/v1/chat/completions\-HAuthorization: Bearer$LITELLM_MASTER_KEY\-HContent-Type: application/json\-d{ model: gemini-3.6-flash-freelayer, messages: [ {role: user, content: Reply with exactly: OK} ], max_tokens: 1024 }|jq-r.choices[0].message.content13. 關(guān)于 429429 Too Many Requests與本地 LiteLLM 啟動問題不同。它通常來自 Gemini 上游常見原因包括免費(fèi)層請求頻率超過限制項(xiàng)目或 API Key 配額耗盡并發(fā)請求過多模型本身的配額策略如果gemini-3.7-flash經(jīng)常返回 429而gemini-3.6-flash可以成功說明網(wǎng)絡(luò)、LiteLLM 和認(rèn)證鏈路未必有問題更可能是特定模型或賬號配額問題。當(dāng)前配置只有一個模型別名時LiteLLM 沒有備用模型可以切換。后續(xù)如果要做容災(zāi)需要在model_list中聲明多個模型并配置 fallback否則 429 會直接返回給客戶端。14. 當(dāng)前結(jié)論這次本地驗(yàn)證最終確認(rèn)了以下鏈路curl → LiteLLM Proxy :4000 → LITELLM_MASTER_KEY 網(wǎng)關(guān)認(rèn)證 → gemini-3.6-flash-freelayer 模型別名 → gemini/gemini-3.6-flash Provider → Gemini API同時LiteLLM Proxy 可以正常啟動。litellm[proxy]是運(yùn)行 Proxy 所需的依賴集合。FastAPI 版本必須與 LiteLLM Proxy 兼容。Redis 部署在 OCIfree-arm-vm節(jié)點(diǎn)上跨集群訪問依賴 Tailscale。Redis 是精確響應(yīng)緩存不是語義緩存。Gemini API Key 和 LiteLLM Master Key 是兩把不同的 Key。--env-file不會自動更新另一個終端的 shell 環(huán)境。/v1/models和聊天接口需要攜帶 LiteLLM Master Key。prisma報(bào)錯是認(rèn)證失敗后的二次異常不是本次最初原因。Gemini 3.x 的 thinking 會消耗max_tokens預(yù)算。429 需要單獨(dú)按上游配額和限流問題處理。