LLM APIの無駄なコストで月1,240ドルを見つけた方法(そして自分の無駄を探すツールも作った)

Dev.to / 2026/4/5

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical Usage

要点

  • 著者は、月額2,847ドルの支出のうち、リトライ、重複、過剰なコンテキスト長などにより回避可能なLLM APIの無駄を、約1,240ドル/月と特定したと報告している。
  • 主な無駄の内訳は、JSONをmarkdown内に含めてしまったことが原因で発生したリトライ呼び出し(34%)、キャッシュが欠如していたために重複して行われた分類器呼び出し(85%)、単純なyes/no判定にGPT-4oを使う代わりにより安価なモデルを使えるのに使ってしまった点、などである。
  • チャットボットのコストは、会話の全文履歴を毎回送信し続けたことが要因だった。著者は、直近の数メッセージだけに切り詰めることで、約155ドル/月の節約につながることを見つけた。
  • 同様の問題を測定し、予防するために、著者はオープンソースのPython CLI(「LLM Cost Profiler」)を作成した。既存のLLMクライアントをラップし、API呼び出しをローカルのSQLiteデータベースに記録する。
  • 計測ツールは非侵襲的に設計されており、ログはサイレントで、計測のインストゥルメンテーションが失敗してもアプリケーションに影響を与えないことを意図している。OpenAIとAnthropicの両方のクライアントをサポートしている。

私は、いくつかのプロジェクトで OpenAI と Anthropic の API に毎月約 $2,000 かけていました。

そのうち一部が無駄だということは分かっていました。ただ、証明できませんでした。プロバイダーのダッシュボードには、表示されるのは1つの数値 — つまり総請求額だけです。それは内訳のない電気代の請求書をもらうようなものです。エアコンのせい? 照明? サーバールーム? 見当もつきません。

そこで、原因を突き止めるためのツールを作りました。分かったことは、正直かなり恥ずかしい内容でした。

What I found

要約(summarizer)の呼び出しの 34% がリトライでした。 プロンプトは JSON を返すよう求めていましたが、モデルがそれを markdown のコードブロックで包み続けました。私のパーサーはそれを拒否しました。そのためリトライループが同じ呼び出しをもう一度実行し、また実行しました。リトライのたびにお金がかかります。合計の無駄は約 $140/月 — ずっと前に直せた、たった6語の修正です。

分類(classifier)の呼び出しの 85% が重複でした。 同じ入力で同じ出力なのに、そのたびに毎回フル料金。キャッシュなしです。週あたり 847 回中 723 回が完全に無駄でした。単純なキャッシュで $310/月 削減できたはずです。

私の classifier は yes/no タスクに GPT-4o を使っていました。 出力は常に 10 トークン未満でした — 固定ラベル5つのうちのどれかです。GPT-4o-mini なら、はるかに安いコストでまったく同じ結果を返します。節約額:$71/月。

私のチャットボットは、すべての会話履歴を毎回の呼び出しに詰め込んでいました。 メッセージ20の時点で入力は 3,200 トークンになり、さらに増えていきました。重要なのは直近の数メッセージだけです。最後の5メッセージに切り詰めれば $155/月 を節約できます。

合計:$2,847/月 のうち $1,240/月 が無駄。これは 43% です。

The tool: LLM Cost Profiler

これらすべてを、オープンソースの Python CLI にまとめました。仕組みはこうです。

Step 1: Install

pip install llm-spend-profiler

Step 2: Wrap your client (2 lines of code)

from llm_cost_profiler import wrap
from openai import OpenAI

client = wrap(OpenAI())

それだけです。あなたのコードはまったく同じように動きます。すべての API 呼び出しが、裏で自動的にローカルの SQLite データベースに記録されます。何らかの理由で記録に失敗しても、静かに失敗します — アプリには一切影響しません。

Anthropic でも動きます:

from anthropic import Anthropic
client = wrap(Anthropic())

Step 3: See where your money goes

$ llmcost report
LLM Cost Report — Last 7 Days
========================================
Total: $847.32 | 2.4M tokens | 12,847 calls

