117セッション・505MBのAI開発ログを全部数えた
前の記事でセッションログの置き場所を突き止めたあと、フォルダのプロパティを開いて固まった。505MB。テキストしか入っていないはずのファイルが、5か月ぶんの写真より重い。
何にそんな容量を使っているのか気になって、全ファイルをパースして数えることにした。対象は2026年6月26日から8月2日までの33日間、5つのプロジェクトにまたがる117セッション。以下はその集計結果で、数字はすべて手元の実ログから出したものだ。
集計に使ったスクリプト
やっていることは単純で、.jsonl を1行ずつ読んでカウンタを回すだけ。JSON Linesなので全体をメモリに載せる必要がなく、500MBでも1分かからない。
const readline = require('readline');
const rl = readline.createInterface({
input: fs.createReadStream(filePath, { encoding: 'utf8' }),
crlfDelay: Infinity,
});
for await (const line of rl) {
if (!line.trim()) continue;
const d = JSON.parse(line);
if (d.type === 'assistant') {
assistantTurns += 1;
for (const b of d.message.content || []) {
if (b.type === 'tool_use') tools[b.name] = (tools[b.name] || 0) + 1;
}
continue;
}
if (d.type !== 'user') continue;
// ツールの実行結果は user 型で入ってくるので弾く
const c = d.message.content;
if (Array.isArray(c) && c.length && c.every((b) => b.type === 'tool_result')) continue;
if (d.isMeta === true) continue;
humanTurns += 1;
}
肝は下から3行目で、ツールの実行結果を除外しないと「人間の発言」が10倍以上に膨らむ。ここを間違えたまま最初の集計を出してしまい、指示が1万件あることになって数分ほど本気で驚いた。
スラッシュコマンド(<command-name> を含む行)やセッション再開時の要約も user 型で入ってくるので、あわせて弾いている。この除外が効きすぎていないかは別途チェックした。全10,713件の user 型のうち、ツール結果が9,395件、メタ扱いが244件、スラッシュコマンド類が260件、残った814件が人間の発言。桁は合っている。
指示1回に対して、AIは23回動いていた
いちばん驚いたのがこれだった。
| 件数 | 指示1件あたり | |
|---|---|---|
| 人間の指示 | 814 | — |
| AIの応答 | 18,774 | 23.1回 |
| ツールの実行 | 9,424 | 11.6回 |
「ファイルを直して」と一言打つと、その裏で平均11.6回のツールが動き、23回の応答が積み上がる。505MBの正体はこれだった。会話としては814往復しかしていないのに、記録としては2万行を超えている。
体感としても、指示を出したあと画面が数分間ひとりでに流れていくことは多い。ただ、それが平均で23回という具体的な数だと分かると受け止め方が変わる。1回の指示のコストは、自分が打った文字数ではなく、その裏で回る23回のほうで決まっている。
AIの仕事の半分は「書く」ではなく「確かめる」
ツールの内訳を見ると、はっきりした偏りが出た。
Bash が4,031回で断トツ。PowerShell の281回を足すと4,312回、全ツール実行の46%がコマンド実行になる。対してファイルを書き換える Edit と Write は合計2,163回で23%。読み取り系の Read と Grep が2,019回で21%。
つまりAIは、コードを書いている時間よりコマンドを叩いて状態を確かめている時間のほうが倍近く長い。テストを走らせ、gitの差分を見て、ビルドを回して、その出力を読む。人間の開発者がやっていることと、比率まで含めてよく似ている。
これは「AIがコードを書いてくれる」というイメージと実際の作業のズレでもある。生成そのものは全体の2割強で、残りは検証と探索に消えている。逆に言えば、確かめる手段が用意されていない作業ほどAIは弱い。手元のプロジェクトでも、コマンドで結果を確認できるもの(テスト、ビルド、HTTPステータス)は速く片付き、目で見ないと分からないもの(レイアウトの崩れ、3Dの姿勢)は何度もやり直しになっている。
人間の指示は、3回に1回は20文字以下
逆方向、つまり人間が何を書いているかも数えた。814件の指示の長さの分布はこうなった。
| 文字数 | 件数 | 割合 |
|---|---|---|
| 20文字以下 | 269 | 33% |
| 21〜50文字 | 190 | 23% |
| 51〜200文字 | 145 | 18% |
| 201文字以上 | 210 | 26% |
平均は242文字だが、これは長文のペースト(エラーログの貼り付けなど)に引っ張られた数字で、実態は3件に1件が20文字以下。「コミットして」「まだ出てない」「これで」くらいの短さだ。
プロンプトエンジニアリングの記事を読むと、丁寧で構造化された長い指示が推奨されている。しかし33日間の実ログでは、その形で書いた指示は4分の1しかなかった。長く書いているのはたいてい最初の依頼で、そこから先は短い相槌が続く。実際の使われ方は、仕様書を渡す作業というより会話に近い。
セッションの長さにも同じ偏りがあった。117セッションのうち60本は指示が1〜5回で終わっている。一方でいちばん長いセッションには104回の指示が入っていた。短いセッションが数を稼ぎ、少数の長いセッションが容量を稼ぐ、という構図になっている。
なお117本のうち19本は人間の発言が0件だった。起動して何も言わずに閉じたセッションで、これも記録としては残る。
トークンの99%はキャッシュの読み直し
課金に直結する数字も出しておく。33日間の合計はこうだった。
| 項目 | トークン数 |
|---|---|
| 出力 | 20,007,812 |
| キャッシュ読み込み | 3,625,285,595 |
| キャッシュ書き込み | 142,088,784 |
出力が2,000万トークン。応答1回あたり約1,066トークンで、これは体感と合う。
問題はその下で、キャッシュの読み込みが36億トークンある。応答1回につき平均19万トークンを読み直している計算になる。長いセッションでは会話の履歴もファイルの中身も全部コンテキストに載ったままなので、1回応答するたびにその全部を読み直す。プロンプトキャッシュが無ければ成立しない規模で、逆に言えばこのワークフローはキャッシュが効くことを前提に組まれている。
セッションを短く切ったほうがいいと言われる理由が、この数字を見てようやく腑に落ちた。文脈が長くなるほど、1回の相槌が重くなる。
この数え方の限界
正直に書いておくと、いくつか自信のない部分がある。
isMeta とマーカー文字列による除外は、Claude Code側の実装に合わせた経験則でしかない。バージョンが変われば取りこぼす。今回は除外後の件数を手で検算して桁が合うことを確かめたが、1件単位の正確さは保証できない。
サブエージェント(Agent ツールで起動した別セッション)の中身も、この集計には入っていない。本体のログでは isSidechain の行が0件で、委譲した先の作業は別ファイルに落ちている。46回の Agent 呼び出しの裏側は、この505MBには含まれていない。
それと、これは私1人・33日間・5プロジェクトの数字であって、一般的な傾向ではない。Unity製アプリと静的サイトとReactアプリが混じった構成なので、ツールの比率はプロジェクトの性質にかなり引きずられているはずだ。
自分のログでも数えられる
集計スクリプトはリポジトリに置いてある(scripts/loganalysis/analyze-sessions.js)。ログのあるフォルダを走査して、統計値だけのJSONを吐く。生の本文は一切出力しない作りにしてあるので、出力をそのまま人に見せても事故らない。
node scripts/loganalysis/analyze-sessions.js --out stats.json
自分の数字が出ると、「AIに任せている」という感覚がどのくらい具体的な作業量なのかが見える。私の場合は、23:1という比率を知ってから指示の出し方が少し変わった。次は、その814件の指示のうち何件が「やり直し」だったのかを数えた話を書く。