◉CLAUDE LABEN
●2.1.296 — サブエージェントごとに autoCompactWindow を指定でき、ワークフロー用のモデルも環境変数で固定できます●HAIKU 5.5 — 2.1.293(10/07)から claude-haiku-5-5 が Anthropic API の既定の Haiku モデルになりました●SONNET 4.5 — Claude API での提供終了は 11/30、残り47日。移行先は Sonnet 5.5●Q&A — Mod が「エラーなしで何も描かれない」ときに見る3か所が共有されています●AGENTS.MD — Codex と Claude Code を同じフォルダで使うとき、AGENTS.md と CLAUDE.md の入口をどう分けるかの整理が出ています●NEW — 「cd して git add して commit」の承認が毎回出るのは、設定の抜けではなく仕様でした●2.1.296 — サブエージェントごとに autoCompactWindow を指定でき、ワークフロー用のモデルも環境変数で固定できます●HAIKU 5.5 — 2.1.293(10/07)から claude-haiku-5-5 が Anthropic API の既定の Haiku モデルになりました●SONNET 4.5 — Claude API での提供終了は 11/30、残り47日。移行先は Sonnet 5.5●Q&A — Mod が「エラーなしで何も描かれない」ときに見る3か所が共有されています●AGENTS.MD — Codex と Claude Code を同じフォルダで使うとき、AGENTS.md と CLAUDE.md の入口をどう分けるかの整理が出ています●NEW — 「cd して git add して commit」の承認が毎回出るのは、設定の抜けではなく仕様でした
記事一覧/Claude Code
⟐ Claude Code/2026-06-16中級

課金変更2日目 — headless 工程の実コストが事前見積もりからどれだけズレたか

6月15日の課金変更で headless 実行が月次クレジットに切り替わりました。発効2日目に工程別の実コストを集計したところ、ある工程だけ見積もりの約2倍。計測の仕組みと、1工程をサブスク枠へ戻した判断を記録します。

Claude Code262headless13コスト管理14自動化87個人開発130

6月15日の朝、いつものようにパイプラインのログを開いて、最初に見たのはクレジットの残量でした。

前日に課金変更が発効し、headless の claude -p 実行・Agent SDK・GitHub Actions が、サブスクリプションの上限とは別枠の月次クレジットへ移りました。繰り越しはありません。前夜まで、私は自分の見積もりを信じていました。工程ごとに「だいたいこのくらい」と当たりをつけ、月の枠に収まると踏んでいたのです。

ところが2日目の朝に集計してみると、ある1工程だけが、見積もりのほぼ2倍を消費していました。

数字そのものより、なぜそこを読み違えたのかが気になりました。今日はその計測の仕組みと、結果として1工程だけサブスク枠へ戻した判断を、淡々と書き残しておきます。同じように自動運用のコストを見直している個人開発者の方の、手がかりになれば幸いです。

まず「工程」を分けないと、何も測れません

私は Dolice Labs の4サイトを自動運用しています。記事生成は1本のスクリプトに見えますが、内側はいくつかの独立した工程に分かれています。

  • 題材選定(参照データを読み、既存記事との重複を避けてテーマを決める)
  • 本文生成(日本語と英語の2本)
  • 品質ゲート(テンプレ検出・整合性チェック)
  • push と後処理(commit、ログ記録)

課金変更の前は、これらをまとめて「1本いくら」と考えていました。サブスク枠の中で動いている限り、内訳を知る必要がなかったからです。

別枠の月次クレジットに変わると、話が変わります。どの工程が重いかを知らないまま枠を使うのは、電気代の総額だけ見て、どの家電が食っているかを把握していないのと同じです。まず工程を分けて、それぞれにクレジットを当てる必要がありました。

工程別にコストを当てる、小さなラッパー

大掛かりな計測基盤は作りませんでした。claude -p を呼ぶ箇所を、薄いラッパーで包んだだけです。各呼び出しの直前に工程名を渡し、終了時に所要時間と概算コストを1行で追記します。

