如果代理決定要發出多少 API 呼叫,成本上限就取決於代理當天的「感覺」。大多數日子都還好,但當工具發生錯誤,鏈路開始重試時,就不是那麼一回事了,而且在發生時,您的日誌裡看不出任何異常。
我維護 budget-guard,這是一個小型開源的 LLM API 帳單斷路器。它有 LangChain.js 配接器,整個整合只需要一個回呼處理程式:
import { ChatOpenAI } from '@langchain/openai';
import { BudgetGuardHandler } from 'budget-guard/langchain';
const handler = new BudgetGuardHandler({
project: 'my-app',
dailyCapUSD: 25,
model: 'gpt-4o',
feature: 'support-bot',
});
const model = new ChatOpenAI({ model: 'gpt-4o' });
await model.invoke(messages, { callbacks: [handler] });
Enter fullscreen mode Exit fullscreen mode
這就是全部的設定。在每次模型呼叫前,處理程式會檢查該專案當天的花費。在上限內,呼叫就會執行,並將實際的 token 使用量換算成美元,累加到目前總額。超過上限時,會在請求離開您的程序前丟出 BudgetExceededError,讓失控迴圈在第一次被阻擋的呼叫就中止,而不是等到第一百次。
以下是一些實務上需要注意的細節。
上限是以美元為單位,而不是 token。自從快取輸入與推理 token 各自定價後,token 就不再是實用的單位。一個「token」在單一回應中,可能會依四種不同費率計費。處理程式會讀取 usage_metadata(在較舊的程式路徑則退回到 llmOutput.tokenUsage),將快取輸入與非快取輸入分開,計算提供者另外計費的推理 token,並對各部分定價。
feature 標籤是我不會省略的部分。單一的每日總額只會告訴您有問題,但按功能細分的明細才能告訴您問題出在哪裡。在我的案例中,洩漏是來自一個已經好幾週沒人想起的資料豐富化工作,悄悄地佔了總支出的 60%。
阻擋之所以有效,是因為處理程式內部設定了 raiseError。LangChain 預設會吞掉回呼錯誤,這會讓上限變成一個禮貌性的建議。這裡不需要任何設定,但值得了解為什麼這個拋出錯誤真的能停止鏈路。
預設是程序本地的。預設的儲存體會在程序重新啟動時重置。有一個 Redis 儲存體,能讓整個 worker 叢集共用同一個上限(使用原子性的「先保留再結算」路徑,因此一百個並行呼叫不會一起超過限制),以及一個檔案儲存體,適合只存活數秒的 cron job。
而它刻意不做的事:它不是一個閘道,沒有儀表板,也看不到不經過它的呼叫。它是您配電箱裡的斷路器,而不是電力公司。如果您已經在使用完整的 LLM 可觀測性平台,可能就不需要這個。如果您只有一個 Node 應用程式,且對使用量頁面感到不安,安裝 npm i budget-guard 並使用上面五行程式碼即可。
導致建立它的經驗教訓,已在之前的文章中說明:7 things I learned trying to stop LLM API bills from silently exploding。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.