統(tǒng)一多模型API調(diào)用的開源網(wǎng)關(guān)方案)
1. LiteLLM 到底解決什么問(wèn)題一個(gè) API 網(wǎng)關(guān)的誕生邏輯做 AI 應(yīng)用做到某個(gè)階段你一定會(huì)遇到這樣一個(gè)問(wèn)題代碼里的模型調(diào)用五花八門某家用 OpenAI 的格式某家用 Anthropic 的格式本地跑的去連 Ollama私有化部署又要走 vLLM光是記住各家 API 差異就夠?qū)懸黄夹g(shù)文檔了。我最后找到的最省事解法就是 LiteLLM——一個(gè)把幾十家模型接口統(tǒng)一成同一套格式的開源網(wǎng)關(guān)。說(shuō)起來(lái)很有意思LiteLLM 這個(gè)名字容易讓人誤以為它是個(gè)“輕量級(jí)大模型”但實(shí)際它和模型本身無(wú)關(guān)。它就是一個(gè)純 Python 寫的中間層你依然用 OpenAI 那套 SDK 的寫法去調(diào)模型LiteLLM 在背后替你翻譯請(qǐng)求、轉(zhuǎn)發(fā)請(qǐng)求、管理密鑰、控制預(yù)算甚至幫你做負(fù)載均衡和失敗重試。換句話說(shuō)你只需要學(xué)會(huì)一種接口格式就能調(diào)用市面上幾乎所有主流的大模型。我以前帶過(guò)一個(gè)項(xiàng)目最開始只用一家的模型代碼寫得很順手。后來(lái)業(yè)務(wù)需要同時(shí)對(duì)比三家模型的效果為了切模型我在代碼里寫了三層 if-else每層對(duì)應(yīng)不同的 SDK光是統(tǒng)一超時(shí)配置就折騰了兩天。接入 LiteLLM 之后整個(gè)調(diào)用層縮成了不到二十行代碼切換模型只需要改一個(gè)字符串。這種體驗(yàn)上的落差才是 LiteLLM 真正打動(dòng)我的地方。那它具體適合誰(shuí)如果你是個(gè)人開發(fā)者想在本地快速體驗(yàn)不同模型LiteLLM 的 SDK 模式足夠輕量如果你在公司負(fù)責(zé) AI 平臺(tái)需要給團(tuán)隊(duì)統(tǒng)一模型入口、控制成本、審計(jì)調(diào)用記錄LiteLLM 的 Proxy 模式幾乎就是為你準(zhǔn)備的。無(wú)論哪種場(chǎng)景它的核心價(jià)值都一樣把“接模型”這件事從一個(gè)月的工作量壓縮到一天。我在實(shí)際使用中反復(fù)確認(rèn)過(guò)LiteLLM 并不僅僅是個(gè)“轉(zhuǎn)換器”它在轉(zhuǎn)換之外還做了三層很關(guān)鍵的事第一層是協(xié)議歸一把各家的請(qǐng)求體、返回體、錯(cuò)誤碼都翻譯成 OpenAI 風(fēng)格第二層是路由調(diào)度可以在多個(gè)模型、多個(gè)密鑰、多個(gè)供應(yīng)商之間做分發(fā)第三層是治理能力密鑰管理、預(yù)算限額、審計(jì)日志這些都是企業(yè)級(jí)網(wǎng)關(guān)該有的東西。這三點(diǎn)合起來(lái)才構(gòu)成一個(gè)完整的“LLM Gateway”。1.1 為什么會(huì)聊到“統(tǒng)一 API 格式”這件事要理解 LiteLLM 的價(jià)值得先承認(rèn)一個(gè)現(xiàn)狀模型廠商之間從來(lái)沒(méi)有為開發(fā)者考慮過(guò)接口兼容。OpenAI 的 Chat Completions 有 messages 數(shù)組和 role 字段Anthropic 的 Messages API 卻用 system 獨(dú)立字段加 content 數(shù)組Google 的 Gemini 又是另一套 generationConfig 結(jié)構(gòu)本地 Ollama 的 /api/chat 走的是精簡(jiǎn)版 OpenAI 風(fēng)格但不完全一致。每個(gè) SDK 的安裝方式不同、錯(cuò)誤類型不同、流式返回的數(shù)據(jù)片結(jié)構(gòu)不同。這個(gè)問(wèn)題的本質(zhì)是“模型接口碎片化”。對(duì)一個(gè)業(yè)務(wù)團(tuán)隊(duì)來(lái)說(shuō)每多接一家模型就要多維護(hù)一套調(diào)用代碼、一套錯(cuò)誤處理邏輯、一套鑒權(quán)方式而且這些代碼往往只為了某一個(gè)供應(yīng)商存在沒(méi)法復(fù)用。更麻煩的是當(dāng)你想在幾個(gè)模型間做 A/B 對(duì)比時(shí)代碼改動(dòng)的范圍會(huì)超出預(yù)期因?yàn)楦骷业某瑫r(shí)時(shí)間、最大 token 限制、重試策略都是獨(dú)立的。LiteLLM 的統(tǒng)一思路很簡(jiǎn)單既然 OpenAI 的 API 格式已經(jīng)被廣泛接受成了事實(shí)上的行業(yè)標(biāo)準(zhǔn)那就讓其他所有模型都“說(shuō)”O(jiān)penAI 的話。你在代碼里寫一個(gè)client.chat.completions.create把相同結(jié)構(gòu)的參數(shù)傳進(jìn)去LiteLLM 會(huì)判斷目標(biāo)模型屬于哪一家然后自動(dòng)轉(zhuǎn)換成對(duì)方需要的請(qǐng)求格式。等于你做應(yīng)用開發(fā)永遠(yuǎn)只面對(duì)一套接口契約。1.2 LiteLLM 的雙層架構(gòu)SDK 模式與 Proxy 模式LiteLLM 提供兩種使用形態(tài)初學(xué)者容易混淆我分開講清楚。第一種是 SDK 模式你在自己的 Python 代碼里直接import litellm調(diào)用litellm.completion()或者litellm.embedding()LiteLLM 作為庫(kù)被嵌入你的進(jìn)程里。這種方式適合個(gè)人項(xiàng)目、小服務(wù)、腳本工具不需要額外部署任何東西venv 里裝個(gè)包就能跑。第二種是 Proxy 模式你啟動(dòng)一個(gè)獨(dú)立的 LiteLLM 服務(wù)進(jìn)程它對(duì)外暴露一個(gè)標(biāo)準(zhǔn)的 OpenAI 兼容接口也就是一個(gè) HTTP 服務(wù)器。你的應(yīng)用代碼不再直接碰 LiteLLM 庫(kù)而是像調(diào)用遠(yuǎn)程 OpenAI 服務(wù)一樣去請(qǐng)求這個(gè)代理。Proxy 模式承載了更多企業(yè)級(jí)能力比如虛擬密鑰、預(yù)算控制、調(diào)用審計(jì)、多模型負(fù)載均衡這些都是 SDK 模式?jīng)]有的。兩者的選擇并不沖突。我個(gè)人的習(xí)慣是本地驗(yàn)證想法用 SDK 模式一旦要上生產(chǎn)環(huán)境或者要交付給團(tuán)隊(duì)統(tǒng)一使用立刻切換到 Proxy 模式。因?yàn)?Proxy 模式把模型接入的復(fù)雜度收攏到一個(gè)獨(dú)立服務(wù)里業(yè)務(wù)代碼完全感知不到底層有多個(gè)模型供應(yīng)商這在多人協(xié)作、多服務(wù)部署的場(chǎng)景下優(yōu)勢(shì)極其明顯。1.3 用生活化的方式理解 LiteLLM 的工作位置我經(jīng)常給團(tuán)隊(duì)同事打一個(gè)比方LiteLLM 就像你出差時(shí)隨身帶的多口轉(zhuǎn)換插頭。插座標(biāo)準(zhǔn)五花八門你不可能每去一個(gè)地方就買一套專用的電線你只需要一個(gè)轉(zhuǎn)換頭把任何插座都變成你能用的形式。LiteLLM 就是這個(gè)轉(zhuǎn)換頭只不過(guò)它轉(zhuǎn)換的不是電流而是各家模型的 API 協(xié)議。但它又比轉(zhuǎn)換頭多做了幾件事。它像一個(gè)有“腦子”的轉(zhuǎn)換頭知道哪個(gè)插座容量不夠時(shí)換另一個(gè)插座供電知道這棟樓的電費(fèi)是多少并幫你記賬知道某個(gè)插座臨時(shí)故障時(shí)自動(dòng)切換到備用口。對(duì)應(yīng)到技術(shù)上就是模型選擇、成本控制、故障轉(zhuǎn)移。這也是我對(duì) LiteLLM 定位的理解它不只是一個(gè)格式翻譯器更是一個(gè) AI 應(yīng)用的流量入口與策略引擎。2. SDK 層實(shí)操?gòu)陌惭b到統(tǒng)一調(diào)用那些模型先聊 SDK 模式因?yàn)樗抢斫?LiteLLM 內(nèi)部邏輯最快的路徑。日常開發(fā)里我用 LiteLLM 的 SDK 模式最多的地方就是寫腳本做模型效果評(píng)測(cè)、跑實(shí)驗(yàn)對(duì)比、或者在小型服務(wù)里快速接一個(gè)模型。它最大的特點(diǎn)就是省事不需要維護(hù)多套 SDK也不用啟動(dòng)任何額外服務(wù)。2.1 環(huán)境準(zhǔn)備與安裝LiteLLM 是一個(gè)純 Python 庫(kù)安裝方式?jīng)]什么特別直接用 pip 就行。有一點(diǎn)需要注意它會(huì)順帶裝不少依賴比如 pydantic、openai 等如果在已有項(xiàng)目里安裝建議單獨(dú)建虛擬環(huán)境避免和項(xiàng)目里其他依賴打架。我一般在做模型接入相關(guān)的項(xiàng)目時(shí)會(huì)直接開一個(gè)新的 venv 或者 conda 環(huán)境。pip install litellm[proxy]這里我用了[proxy]的 extra 安裝因?yàn)槲抑篮竺嬉欢〞?huì)用到代理服務(wù)。如果你只想要 SDK 模式裝pip install litellm就夠。安裝完成之后可以跑一下自帶的版本命令確認(rèn)環(huán)境正常然后順手看一眼支持的模型列表。python -c import litellm; print(litellm.__version__) python -c import litellm; print(litellm.model_list)2.2 首次調(diào)通寫一段最簡(jiǎn)單的模型調(diào)用裝好之后最快驗(yàn)證通路的方式就是調(diào)一次litellm.completion()。大多數(shù)模型服務(wù)都需要 API 密鑰推薦的做法是用環(huán)境變量配置不要硬編碼在代碼里。LiteLLM 默認(rèn)會(huì)讀取一些常見(jiàn)的環(huán)境變量名比如OPENAI_API_KEY、ANTHROPIC_API_KEY等這樣你在代碼里就不用寫api_key參數(shù)了。import os import litellm os.environ[OPENAI_API_KEY] your-openai-key os.environ[ANTHROPIC_API_KEY] your-anthropic-key # 調(diào)用 OpenAI 系模型 response_openai litellm.completion( modelgpt-4o-mini, messages[{role: user, content: 你好請(qǐng)簡(jiǎn)單介紹一下自己}], ) # 調(diào)用 Anthropic 系模型 response_anthropic litellm.completion( modelanthropic/claude-3-5-sonnet, messages[{role: user, content: 你好請(qǐng)簡(jiǎn)單介紹一下自己}], ) print(response_openai.choices[0].message.content) print(response_anthropic.choices[0].message.content)注意看第二段代碼模型名前面多了anthropic/前綴這是 LiteLLM 識(shí)別模型所屬供應(yīng)商的方式。如果你要調(diào) Google 的 Gemini就寫gemini/gemini-1.5-pro調(diào)本地 Ollama 就寫ollama/llama3調(diào) Azure OpenAI 就寫azure/gpt-4o。這個(gè)前綴機(jī)制很重要后面我們講配置文件和排查問(wèn)題時(shí)還會(huì)反復(fù)提到它。我第一次用的時(shí)候犯過(guò)一個(gè)錯(cuò)直接把模型名寫成了claude-3-5-sonnet沒(méi)加anthropic/前綴結(jié)果 LiteLLM 把它當(dāng)成 OpenAI 系的模型去請(qǐng)求然后報(bào)了一個(gè)模型不存在。這件事給我的教訓(xùn)就是LiteLLM 的模型名規(guī)則是“供應(yīng)商前綴 模型名”前綴不能省。想知道一個(gè)模型到底應(yīng)該怎么寫去 LiteLLM 文檔的模型列表里查一次比在代碼里猜要快得多。2.3 進(jìn)階用法流式、異步、函數(shù)調(diào)用模型調(diào)用進(jìn)入真實(shí)業(yè)務(wù)場(chǎng)景之后光會(huì)completion()不夠。最常遇到的是流式輸出需求也就是像 ChatGPT 那樣一個(gè)字一個(gè)字地往外蹦。LiteLLM 對(duì)這個(gè)場(chǎng)景的支持很直接加一個(gè)streamTrue參數(shù)就能拿到生成器。response litellm.completion( modelgpt-4o-mini, messages[{role: user, content: 寫一段關(guān)于秋天的短文}], streamTrue, ) for chunk in response: delta chunk.choices[0].delta.content if delta: print(delta, end, flushTrue)流式返回的每個(gè) chunk 結(jié)構(gòu)基本上和 OpenAI 的流式格式一致所以如果你之前寫過(guò) OpenAI 流式代碼幾乎可以無(wú)縫遷移。還有一點(diǎn)不同供應(yīng)商的流式行為不一致有些是逐 token 返回有些是分塊返回但 LiteLLM 已經(jīng)在內(nèi)部幫你抹平了差異你在上層拿到的永遠(yuǎn)是 OpenAI 風(fēng)格的 chunk。再就是異步調(diào)用。在高并發(fā)場(chǎng)景下用異步能顯著提升吞吐量。LiteLLM 提供了litellm.acompletion()接口用起來(lái)和同步版本幾乎一樣只是需要配合await使用。import asyncio import litellm async def main(): response await litellm.acompletion( modelgpt-4o-mini, messages[{role: user, content: 寫一首五言絕句}], ) print(response.choices[0].message.content) asyncio.run(main())異步版的內(nèi)部實(shí)現(xiàn)實(shí)際上是把請(qǐng)求丟進(jìn)了線程池去處理所以在某些嚴(yán)格限制線程數(shù)的環(huán)境里要注意別把線程池?fù)伪?。另外函?shù)調(diào)用Function Calling在 LiteLLM 里同樣做了統(tǒng)一各家模型只要支持都能識(shí)別 OpenAI 格式的tools參數(shù)這點(diǎn)我在多模型適配的業(yè)務(wù)里用過(guò)多次確實(shí)省心。2.4 SDK 層容易踩的幾個(gè)坑SDK 模式看著簡(jiǎn)單實(shí)際用起來(lái)有幾個(gè)坑值得單獨(dú)提醒。第一個(gè)是環(huán)境變量大小寫問(wèn)題。比如 Azure OpenAI 配置里有一堆像是AZURE_API_VERSION、AZURE_API_BASE之類的變量拼寫和大小寫必須和 LiteLLM 預(yù)期的一致否則認(rèn)證就會(huì)失敗。排查這類問(wèn)題最好的辦法是打開日志設(shè)置litellm.set_verbose True就能看到完整的請(qǐng)求日志。第二個(gè)坑是超時(shí)設(shè)置。LiteLLM 默認(rèn)的請(qǐng)求超時(shí)時(shí)間有時(shí)會(huì)比較長(zhǎng)而且不同供應(yīng)商的默認(rèn)值可能不一樣。如果你的業(yè)務(wù)對(duì)響應(yīng)時(shí)間敏感一定要顯式設(shè)置request_timeout建議給一個(gè)你認(rèn)為合理的值比如 30 秒而不是依賴默認(rèn)值。第三點(diǎn)關(guān)于模型重試。LiteLLM 內(nèi)部自帶簡(jiǎn)單的失敗重試機(jī)制但默認(rèn)的重試次數(shù)、重試間隔不一定適合你的場(chǎng)景。遇到上游服務(wù)限流的問(wèn)題重試反而會(huì)加劇限流所以要認(rèn)真配置num_retries和retry_interval不要盲目提高重試次數(shù)。我現(xiàn)在習(xí)慣把 num_retries 控制在 2 次以內(nèi)讓錯(cuò)誤快速暴露出來(lái)。3. Proxy 模式把模型接入做成一件事如果說(shuō) SDK 模式是給個(gè)人開發(fā)者準(zhǔn)備的便利工具那 Proxy 模式就是給團(tuán)隊(duì)、給生產(chǎn)環(huán)境準(zhǔn)備的基礎(chǔ)設(shè)施。我一開始只用 SDK 模式后來(lái)同事多了人人都來(lái)問(wèn)“你的 API Key 是什么”“我要接的模型怎么配”我才意識(shí)到統(tǒng)一網(wǎng)關(guān)是必然選擇。LiteLLM 的 Proxy 模式本質(zhì)上就是一個(gè)專為 LLM 場(chǎng)景設(shè)計(jì)的 API 網(wǎng)關(guān)。3.1 為什么團(tuán)隊(duì)協(xié)作遲早要走到 Proxy讓大家各自拿著 SDK 接模型短期看著靈活時(shí)間一長(zhǎng)就是災(zāi)難。每個(gè)人的代碼里都有自己的模型配置、自己的密鑰管理方式有人把 API Key 寫死在代碼里有人根本沒(méi)設(shè)超時(shí)。一旦你要給團(tuán)隊(duì)換一個(gè)底層模型就得通知所有人改代碼。這個(gè)場(chǎng)景下Proxy 模式的核心價(jià)值就出來(lái)了模型相關(guān)的所有配置全部收斂到一個(gè)服務(wù)里業(yè)務(wù)代碼只需要知道一個(gè)網(wǎng)關(guān)地址。除了配置收斂Proxy 模式還把一個(gè)很關(guān)鍵的能力帶出來(lái)了——密鑰隔離。你完全可以用一個(gè)網(wǎng)關(guān)主密鑰按團(tuán)隊(duì)、按項(xiàng)目、按個(gè)人生成不同的虛擬密鑰每個(gè)虛擬密鑰可以綁定不同的模型白名單、不同的預(yù)算上限。這樣團(tuán)隊(duì)成員各用各的密鑰互不干擾出問(wèn)題比如某個(gè)密鑰被濫用時(shí)可以直接吊銷不影響其他人。還有審計(jì)日志。LiteLLM Proxy 會(huì)把每次調(diào)用的模型、Token 數(shù)、耗時(shí)、密鑰標(biāo)識(shí)記錄下來(lái)配合數(shù)據(jù)庫(kù)存儲(chǔ)就能做成本分析、用量追蹤。這個(gè)能力在“模型費(fèi)用分?jǐn)偂薄胺?wù)容量規(guī)劃”這些場(chǎng)景下特別有用。一個(gè)網(wǎng)關(guān)把模型接入這件事從“每個(gè)人的技術(shù)活”變成了“平臺(tái)的一項(xiàng)能力”。3.2 config.yamlProxy 的中樞神經(jīng)Proxy 模式的一切配置都圍繞一個(gè) YAML 文件展開叫config.yaml。啟動(dòng)代理時(shí)通過(guò)--config參數(shù)指定這個(gè)文件。這是整個(gè) LiteLLM Proxy 最核心的部分我把一個(gè)生產(chǎn)環(huán)境用得比較多的配置寫出來(lái)逐字段解釋。model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY - model_name: local-llama litellm_params: model: ollama/llama3 api_base: http://localhost:11434 litellm_settings: drop_params: true set_verbose: false num_retries: 2 request_timeout: 30 cache: true cache_params: type: redis host: localhost port: 6379 general_settings: master_key: sk-your-master-key-here database_url: postgresql://user:passwordlocalhost:5432/litellm先看model_list它是路由的入口表。每個(gè)條目有一個(gè)model_name這是你對(duì)外暴露給調(diào)用方的名字業(yè)務(wù)代碼請(qǐng)求的時(shí)候只認(rèn)這個(gè)名字。底下的litellm_params.model才是真正的供應(yīng)鏈路由openai/、anthropic/、ollama/這些前綴決定請(qǐng)求會(huì)被翻譯成哪家格式、發(fā)到哪個(gè)地址。這里一個(gè)比較巧妙的設(shè)計(jì)是多個(gè)條目可以共用同一個(gè)model_name。比如我把同一個(gè)model_name配置到兩個(gè)不同的供應(yīng)商上LiteLLM 就會(huì)在它們之間做負(fù)載均衡。這個(gè)能力在“多云容災(zāi)”場(chǎng)景里很好用OpenAI 掛了流量自動(dòng)轉(zhuǎn)到本地或者其他家。litellm_settings段是全局行為配置。drop_params: true值得專門講一下各家的請(qǐng)求參數(shù)并不完全一樣比如top_p、frequency_penalty這些參數(shù)有些供應(yīng)商根本不支持如果傳過(guò)去就會(huì)報(bào)錯(cuò)。打開drop_params后LiteLLM 會(huì)自動(dòng)丟棄目標(biāo)供應(yīng)商不支持的參數(shù)這個(gè)開關(guān)我強(qiáng)烈建議在生產(chǎn)環(huán)境打開。general_settings段管的是網(wǎng)關(guān)自身的運(yùn)維配置。master_key是代理服務(wù)的主密鑰所有管理接口的訪問(wèn)都要用到它。另外建議開啟database_url把調(diào)用日志、密鑰信息持久化到數(shù)據(jù)庫(kù)里。沒(méi)有數(shù)據(jù)庫(kù)很多統(tǒng)計(jì)功能會(huì)退化為內(nèi)存模式重啟就丟數(shù)據(jù)。3.3 啟動(dòng)代理與驗(yàn)證通路配置文件寫好后啟動(dòng)代理服務(wù)非常簡(jiǎn)單。默認(rèn)監(jiān)聽在 8000 端口你可以通過(guò)參數(shù)調(diào)整。litellm --config ./config.yaml --port 8000啟動(dòng)成功后可以先用一個(gè)簡(jiǎn)單的 curl 請(qǐng)求驗(yàn)證通路。因?yàn)?LiteLLM Proxy 對(duì)外提供的是 OpenAI 兼容接口所以你可以用任何 OpenAI SDK 的客戶端去連它只需要把 base_url 指到代理地址即可。curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-your-master-key-here \ -d { model: claude-sonnet, messages: [{role: user, content: 你好}] }這里傳給model的參數(shù)是config.yaml里定義的model_name也就是claude-sonnet而不是真正的供應(yīng)商模型名。這個(gè)隔離設(shè)計(jì)讓上層業(yè)務(wù)完全不用關(guān)心底層到底是哪個(gè)模型將來(lái)你把claude-sonnet背后的實(shí)現(xiàn)從 Anthropic 換成本地 vLLM業(yè)務(wù)代碼一行都不用改。3.4 虛擬密鑰、預(yù)算控制與負(fù)載均衡Proxy 模式有一個(gè)非常實(shí)用的管理接口體系都是通過(guò) HTTP 調(diào)用的。我用得最多的是/key/generate這個(gè)端點(diǎn)用來(lái)創(chuàng)建虛擬密鑰。你可以限制這個(gè)密鑰能訪問(wèn)哪些模型、能花多少錢甚至綁定到某個(gè)用戶或團(tuán)隊(duì)。curl -X POST http://localhost:8000/key/generate \ -H Authorization: Bearer sk-your-master-key-here \ -H Content-Type: application/json \ -d { models: [gpt-4o-mini], budget: { budget_limit: 100, time_period: 30d } }返回結(jié)果里有一串以sk-開頭的 key把它發(fā)給對(duì)應(yīng)的團(tuán)隊(duì)成員他們就能用這個(gè) key 請(qǐng)求代理。虛擬密鑰的價(jià)值在于第一真正的上游密鑰不會(huì)暴露給任何團(tuán)隊(duì)成員第二每個(gè)密鑰的預(yù)算獨(dú)立誰(shuí)超額了系統(tǒng)會(huì)自動(dòng)攔截不需要人工干預(yù)。負(fù)載均衡的配置在前面說(shuō)過(guò)原理在model_list里model_name相同、litellm_params不同的條目之間LiteLLM 默認(rèn)會(huì)做輪詢分發(fā)。如果你需要不同權(quán)重可以用路由策略參數(shù)控制。這個(gè)能力我通常用在“主備切換”場(chǎng)景一個(gè)容量較大的主力供應(yīng)商、一個(gè)成本較低的備用供應(yīng)商主供應(yīng)商限流時(shí)自動(dòng)降級(jí)到備用。3.5 Proxy 生產(chǎn)化部署的關(guān)鍵經(jīng)驗(yàn)Proxy 模式一旦跑在生產(chǎn)環(huán)境有幾個(gè)經(jīng)驗(yàn)值得分享。第一個(gè)是 Docker 部署。LiteLLM 官方提供了現(xiàn)成的鏡像用 Docker Compose 可以很輕量地把代理服務(wù)和配套的 Redis、PostgreSQL 都編排起來(lái)隔離性比直接裸跑進(jìn)程好很多。我一般會(huì)把config.yaml和.env文件掛載進(jìn)容器不把密鑰寫進(jìn)鏡像。第二個(gè)經(jīng)驗(yàn)是端口與網(wǎng)絡(luò)。如果你的業(yè)務(wù)服務(wù)分布在不同的網(wǎng)絡(luò)區(qū)域要確保它們都能訪問(wèn)到代理服務(wù)的端口同時(shí)做好訪問(wèn)控制不要讓代理端口暴露到公網(wǎng)。建議在代理前面放一層網(wǎng)關(guān)比如自帶鑒權(quán)的 API 網(wǎng)關(guān)負(fù)責(zé)更細(xì)粒度的流量控制。還有個(gè)容易忽略的點(diǎn)代理服務(wù)的日志。日志里會(huì)包含完整的請(qǐng)求參數(shù)和響應(yīng)內(nèi)容這些數(shù)據(jù)里可能有用戶輸入或生成結(jié)果要注意脫敏和訪問(wèn)權(quán)限控制。尤其是在多租戶使用場(chǎng)景下日志數(shù)據(jù)的安全邊界要提前劃清楚別等出問(wèn)題了再去亡羊補(bǔ)牢。4. 常見(jiàn)問(wèn)題排查與避坑實(shí)錄技術(shù)文章寫到最后我一般都會(huì)把自己踩過(guò)的坑整理出來(lái)。LiteLLM 用久了問(wèn)題是會(huì)集中出現(xiàn)在幾個(gè)地方系統(tǒng)性排查效率很高。下面這張表是我在多個(gè)項(xiàng)目里沉淀下來(lái)的高頻問(wèn)題速查配合后面的詳細(xì)解釋一起看?,F(xiàn)象常見(jiàn)原因解決方案模型不存在錯(cuò)誤模型名前忘了加供應(yīng)商前綴檢查model參數(shù)確認(rèn)前綴格式請(qǐng)求超時(shí)默認(rèn)超時(shí)時(shí)間過(guò)長(zhǎng)或模型響應(yīng)慢顯式設(shè)置request_timeout參數(shù)報(bào)錯(cuò)某些供應(yīng)商不支持部分采樣參數(shù)打開drop_params: true流式輸出卡住上游接口不穩(wěn)定或超時(shí)配置太短檢查流式請(qǐng)求的超時(shí)適當(dāng)調(diào)大密鑰鑒權(quán)失敗master_key 或虛擬密鑰配置不對(duì)檢查Authorization頭確認(rèn)密鑰有效并發(fā)一高就失敗連接池或線程池太小調(diào)大并發(fā)數(shù)或考慮多實(shí)例部署緩存命中但結(jié)果奇怪緩存語(yǔ)義錯(cuò)誤地命中了不同請(qǐng)求關(guān)閉緩存或細(xì)化緩存 key4.1 模型名前綴與格式問(wèn)題這個(gè)是我見(jiàn)到開發(fā)者問(wèn)得最多的。LiteLLM 的模型名規(guī)則可以理解為“目標(biāo)供應(yīng)商前綴/模型標(biāo)識(shí)符”。比如 OpenAI 系的可以直接寫gpt-4o-mini也可以寫openai/gpt-4o-mini但 Anthropic 的必須寫anthropic/claude-3-5-sonnetGoogle 的寫gemini/gemini-1.5-pro本地的寫ollama/llama3。很多人剛上手時(shí)不習(xí)慣這個(gè)規(guī)則寫錯(cuò)了就會(huì)得到模型不存在的報(bào)錯(cuò)。判斷方法很簡(jiǎn)單去 LiteLLM 官網(wǎng)的模型列表頁(yè)查一下你要用的模型名它寫了什么你就用什么。如果用了自定義模型名要確認(rèn)litellm_params里面映射的model字段前綴正確。我排查這類問(wèn)題上最快的動(dòng)作就是打開 verbose 日志看實(shí)際發(fā)出的請(qǐng)求地址是什么。4.2 超時(shí)與重試策略怎么配才合理超時(shí)問(wèn)題在接 Anthropic 和 Gemini 時(shí)特別容易遇到因?yàn)樗鼈兊耐评硭俣瓤赡鼙?OpenAI 更慢如果沿用 OpenAI 時(shí)代的超時(shí)設(shè)置就會(huì)頻繁超時(shí)。反過(guò)來(lái)如果你把所有超時(shí)都調(diào)成很大的值一旦上游真的掛了你的應(yīng)用會(huì)長(zhǎng)時(shí)間卡住。我的做法是分層設(shè)置第一層LiteLLM 的request_timeout設(shè)為業(yè)務(wù)可接受的上限比如 30 到 60 秒第二層依賴上游 SDK 自帶的超時(shí)比如有些供應(yīng)商 SDK 默認(rèn)連接超時(shí)是 10 秒讀取超時(shí)是 60 秒。兩層配合既能兜底又能快速暴露問(wèn)題。重試策略上num_retries設(shè) 2 次我認(rèn)為比較平衡間隔時(shí)間建議逐步擴(kuò)大避免同時(shí)間打爆上游。4.3 緩存與日志的兩個(gè)深坑緩存是我用 LiteLLM Proxy 時(shí)最小心的地方。它的緩存機(jī)制可以緩存 LLM 的完整響應(yīng)降低重復(fù)請(qǐng)求的開銷和費(fèi)用。但大模型輸出天然帶有隨機(jī)性如果業(yè)務(wù)要求每次生成結(jié)果不同打開緩存反而會(huì)出問(wèn)題。我建議只在確定性比較強(qiáng)的場(chǎng)景比如知識(shí)問(wèn)答、關(guān)鍵詞提取里開緩存而且最好把緩存的 key 配置得細(xì)一點(diǎn)把 temperature、top_p 這些采樣參數(shù)都納入 key避免不同參數(shù)的請(qǐng)求互相污染。日志這塊前面已經(jīng)提醒過(guò)脫敏問(wèn)題再補(bǔ)一個(gè)點(diǎn)LiteLLM 的日志是可配置的可以根據(jù)需求調(diào)整日志級(jí)別。生產(chǎn)環(huán)境建議把set_verbose關(guān)掉避免記錄過(guò)于詳盡的請(qǐng)求體既能減少存儲(chǔ)壓力也降低敏感信息泄露的風(fēng)險(xiǎn)。出了問(wèn)題需要排查時(shí)臨時(shí)打開 verbose完事再關(guān)掉。5. 一個(gè)很實(shí)用的小技巧在網(wǎng)關(guān)層面做模型 A/B 測(cè)試最后分享一個(gè)我把 LiteLLM 用出額外價(jià)值的場(chǎng)景模型選型對(duì)比。很多團(tuán)隊(duì)想在 OpenAI、Anthropic、本地開源模型之間做效果評(píng)估往往需要寫一套并行調(diào)用代碼然后手工整理結(jié)果。有了 LiteLLM Proxy 之后這個(gè)事變得非常簡(jiǎn)單。思路是在config.yaml里把不同供應(yīng)商的真實(shí)模型映射到同一個(gè)model_name下面然后輪流切換litellm_params.model指向的目標(biāo)或者直接配置兩個(gè)不同名的模型入口。然后用一個(gè)腳本同時(shí)請(qǐng)求這兩個(gè)入口把返回結(jié)果、Token 消耗、響應(yīng)耗時(shí)都記錄下來(lái)做對(duì)比。我實(shí)際用下來(lái)這套方案比在業(yè)務(wù)代碼里寫多供應(yīng)商適配要省事得多。而且因?yàn)橥ㄟ^(guò)網(wǎng)關(guān)統(tǒng)計(jì)成本數(shù)據(jù)也是現(xiàn)成的直接就能算出每個(gè)模型回答一次的平均成本。我當(dāng)時(shí)就是通過(guò)這種方式說(shuō)服團(tuán)隊(duì)把一部分高頻低復(fù)雜度的問(wèn)題從商用模型遷移到本地模型成本降了將近一半效果差距卻很細(xì)微。LiteLLM 這個(gè)東西初看以為是工具用久了會(huì)發(fā)現(xiàn)它更像一種接入模型的“方法論”把復(fù)雜的、易變的模型生態(tài)屏蔽在業(yè)務(wù)視角之外。我個(gè)人到現(xiàn)在仍保持著一個(gè)小習(xí)慣——每次新項(xiàng)目起步接模型先把 LiteLLM 搭起來(lái)再去談業(yè)務(wù)邏輯這省下來(lái)的時(shí)間遠(yuǎn)比想象中要多。如果你正在被多模型接入折磨不妨花一個(gè)下午把 Proxy 跑起來(lái)我相信你也會(huì)得出類似結(jié)論。