#!/usr/bin/env bash
# run_stage.sh — claude -p を工程名つきで実行し、消費を1行ログに残す
# 使い方: ./run_stage.sh "topic-select" "プロンプト文字列"
set -euo pipefail
 
STAGE="$1"
PROMPT="$2"
LOG="${HOME}/pipeline_cost/$(TZ=Asia/Tokyo date +%Y-%m-%d).tsv"
mkdir -p "$(dirname "$LOG")"
 
start=$(date +%s)
 
# --output-format json で usage を受け取り、人間向けの結果と分離する
result=$(claude -p "$PROMPT" --output-format json)
 
end=$(date +%s)
elapsed=$((end - start))
 
# usage からトークン数を取り出す(フィールド名は環境で確認しておく)
in_tok=$(echo "$result"  | jq -r '.usage.input_tokens  // 0')
out_tok=$(echo "$result" | jq -r '.usage.output_tokens // 0')
cache_read=$(echo "$result" | jq -r '.usage.cache_read_input_tokens // 0')
 
printf '%s\t%s\t%ss\t%s\t%s\t%s\n' \
  "$(TZ=Asia/Tokyo date +%H:%M:%S)" "$STAGE" "$elapsed" \
  "$in_tok" "$out_tok" "$cache_read" >> "$LOG"
 
# 本来の結果(result フィールド)だけを後段へ渡す
echo "$result" | jq -r '.result'

ポイントは2つあります。

1つは --output-format json を使い、生成結果と usage を分けて取り出すことです。これがないと、トークン数を後から推定するしかなくなります。

もう1つは cache_read_input_tokens を別カラムで残すことです。プロンプトキャッシュからの読み出しは課金単価が大きく違うため、入力トークンと混ぜて記録すると、後で原因を切り分けられなくなります。私が見積もりを外したのは、まさにこのキャッシュ読み出しの扱いでした。

計測そのものにも、小さな落とし穴がありました。--output-format json の usage は、工程によっては期待したフィールドが空で返ることがあります。私は最初、空の値を0として黙って足していたため、初日の集計が実態より軽く出ていました。jq -r '.usage // empty' で usage の有無を先に確かめ、欠けている行はログに「usage欠落」と明示して、平均値で補わずに別扱いにしています。総額を信じる前に、まず計測の穴を疑う——回り道に見えて、これが一番の近道でした。

2日分のログを工程別に畳む

1日分のログがたまったら、工程ごとに合計します。集計は短い Python で十分でした。

# aggregate_cost.py — 工程別にトークンを合計し、概算コストを出す
import csv, sys
from collections import defaultdict
 
# 単価は自分のプランの料金表で必ず確認すること(ここは概算用の例)
PRICE_IN  = 3.00 / 1_000_000   # 入力 100万トークンあたり
PRICE_OUT = 15.00 / 1_000_000  # 出力 100万トークンあたり
PRICE_CACHE_READ = 0.30 / 1_000_000  # キャッシュ読み出しは桁が違う
 
agg = defaultdict(lambda: {"in": 0, "out": 0, "cache": 0, "runs": 0})
 
for path in sys.argv[1:]:
    with open(path) as f:
        for row in csv.reader(f, delimiter="\t"):
            _, stage, _elapsed, in_tok, out_tok, cache = row
            a = agg[stage]
            a["in"]    += int(in_tok)
            a["out"]   += int(out_tok)
            a["cache"] += int(cache)
            a["runs"]  += 1
 
print(f"{'stage':24} {'runs':>5} {'in':>10} {'out':>10} {'cache':>12} {'$est':>8}")
for stage, a in sorted(agg.items(), key=lambda kv: -(kv[1]['in'])):
    cost = a["in"]*PRICE_IN + a["out"]*PRICE_OUT + a["cache"]*PRICE_CACHE_READ
    print(f"{stage:24} {a['runs']:5d} {a['in']:10d} {a['out']:10d} {a['cache']:12d} {cost:8.2f}")

2日分のTSVを渡すと、工程ごとの実消費が一覧になります。これを、課金変更の前夜に立てておいた見積もりと並べて眺めました。

ズレが一番大きかったのは「題材選定」でした

