AIにAPIを叩かせるなら、コストは自分で見ろ
📊この記事の図解版があります。内容を視覚的にまとめたページで、全体像をサッと把握できます
図解を見るAIにAPIを叩かせるなら、コストは自分で見ろ
「クレジットが足りない」という警告が出た。
想定より、明らかに早い。
X API を Pay-per-use(従量課金)で使っている。自作の投稿支援ツールを1日2〜3回動かす程度だ。月のクレジットが余裕で足りる計算だった。なのに、まだ月の半ばで警告が飛んできた。
「まあ、もう少し課金すればいいか」とは思わなかった。計算が合わないなら、原因がある。原因があるなら、直せる。
この記事は、AIツールが裏で叩いているAPIのコストを可視化し、キャッシュで9割削減した実践記録だ。技術的には地味な話だが、小さな違和感をスルーしないという姿勢の話でもある。
AIは気前よくAPIを叩く
僕は x-post というCLIツールを自作して使っている。X(旧Twitter)への投稿をAIが支援してくれるツールだ。投稿案の生成、エンゲージメント分析、フォロワーの増減トラッキング——ひと通りの機能が揃っている。
このツールはX APIを従量課金プランで叩いている。1日2〜3回実行する程度だから、月のクレジットには余裕があるはずだった。
問題は、AIが毎回律儀に全データを取りに行く設計になっていたことだ。
フォロワーリストの取得を例にとる。フォロワー660人。APIは1回のリクエストで最大100件しか返さない。つまり全件取得するには7回のAPIコール(ページネーション)が必要になる。これを毎回の実行でやっていた。
さらにエンゲージメント(いいね・リポスト・返信の数)も、30日以内の全投稿を毎回取得していた。朝に取得したデータを、昼にもう一度取りに行く。数時間で劇的に変わるわけがないのに。
内訳はこうだ。フォロワーリスト取得に7コール、エンゲージメント取得に1コール、自分のプロフィール情報取得に1コール。合計9コール。1日3回実行すれば27コール。月810コール。クレジットが減るのは当然だった。
原因は「キャッシュがない」だけだった
原因を調べるのに30分もかからなかった。
コードを読めば一目瞭然だ。フォロワーリスト取得のロジックに、前回取得したデータを再利用する仕組みが一切なかった。毎回APIを叩いて、毎回全件取得して、毎回保存する。正直で愚直な実装だ。
面白いことに、前回の実行結果(スナップショット)には follower_ids というフィールドが保存されていた。データはあるのに、次の実行時に参照していなかった。宝の持ち腐れだ。
問題を3つに分解する。
| # | 無駄 | 内容 |
|---|---|---|
| 1 | フォロワー全件取得 | 660人を毎回7 APIコールで取得。前回データを使わない |
| 2 | エンゲージメント毎回取得 | 6時間前に取ったデータをまた取りに行く |
| 3 | 既存データ未活用 | スナップショットに follower_ids があるのに無視 |
3つとも、答えは同じだった。キャッシュを入れればいい。
キャッシュとは、一度取得したデータを手元に保存しておいて、次回はそれを使い回す仕組みのことだ。ウェブ開発の世界で何十年も使われてきた、古典中の古典。TTL(Time To Live = データの有効期限)を設定して、期限内なら前回の結果をそのまま返す。それだけの話だ。
古い技術が、ちゃんと効く
実装した対策は3つ。
1. フォロワーリストに24時間キャッシュ(効果: 最大)
前回の取得から24時間以内なら、APIを叩かずにキャッシュを使う。判定ロジックはシンプルだ。
| 優先度 | 条件 | 判定 |
|---|---|---|
| 1 | 前回データなし or 空 | API取得 |
| 2 | 前回取得から24時間超 | API取得 |
| 3 | 最新のフォロワー数とキャッシュの件数が5件以上乖離 | API取得 |
| 4 | 上記いずれにも該当しない | キャッシュ使用 |
優先度3がポイントだ。プロフィール情報(meコマンド)で取得した最新のフォロワー数と、キャッシュに保存されているフォロワーIDリストの件数を比較する。フォロワーが急に増減した場合は、TTL内でもAPIを叩き直す。「24時間キャッシュだからフォロワーが100人増えても気づかない」ということは起きない。
「24時間」という値に深い根拠はない。フォロワーリストは1日に何度も確認するものではないから、1日1回の更新で十分だろう、という判断だ。厳密に計算して出した数値ではなく、まず入れてみて、問題があれば調整すればいい。キャッシュTTLは設計書で決めるものではなく、運用で育てるものだ。
2. エンゲージメント取得に6時間TTL(効果: 中)
こちらも同じ考え方だ。投稿してから30日以内のツイートのエンゲージメントを追跡しているが、数時間で劇的に変わることは少ない。6時間のTTLを設定して、その間は再取得をスキップする。
| 条件 | 判定 |
|---|---|
| エンゲージメント未取得 | 取得 |
| 投稿から30日超 | スキップ(確定値) |
| 前回取得から6時間以内 | スキップ |
| 上記以外 | 再取得 |
3. usage サブコマンドの追加(効果: 可視化)
python3 x-api-client.py usage --days 7
実行すると、日ごとのAPI使用量が棒グラフで表示される。
日次使用量(直近 7 日):
日付 件数 グラフ
------------------------------------------
2026-03-05 12 ######
2026-03-06 8 ####
2026-03-07 15 ########
2026-03-08 3 ##
2026-03-09 2 #
2026-03-10 1 #
2026-03-11 2 #
合計: 43 件(直近 7 日)
月次のリセット日、日ごとの消費トレンドが一目でわかる。見えないものは管理できない。 コストの可視化は、最適化の第一歩であり最後の砦でもある。
キャッシュを入れるときの注意
キャッシュは万能ではない。24時間の間にフォロワーが入れ替わっていても、キャッシュ内のデータは古いままだ。今回の用途——投稿支援ツールのフォロワー分析——ではこの程度のズレは許容できる。しかし、課金判定や認証に関わるデータに同じ設計を適用してはいけない。「このデータが古くても、何が困るか?」を考えてからTTLを決める。答えが「特に困らない」なら、キャッシュを入れていい。
9コールが2コールになった
改善前後の比較をまとめる。
| 指標 | 改善前 | 改善後 |
|---|---|---|
| 1回あたりのAPIコール | 約9回 | 1〜2回(通常時) |
| フォロワー取得(日次) | 14〜21コール | 最大7コール |
| エンゲージメント取得(日次) | 実行回数 × 投稿数 | 最大4回/日 |
| 月間推定(1日3回実行) | 約810コール | 約90コール |
月810コールが90コールになった。約89%の削減。通常の実行——フォロワーリストのキャッシュが有効で、エンゲージメントのTTLも切れていない状態——では、APIコールは自分のプロフィール情報の取得(1コール)だけだ。
この変更はClaude Codeのサブエージェント機能を使って、シニアエンジニア役のAIにレビューさせた。2ラウンドのレビューでMedium指摘が2件出て、修正してGoをもらった。AIが書いたコードを、別のAIがレビューする。人間の仕事は「違和感に気づくこと」と「最終判断を下すこと」だ。
小さな違和感をスルーするな
クレジットの警告が出たとき、「まあ、追加課金すればいいか」と思うこともできた。月数百円の話だ。ビジネスインパクトは小さい。
でも、「計算が合わない」という違和感をスルーしなかったから、原因を30分で特定できた。キャッシュという古典的な手法で9割削減できた。
これはAPIコストの話だけではない。
「テストが1件だけ落ちてるけど、関係なさそうだから無視しよう」 「レスポンスが少し遅くなったけど、まあ許容範囲か」 「エラーログが増えてるけど、動いてるから大丈夫だろう」
こういう「まあいっか」の積み重ねが、コードの品質を静かに蝕む。小さな違和感をスルーする目は、大きなバグもスルーする。
AIにAPIを叩かせる時代だからこそ、コストの感覚は人間が持っていないといけない。AIは「このAPIコール、本当に必要ですか?」とは聞いてくれない。気前よく、正直に、愚直にAPIを叩く。それを監視し、最適化の判断を下すのは、人間の仕事だ。
もしあなたもAIツールを作っているなら、まず1つだけやってみてほしい。ツールが1回の実行で何回APIを叩いているか、数えてみろ。 想定より多かったら、そこにキャッシュの余地がある。
違和感を感じたら、立ち止まれ。30分の調査が、月のコストを9割減らすこともある。
関連記事
- AIの「できます」を信じるな — 一次情報に当たる技術 — AIの回答を検証する習慣と、公式ドキュメントでの裏取りの実践
- AIコーディングツールに「取扱説明書」を書いたら、開発が変わった — AIへのルール整備とコンテキスト管理の運用記録