# 「減るはず」が、二度外れた：AIへの問い合わせを削る話

> トレカ情報アプリで、AI への問い合わせを減らそうとした記録。45%減るはずが4.5%、配備したのに束ねが0回。数え直して見つかったことを、コミットの数字で書いた。

- URL: https://koshinstudio.com/notes/torecadash-ai/
- 公開: 2026-10-07
- 書いた人: Koshin（https://koshinstudio.com/about/）
- サイト: Koshin Studio

  English version (https://koshinstudio.com/en/notes/torecadash-ai/)

トレカダッシュ 開発の記録 ／ 2026年10月

  iOS アプリ「トレカダッシュ」は、トレカ（ポケカ・遊戯王・ワンピース）の予約・抽選・先着販売の情報を集めて、通知するアプリです。集めた記事が「どの商品の話か」を決める処理に、AI（Gemini）を使っています。この AI への問い合わせを減らそうとして、「減るはず」と書いたものが、二度、外れました。コミットに残っている数字で、順に書きます。

  このサイトには、トレカダッシュの作品ページはまだありません。ここに書くのは、開発の記録です。

## 何をAIに聞いているのか

  記事の題名（たとえば「30th CELEBRATION プレミアムデッキセット エーフィ」）を、最近の商品の候補リスト（直近60件）と突き合わせて、どの商品なのかを AI に答えてもらう、という処理です。1回の問い合わせは約 3,083 トークンで、そのうち約 1,800 は、毎回同じ固定の説明文でした。

## 一つ目：題名が商品名そのものなら、聞かなくていい

  題名が、既知の商品名とそのまま一致するなら、AI に聞く必要はありません。この「短絡」を入れたところ、実データではX の監視で 43%が当てはまりました。食い違い（短絡の答えが、AI の答えと違う）は 0 件です。そこで、これで約 45% 減ると記録しました。

  ところが、配備して90分たっても、短絡は1回も発火しませんでした。数え直すと、こうでした。

    対象 | 短絡できる件数 | 元から無料だった | 新たに減る

    X の監視 | 813 | 768 | 45（2%）

    その他 | 419 | 188 | 231（32%）

  この処理の手前には、公式カタログと照らし合わせる、元から無料の経路がありました。短絡できる記事のほとんどは、そこで先に片付いていたのです。新たに減る分を足すと、1日に約39回、全体の約4.5%。45% ではなく、4.5% でした。

> その規則が当たる割合と、実際に減る呼び出しは、別物。
  手前に無料の経路があるなら、差し引きまで数えないといけない。コミットの教訓の欄には、そう書いてあります。処理自体は正しく安全だったので残しています。ただし、AI の削減としては小さいものでした。

## 二つ目：まとめて聞く

  次の本命は、複数の記事を1回の問い合わせにまとめることでした。固定の説明文が1回で済むからです。候補リストは、同じジャンルの記事なら「最近の60件」を共有するので、合併してもほとんど増えません。

  設計では、二つのことに気をつけました。

- 待ち時間を入れない。実測では、数百ミリ秒の短い窓では、まとめられませんでした（同じ「秒」に来る記事は、24時間で12回だけ）。かといって、数分待つと、X 監視の巡回が5倍遅くなります。そこで、「まだ動いている記事が、全員、待ちに入った瞬間に送る」方式にしました。保険の上限は20秒です。

- 精度を落とさない。まとめると、候補リストが全員ぶんの合併になり、他の記事の候補が見えてしまいます。そこで、答えは本物の商品IDで返してもらい、その記事自身の候補に含まれるかを、必ず検証します。候補外なら採用しません。返事が欠けた記事は、その記事だけ1件で聞き直します。

  効果は、直近2日の実際の記事で、候補リストを再現して測りました（送る文字数）。

    まとめる件数 | 1件ずつ | まとめて | 減り方

    2件 | 21,762字 | 13,427字 | −38%

    3件 | 32,673字 | 14,964字 | −54%

    4件 | 43,571字 | 16,192字 | −63%

    6件 | 65,000字 | 17,729字 | −73%

## 三つ目：配備したのに、一度も束ねていなかった

  配備して6時間。商品照合は47回あり、束ねは0回でした。同じ分に2〜7件の呼び出しがあったのに、1件ずつ聞いていたのです。

  原因は、「送る条件」でした。条件を「待っている数 ≧ まだ終わっていない処理の数（pending）」で見ていたのですが、待ちに入った処理も、pending に含まれていました。X の監視は32アカウントを同時に回します。先に31件が終わっていれば、pending は1。最後の1件が待ちに来た瞬間に、条件が成立して、1件のまま即送信されていました。

  直し方は、「まだ待ちにも来ていない処理がゼロか」で見ること。完全に終わった数と、いま待っている数の合計が、全体に達したら送ります。あわせて、保険の上限を20秒から6秒に縮めました。1件しか来ない回で毎回20秒待つと、X 監視1回の実行（実測17.8秒）より長くなって、巡回が遅れるからです。

  この確認のとき、一つ目の短絡も、見直されました。6時間で、47回中28回（60%）が、AI を呼ばずに済んでいました。短絡は、正しく効いていました。

## 分かったこと

- 「当たる割合」を、削減量と書かない。手前に無料の経路があれば、減るのは差し引き分だけです。

- 配備しただけでは、動いたことにならない。「束ね0回」は、数え直したから見つかりました。ログに「束ねた」と出るかを先に決めておけば、もっと早く気づけたはずです。

- 三つの数字（4.5%、−38〜73%、60%）は、どれも、最初に見積もった数字ではありません。配備したあとに、実データで測り直した数字です。

  この記事の数字は、コミットの記録（2026年9月4日・5日）から取りました。料金の金額は書いていません。

  この話に出てくるもの

- 広告の間隔を、回数ではなく時間で測る (https://koshinstudio.com/notes/adgap/) — 「測っていない」と気づいた、別の記録

- JSONLを読んだら壊れた (https://koshinstudio.com/notes/u2028/) — 数え直して原因が見つかった、別の記録
