Claude Code で背景のエージェントを走らせると、一覧に出る短い要約のためにトークンの 15〜20% が使われている、という測定が GitHub の gist で公開されました(ある会社が、自社の OpenTelemetry の記録を query_source ごとに集めた物です。SNS などで話題になりました)。手元の Claude Code でも同じことが起きるのかを、同じ query_source で数えて技術検証しました。
結論
- 対話の画面では、背景のエージェントの要約(query_source が
agent_summary)が推定費用の 16〜19% を占めました。2.1.312 でも 2.1.227 でも出ました。 -pで起こしたときも、-pを外して stream-json の入力で起こしたときも、要約の要求は 0 件でした。- エージェントの一覧の行を書き替える
subagentStatusLineでは止まりませんでした。背景の実行を切る公式の環境変数CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1では 0 になりましたが、代わりに背景の実行そのものが使えなくなります。 - どの値も、背景のエージェント3本・2分半ほどの小さな作業を1回ずつ回して得たものです。割合は作業の大きさや長さで変わるはずなので、目安として読んでください。
元の測定と、ここで確かめたこと
元の測定によると、Claude Code は背景のエージェントごとに約 30 秒おきに会話の全体をモデルに送り、一覧に出す「今何をしているか」の1行を作らせています。OpenTelemetry の記録を query_source ごとに集めると、それがトークンの 15〜20% になるそうです。元の測定には要約を止める非公式の仕掛けも添えて配られていますが、作者自身が利用規約とぶつかるかもしれないと書いているので、私たちは使っていません。
私たちは元の測定と同じ数え方で、Claude Code の起こし方を6通りに変えて回しました。見たのは、要約が出るか、出るならどれくらいの割合か、公式の設定で止められるか、の3点です。
試した環境
- Mac
- Claude Code 2.1.312(VS Code の拡張に入っている本体を直に起こしました)と 2.1.227
- モデルは既定の Opus(集計に出た名前は、2.1.312 で
claude-opus-5-5、2.1.227 でclaude-opus-5) - サブスクリプションのログインで動かし、その枠の中で測りました。起こした Claude Code には API のキーを渡していません(起動時の apiKeySource は none)。従量課金になっていないかの確かめ方は、ヘッドレスの Claude Code が意図せず従量課金で走っていないかは rate_limit_event で確かめるに書きました。
- 費用は、Claude Code がテレメトリに載せる推定費用(
cost_usd)です。Claude Code の見積もりで、請求の額ではありません。6回を足すと約 $11 でした。
測り方
テレメトリを手元の受け口に送る
Claude Code は、公式の設定でテレメトリを OpenTelemetry の形で出せます。ログを OTLP/HTTP の JSON で、手元に立てた受け口へ送りました。受け口は 127.0.0.1:4318 で POST を受け、中身を1行ずつファイルに書き足すだけの、20 行ほどの Python のスクリプトです。どの回も、次の形で起こしました。
env -u ANTHROPIC_API_KEY -u ANTHROPIC_AUTH_TOKEN -u CLAUDECODE -u CLAUDE_CODE_ENTRYPOINT \
CLAUDE_CODE_ENABLE_TELEMETRY=1 OTEL_METRICS_EXPORTER=none OTEL_LOGS_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/json \
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://127.0.0.1:4318/v1/logs \
OTEL_LOGS_EXPORT_INTERVAL=2000 \
claude <引数>
集計では、ログのうち event.name が api_request の物(公式の文書でいう claude_code.api_request)を拾い、query_source とモデルの組ごとに足し上げました。足したのは、要求の数、トークン(入力・出力・キャッシュの読みと書き)、cost_usd です。query_source に repl_main_thread や compact、サブエージェントの名前などが入ることは、公式の文書で確かめました。
まず -p で1行だけ送り、受け口にログが届くことを確かめました。下は、そのとき受けたログの集計です。
$ claude -p "Reply with the single word: ok" --output-format stream-json --verbose
query_source model req cost$
sdk claude-opus-5-5 1 0.0902
generate_session_title claude-haiku-5-5 1 0.0001
-p の本体の要求は sdk、会話の題を作る要求は Haiku の generate_session_title として出ます。この欄を見れば、どの部分が出した要求かを分けられます。
作業
作業の中身は、背景のエージェント3本にそれぞれ「sleep 20 を走らせてから 10KB のファイルを読む」を5回くり返させることです。使ってよい道具は --allowedTools "Agent" "Task" "Read" "Bash(sleep 20)" に絞りました。1回は2分半ほどで終わります。渡した指示は次のとおりです。
This is a measurement run. Do exactly this and nothing else.
In ONE message, use the Agent tool three times to start three agents in the background (run_in_background: true). Give each agent these instructions:
"Repeat the following for N = 1, 2, 3, 4, 5, one step at a time: run the Bash command `sleep 20`, then read the file ../data/N.txt with the Read tool. After the fifth file, reply with one line: the number of lines you read in total."
Do not do the work yourself. After starting them, wait until all three agents have reported back. Then reply with the single line: all done
対話の画面は疑似端末で起こし、「all done」が出たら閉じました。起こすと最初にフォルダを信頼するかの確認が出ます。既定の選び肢は「No, exit」なので、Enter だけを送るとそこで終わってしまいます。下の矢印で「Yes, I trust this folder」に移してから Enter を送りました。また、画面の文字はカーソルの移動で空白が詰まり、「alldone」のように出ます。そのため、空白があってもなくても見つかるように探しました。
結果:要約が出たのは対話の画面だけ
同じ作業を6通りの形で1回ずつ回した結果です。
| 形 | 版 | agent_summary の要求 | 推定費用のうち要約 | 全体の推定費用 |
|---|---|---|---|---|
| 対話の画面 | 2.1.312 | 12 件 | 18.5%($0.366) | $1.98 |
| 対話の画面 | 2.1.227 | 12 件 | 17.0%($0.529) | $3.11 |
| 対話の画面 + subagentStatusLine で一覧の行を書き替え | 2.1.312 | 11 件 | 15.8%($0.309) | $1.96 |
| 対話の画面 + CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 | 2.1.312 | 0 件 | 0% | $1.63 |
| -p | 2.1.312 | 0 件 | 0% | $1.04 |
| -p を外して stream-json の入力 | 2.1.312 | 0 件 | 0% | $1.25 |
背景の実行を切らなかった対話の画面の3回では、要約が推定費用の 15.8〜18.5% を占めました。元の測定の 15〜20% と同じ水準です。ただし、ここでの割合はトークンの数ではなく、推定費用に占める割合です。対話の画面では要約のほかに、次の入力の候補を作る要求(prompt_suggestion)も 2.0〜3.5% ありました(背景の実行を切った回では 0.8%)。
全体の推定費用は、形ごとにばらつきがあります。たとえば 2.1.312 の -p と対話の画面とでは $0.94 の差があり、要約の分($0.366)より大きくなっています。どの形も1回ずつの値で、全体の額の差は要約だけでは説明できません。
要約は約 30 秒おきに、会話の全体を送って作られる
対話の画面の2回について、agent_summary の要求が出た時刻と大きさを調べました。動きをまとめると、次の図のようになります。
2.1.312 の回では、要約の要求が 39・71・104・136 秒あたりに3件ずつ出ました。背景のエージェント3本ぶんがほぼ同時に、約 31 秒おきに出ていたことになります。2.1.227 の回も、約 28〜31 秒おきに同じ形で出ました。
1回に送る量は、そのエージェントの会話の全体でした。2.1.312 では、会話が伸びるにつれて 35,494 トークンから 58,328 トークンまで増え、平均は 49,448 トークンでした(入力・キャッシュの読み・キャッシュの書きの和)。それに対して、返ってくるのは 12〜15 トークンほどです。送る量の約 9 割はキャッシュの読みでした。2.1.227 では、送る量が 24,239 から 47,524 トークン(平均 39,130 トークン)、返りが 10〜15 トークンでした。
2.1.227 でも出た
要約が入る前の版と比べるつもりで 2.1.227 も回しましたが、こちらでも要約の要求が 12 件出て、推定費用の 17.0% を占めました。元の測定では 2.1.232 から既定で入ったとされており、手元の結果とは食い違います。手元の設定に要約を入れるような項目が無いことは、設定の項目名で確かめました。2.1.227 より前の版は試していません。
-p と stream-json の入力では出なかった
-p で起こした形でも、-p を外して stream-json の入力で起こした形でも、agent_summary は 0 件でした。本体の要求の query_source は、どちらも sdk です。背景のエージェント自体は同じように動いていて、agent:builtin:general-purpose の要求は -p で 32 件、stream-json の入力で 35 件でした。対話の画面(33 件)とほぼ同じです。
stream-json の入力の形では、ユーザの発言を1つ送り、「all done」の result が来たところで stdin を閉じました。この起こし方は、claude -p では --chrome が無視される:-p を外して stream-json の入力で起こし、ブラウザとフックの関門を両立するで使ったものです。