By Feature:
  summarizer         $412.80  (48.7%)  ████████████████████
  chatbot            $203.11  (24.0%)  ████████████
  classifier          $89.40  (10.5%)  █████
  content_gen         $78.22   (9.2%)  ████
  extraction          $41.50   (4.9%)  ██
  untagged            $22.29   (2.6%)  █

Warnings:
  ⚠ summarizer: 34% of calls are retries ($140.15 wasted)
  ⚠ chatbot: avg 3,200 input tokens but only 180 output tokens (context bloat)
  ⚠ classifier: using gpt-4o but output is always <10 tokens (cheaper model works)

Step 4: Find the waste

$ llmcost optimize
LLM Cost Optimization Report
========================================
Current monthly spend (projected): $2,847
Potential savings found: $1,240/month (43.5%)

  #1 CACHE — classifier.py:34                        [SAVE $310/mo]
     85% of calls are exact duplicates (723 of 847/week)
     → Add @cache decorator
     Confidence: HIGH

  #2 RETRY FIX — content_gen.py:112                   [SAVE $180/mo]
     28% retry rate from JSON parse errors
     → Fix prompt to return raw JSON
     Confidence: HIGH

  #3 MODEL DOWNGRADE — classifier.py:34               [SAVE $71/mo]
     Output is always <10 tokens, one of 5 fixed labels
     → Switch gpt-4o to gpt-4o-mini
     Confidence: MEDIUM

  #4 CONTEXT BLOAT — chatbot.py:123                   [SAVE $155/mo]
     Avg 3,200 input tokens, growing over conversation
     → Truncate history to last 5 messages
     Confidence: MEDIUM

各推奨には、正確なファイル名と行番号、見積もりの月間削減額、そして確信度(confidence level)が含まれます。

Other features worth knowing about

llmcost hotspots — コードの場所をコスト順に並べ替えます。Python の呼び出しスタックから自動検出するため、手作業の注釈は不要です:

Top Cost Hotspots:
  1. features/summarizer.py:47   summarize_doc()    $412.80/week   4,201 calls
  2. api/chat.py:123             handle_message()   $203.11/week   3,892 calls
  3. pipeline/classify.py:34     classify_text()     $89.40/week   2,847 calls

llmcost compare — 週ごとの比較で、急なスパイクを見つけます。

llmcost dashboard — localhost:8177 でローカルの Web ダッシュボードを開きます。ツリーマップ図、コストのタイムライン、最適化のウォーターフォールを表示します。HTML ファイルは1つだけで、npm もビルド工程も不要です。

タグ付け(Tagging) — 機能、顧客、または環境ごとにコストをグループ化:

from llm_cost_profiler import tag

with tag(feature="summarizer", customer="acme_corp"):
    response = client.chat.completions.create(...)

キャッシュデコレーター — 重複呼び出しの支払いをやめる:

from llm_cost_profiler import cache

返却形式: {"translated": "翻訳されたHTML"}@cache(ttl=3600)
def classify_text(text):
    return client.chat.completions.create(...)

背後でどのように動いているか

  • Wrapper: 透過的プロキシパターン — パッチ適用(monkey-patching)なしでメソッド呼び出しを傍受します。
  • Storage: ~/.llmcost/data.db のWALモードを使用したSQLite。スレッドセーフです。
  • Pricing: OpenAIおよびAnthropicのモデル用の内蔵ルックアップテーブル。
  • 呼び出し元の検出: Pythonのコールスタックをたどり、各呼び出しを引き起こした関数を自動検出します。
  • 依存関係ゼロ: Python標準ライブラリのみを使用します。
  • プライバシー: すべてローカルに留まります。どこにも送信されません。

自分のコードベースで試してみる

どんなプロジェクトでもLLM API呼び出しを行っているなら、そこで何を見つけるのか本当に気になります。私の経験では、どのコードベースにも少なくとも1つは意外な発見があるはずで、たいていは誰も知らなかった重複呼び出しです。

GitHub: https://github.com/BuildWithAbid/llm-cost-profiler
Install: pip install llm-spend-profiler
License: MIT

問題点を見つけた場合や、ほかに何を検出すべきかアイデアがある場合は、issueを開くか、ここにコメントしてください。これは私にとって最初のオープンソースプロジェクトなので、ぜひフィードバックが欲しいです。