エージェントがAPIコール数を決定する場合、コスト上限はその日のエージェントの気分次第になります。ほとんどの日は問題ありませんが、ツールがエラーを起こし、チェーンが再試行を繰り返す日にはそうはいきません。そしてその間、ログには何もおかしな点は表示されません。
私は budget-guard をメンテナンスしています。これはLLM API請求のための小さなオープンソースサーキットブレーカーです。LangChain.jsアダプターがあり、統合全体が1つのコールバックハンドラーで済みます:
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
これがセットアップのすべてです。モデル呼び出しの前に、ハンドラーはプロジェクトがその日にどれだけ使用したかを確認します。上限未満の場合、呼び出しが実行され、実際のトークン使用量がUSDに変換されて累計に追加されます。上限を超えた場合、リクエストがプロセスから送信される前に BudgetExceededError をスローするため、暴走ループはブロックされた100回目の呼び出しではなく、最初の呼び出しで終了します。
実践で重要な詳細がいくつかあります。
上限はトークンではなくドルです。 キャッシュされた入力と推論トークンがそれぞれ独自の価格を持つようになって以来、トークンは有用な単位ではなくなりました。1つの「トークン」が単一のレスポンス内で4つの異なるレートで請求されることがあります。ハンドラーは usage_metadata を読み取り(古いコードパスでは llmOutput.tokenUsage にフォールバック)、キャッシュされた入力とキャッシュされていない入力を分割し、プロバイダーが別途請求する推論トークンをカウントし、各部分に価格を設定します。
feature タグはスキップすべきではない部分です。 単一の日次合計では問題があることがわかります。機能ごとの内訳ではどこに問題があるかがわかります。私の場合、漏洩は数週間誰も考えていなかったエンリッチメントジョブで、総支出の60%を静かに占めていました。
ブロッキングが機能するのは、ハンドラーが内部で raiseError を設定するためです。 LangChainはコールバックエラーをデフォルトで飲み込むため、上限が単なる丁寧な提案になってしまいます。ここでは設定する必要はありませんが、スローが実際にチェーンを停止する理由を知っておく価値があります。
デフォルトではプロセスローカルです。 デフォルトストアはプロセスが再起動するとリセットされます。Redisストアがあり、ワーカーフリート全体で1つの上限を共有できます(アトミックなreserve-then-settleパスがあり、100の同時呼び出しが一緒に制限を超えることはできません)、また数秒しか存在しないcronジョブ用のファイルストアもあります。
そして意図的に行わないこと:ゲートウェイではなく、ダッシュボードもなく、それを通さない呼び出しを見ることもできません。ヒューズボックス内のブレーカーであり、電力会社ではありません。すでに完全なLLM可観測性プラットフォームを実行している場合、おそらくこれを必要としないでしょう。1つのNodeアプリがあり、使用状況ページについて不安を感じている場合、npm i budget-guard と上記の5行で済みます。
これを構築するに至った教訓は、以前の投稿にあります: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.