止めるには:表示を替えても止まらず、背景の実行を切ると 0
subagentStatusLine では止まらない
subagentStatusLine は、エージェントの一覧の行を自分のコマンドで作る公式の設定です。公式の文書には、行の label は「Claude Code が要約を持っているときはその要約」と書かれています。そこで、行を説明(description)とトークン数だけにするコマンドを用意しました。設定のファイルは変えず、--settings でその回にだけ渡しています。
claude --settings '{"subagentStatusLine": {"type": "command", "command": "<下のスクリプト>"}}' <ほかの引数>
#!/usr/bin/env python3
import json, sys
# 一覧の各行を、説明とトークン数だけにする(モデルが書いた label は使わない)
d = json.load(sys.stdin)
for t in d.get("tasks", []):
print(json.dumps({"id": t["id"], "content": f"{t.get('description', '')} · {t.get('tokenCount', 0)} tokens"}))
表示を自分のコマンドに替えても、agent_summary の要求は 11 件出て、推定費用の 15.8% を占めました。一覧の行に要約を使わないようにしても、要約の要求そのものは止まりません。
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 で 0 になった
次に、公式の環境変数 CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 を付けて対話の画面で回しました。背景で動かす指定そのものを無くす環境変数です。この回では agent_summary が 0 件になりました。エージェント3本は手前で並んで動き、同じ作業が2分半ほどで終わりました。
その代わり、公式の文書の説明では、背景のエージェント・Ctrl+B・背景のシェルが使えなくなります。要約だけを止めたくても、背景の実行ごと手放すことになります。
要約だけを止める項目は見つけられなかった
公式の文書のうち、設定・環境変数・ステータスラインの頁を読んだ範囲では、要約だけを止める項目は見当たりませんでした。ただ、文書は長く、全部は読み切れていません。
手元で確かめるなら
- 上の環境変数でログを受け、
claude_code.api_requestをquery_sourceごとに数えると、要約の分がagent_summaryの行として見えます。 - 対話の画面で背景のエージェントを多く使うなら、この分が上乗せされると見込んでおくとよさそうです。
-pで起こした形と、stream-json の入力で起こした形では、今回は出ませんでした。 - 対話の画面で止めたいなら
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1を使います。背景の実行が使えなくなるのと引き換えです。subagentStatusLineで表示を替えるだけでは止まりません。
確かめていないこと
- どの形も1回ずつしか回していません。割合はエージェントの数・会話の長さ・走る時間で変わるはずですが、長く走る作業での割合は測っていません。
- 今回、要約に使われたモデルはエージェントと同じ Opus でした。別のモデルにしたときにどうなるかは見ていません。
- 2.1.227 より前の版で要約が出るかどうか。
- Windows・Linux での振る舞い。試したのは Mac だけです。
- 対話の画面で、背景のエージェントを使わずに手前のサブエージェントだけで進める作業なら、要約が出ないのかどうか。今回試したのは、背景の実行を切った1回だけです。
おわりに
背景のエージェント3本・2分半ほどの小さな作業でも、対話の画面では推定費用の 16〜19% が要約に回りました。気になる場合は、まず手元のテレメトリで agent_summary の行を数えてみてください。
※ この記事に書いた Claude Code の振る舞い・設定・環境変数・テレメトリの項目は執筆時点の情報で、いまは変わっている可能性があります。