意外だったのは、最も重かったのが本文生成ではなく、題材選定だったことです。

本文生成は出力トークンが多いぶん高くつく、と予想していました。実際それは見積もりどおりでした。読み違えていたのは入力側です。

題材選定の工程では、参照データ・既存記事のタイトル一覧・読者ペルソナを毎回読み込みます。私はこれを「キャッシュが効くから安い」と決めつけていました。ところがログを見ると、キャッシュが効いていたのは連続実行のときだけでした。4サイトを時間帯で分散させている都合上、同じ参照データを読む呼び出しの間隔が空き、キャッシュの有効期間を越えて毎回フルの入力課金が発生していたのです。

つまり、コストを押し上げていたのは出力の量ではなく、分散スケジュールとキャッシュ寿命のすれ違いでした。これは総額だけ見ていたら一生気づけなかった種類のズレです。AdMob の収益を国別・時間帯別に分解して初めてボトルネックが見えるのと、感覚としてはよく似ています。

1工程だけ、サブスク枠へ戻しました

対処は単純です。題材選定だけを headless から外し、通常のサブスクリプション枠(対話セッション内)へ戻しました。

判断の基準は、月次クレジットの解説を読んで自分なりに整理した、次の問いです。

  • 完全無人で回す必要があるか → はい、なら headless(月次クレジット)に残す
  • 入力が重く、キャッシュが効きにくいか → はい、ならサブスク枠へ戻す候補
  • 出力が主役で、無人実行の価値が高いか → はい、なら headless に残す
  • 自分が朝にまとめて確認しながら回せるか → はい、ならサブスク枠で十分

題材選定は「入力が重く、キャッシュが効きにくい」「朝にまとめて確認できる」の2つに当てはまりました。逆に本文生成と品質ゲートは、深夜帯に無人で完結させる価値が大きいため、headless に残しています。

ここで大事なのは、全部を一気に動かさないことだと考えています。1工程だけ移して、翌日のログでまた確かめる。個人開発の運用変更は、この「1つだけ変えて測る」を守るほど、後で原因を追いやすくなります。

これから数日で確かめること

2日分の実測は、あくまで初期値です。月初は枠が潤沢に見えるので、バーンレートが正しいかどうかは、もう数日ぶんのログがたまらないと判断できません。

これから確かめるのは3つです。題材選定をサブスク枠へ戻したあと、headless 側のクレジット消費が見積もりの線に乗るか。キャッシュ寿命を意識してスケジュールを少し寄せたとき、入力課金がどれだけ下がるか。そして、Anthropic 側のダッシュボードに出る消費と、自分のローカル集計がどこまで一致するか。

数字が出そろったら、また工程表を引き直すつもりです。総額ではなく工程で見る——課金体系が変わった今、この一手間が運用の効きどころになる、というのが2日目の実感です。

最後までお読みいただき、ありがとうございました。同じく月次クレジットの設計に頭を悩ませている方の、小さな足場になればうれしく思います。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-09-20
Pro を払っているのに Console に請求が立っていたとき、私が最初に見た一行
サブスクリプションと API の従量は別会計で、Claude Code はそのどちらでも動きます。どちらが選ばれているかを決めるのは優先順位で、ログインはその最下段です。status の読み方と、無人実行だけが別の答えを返す理由を書き残します。
⟐ Claude Code2026-08-25
空白ひとつで、80件の検査が0件になる — 一括処理を任せる前に置くガード
空白を含むフォルダ名の下で走らせた検査ループが、80件のうち1件も開いていませんでした。断片が実在パスに化ける仕組みを実測で切り分け、削除を伴うバッチに置く件数アサーションまで書き残します。
⟐ Claude Code2026-05-18
Play Store 段階公開を Claude Code で自動監視する — v2.1.0 クラッシュ対応から学んだリリース戦略
Android アプリの段階公開(5%→100%)を Claude Code で自動監視するシステムの実装記録。Beautiful HD Wallpapers v2.1.0 での RecyclerView クラッシュ対応を例に、Crash-free Users 99.7% 基準の自動判定・ロールバック判断ロジックを詳解します。