「なぜそうしたか」を履歴から引くと1,166,528トークン、専用インデックスなら5,893 — AI利用コスト実測レポート #03
この記事について
第2回は「今のコードはどう繋がっているか」をコードグラフで引く話だった。今回は対になるもう半分、「なぜそうしたか」を過去のセッション履歴から引く側を測る。
道具は ctx(ctx.rs、Rust製・完全ローカルのエージェント履歴横断検索)。Claude Code などのセッションログを SQLite にインデックスし、ctx search で横断検索する。測定日時点のインデックス規模は下表のとおり。
| 項目 | 値 |
|---|---|
| 測定日 | 2026-07-30 |
| インデックス済みアイテム | 87,980件 |
| インデックス済みソース | 320件 |
| カタログ済みセッション | 61件 |
| データ配置 | ローカルの SQLite 1本(外部送信なし) |
| トークナイザ | tiktoken o200k_base(第2回と同一。Claude のものではないため絶対値は近似) |
第2回と同じく、測るのは推論ではなくツール出力としてコンテキストへ流し込まれる量である。
測り方
比較対象は「ctx が無かったらどうするか」——生のセッションログ(~/.claude/projects/**/*.jsonl)を直接 grep する経路にした。
| 列 | 中身 |
|---|---|
grepのみ | 履歴 jsonl を grep した出力だけ |
grep+読了 | grep 出力 + ヒットしたセッションファイルを実際に開いて読んだ場合 |
ctx | ctx search "…" --limit 5 の出力 |
baseline を非現実的に膨らませないための条件を2つ置いた。
- 読むファイルは上位3本まで。履歴 jsonl は1本で数MBあり、全件読ませると baseline が現実離れして比較が不誠実になる
- 1ファイルあたり先頭400,000バイトで打ち切り。実際のエージェントも上から一定量読んで打ち切る
そして第2回と同じ方針で、ctx が負ける問いを混ぜた。
結果
| 問い | 種類 | grepのみ | grep+読了 | ctx |
|---|---|---|---|---|
| CF Pages のビルドが11日間止まっていた原因は何だったか | 経緯 | 35,769 | 347,112 | 1,291 |
| CI の自動マージをローカル常駐に移したのはなぜか | 経緯 | 80,679 | 560,289 | 1,302 |
| 無人セッションが長時間ハングした原因は何だったか | 経緯 | 12,440 | 257,163 | 907 |
| 画像最適化スクリプトは何という名前か | 現状 | 39 | 39 | 962 |
| 今の公開系ルールは何条あるか | 現状 | 1,925 | 1,925 | 1,431 |
| 合計 | 130,852 | 1,166,528 | 5,893 |
経緯を問う3問だけの小計は 1,164,564 → 3,500 トークン(99.7%減)。桁が3つ変わる。
理由は単純で、生の履歴には答えではなく会話が入っているからだ。該当セッションを開くと、結論の1段落に辿り着くまでにその日の全やりとりを読むことになる。
現状を問うと負ける
下2問はどちらも ctx が高いか、勝っていても意味がない。
$ ls scripts/ | grep -i image # 39トークン。これが答え
$ ctx search "画像最適化 スクリプト WebP 変換" --limit 5 # 962トークン
「今どうなっているか」を聞かれたら、現物を見るのが最も安い。 ファイル一覧は最初から短く、履歴検索は過去の議論を引いてくるぶん重い。
より重要なのは最後の1問である。ルール文書の現行条文を問うと、ctx は 1,431 トークンで、直接読む 1,925 トークンより安い。だが返ってきたのは 2026-06-24 や 2026-07-06 のセッションでの議論であって、現行の条文ではない。
| 観点 | 直接読む | ctx |
|---|---|---|
| トークン | 1,925 | 1,431(安い) |
| 返ってくるもの | 現行の条文そのもの | 過去にその話をした会話 |
| 答えになるか | ✅ | ❌ |
トークンが安いことと、答えになっていることは別の話である。安い方を選ぶ判断を機械化すると、この問いでは静かに間違える。ベンチマークの数字だけを見て道具を選ぶと踏む穴として、消さずに残しておく。
上位2件で答え、下位3件はノイズ
勝った側も手放しではない。実際の出力を見ると、答えているのは上位2件までだった。
1. importance 1.00 | 2026-07-01 → 監視パスが誤設定で毎ビルド skipped。正しくは単一 `*`
2. importance 0.90 | 2026-07-07 → 別件のビルド全滅。原因特定済み
3. importance 0.28 | 2026-07-19 → 無関係
4. importance 0.26 | 2026-07-17 → 無関係(記事整理の話)
5. importance 1.00 | 2026-06-20 → 別の日の別のビルド不安定
1件目が探していた答えそのもの(監視パスに ** を書いたせいで全ビルドが skipped 扱いになっていた件)で、importance スコアも 1.00 で最上位に来ている。一方 3・4件目は 0.3 未満のノイズで、素直に --limit 5 で引くと3件ぶんの無駄が乗る。
実運用では --limit 3 程度に絞り、当たりを引いてから ctx show event <id> --window 10 で前後を開くのが安い。検索結果は答えではなく入口として扱う。
何と何を使い分けるか
第2回のコードグラフと合わせると、担当が綺麗に割れる。
| 問い | 道具 | 正となるデータ |
|---|---|---|
| 今どう繋がっているか | コードグラフ | ソースの AST |
| 今どうなっているか | 現物を読む | ファイルそのもの |
| なぜそうしたか | ctx | 過去のセッション履歴 |
| これからどうするか | ルール文書・設計文書 | リポジトリ内の正本 |
ctx が代替できるのは3行目だけである。ここは従来、人間の記憶か、諦めて再調査するかしかなかった領域だった。再調査は同じ失敗をもう一度踏むまで始まらないことが多く、コストは今回測った 1,164,564 トークンより遥かに高い。
再現方法
測定スクリプトはリポジトリに置いた。同じ5問を同じ条件で回し直せる。
uv run --with tiktoken python3 scripts/ctx_token_bench.py
問いはすべて、このリポジトリで実際に事故として起きて後から掘り直したものを使っている(ビルド11日凍結・CI 常駐移設・無人セッションのハング)。架空のクエリで測ると、履歴に都合よく答えが入っている問いばかりを選んでしまうためである。
次回予告
次はモデル別(Opus/Sonnet/Fable/Haiku)の使用比率とコスト構成比を見る。用途に応じた使い分けが実際にコストを下げているかを確認する回にする。
なお ctx の導入手順そのもの(3台への展開、インデックスを同期しない判断、Antigravity のログが既定パスに無い件)は、このシリーズとは別に導入記録として書く。