← 用語集 dev-cycle →

11 現場の知見 — 使ってみないとわからないこと


実際にClaude Codeを使い込んで得た実践知。公式ドキュメントには書いていない「暗黙知」をまとめる。


📑 セクション一覧(目次)


A. コンテキスト経済学

トークンがどう消費されているかを理解することが、効率的な使い方の第一歩。

入力:出力 = 13:1 は正常

ChatGPT等のチャットAIでは「短い質問 → 長い回答」なので出力の方が多くなりがち。しかしClaude Codeでは逆転する。

理由: 毎ターンで「システムプロンプト + MCP定義 + メモリ + 過去の会話すべて + ツール結果」を丸ごと再送しているため。

ターン1: [システム + MCP + メモリ] = ~40K入力 → 回答 = ~1K出力
ターン5: [システム + MCP + メモリ + 過去4回] = ~60K入力 → 回答 = ~1K出力
ターン10: [システム + MCP + メモリ + 過去9回] = ~100K入力 → 回答 = ~1K出力

→ セッションが長くなるほど、1ターンあたりのコストが雪だるま式に増加。

200Kの実質使える量は〜160K

コンテキストウィンドウは最大200Kトークンだが、ユーザーが自由に使えるのは約160K

固定消費(毎ターン) 推定サイズ
MCPツール定義(6サーバー83ツール) ~21K
システムプロンプト(CLAUDE.md等) ~15K
Auto Memory(MEMORY.md + 各ファイル) ~5〜10K
その他システム指示 ~5K
合計 ~40K

→ 会話を始める前に既に20%消費済み。長いセッションではすぐに上限に近づく。

MCP定義だけで毎ターン消費

MCPツールは呼び出した時だけコストが発生するわけではない。ツールの定義(名前・説明・パラメータ)が毎ターンの入力に含まれる

/context 1回で~4Kトークン消費

コンテキスト使用量を確認する /context コマンド自身もトークンを消費する。1回約4K。多用は避け、気になった時だけ使う。

32MBバイト上限(画像が唯一の犯人)

トークンとは別に**リクエストペイロードのバイトサイズ上限(32MB)**がある。Request too large (max 32MB) が出たらこれ。

2つの上限を混同しないこと(これが核心):

上限 単位 MCP削減の効果
1M窓 トークン 効く(MCP固定費32kが長時間・複数セッションで効く)
32MB バイト 無意味(テキスト定義全部で0.3MB・物理的に届かない)

⚠️ 訂正・補足(2026-06-30): 上記「テキストだけで32MBには絶対届かない・唯一の経路は画像」は auto-compact 有効前提の記述だった。実際は環境・条件により経路が変わる:

  • auto-compact 無効(DISABLE_AUTO_COMPACT 設定環境=本環境)の場合: 履歴が圧縮されず、画像を使わなくてもツール結果(ファイルRead・コマンド出力等の巨大テキスト)の蓄積で20-30往復で32MB到達し得る。純会話テキスト(1M tok ≈ 3-4MB)では届かないが、ツール結果込みなら別。
  • auto-compact 有効の場合: 1M窓到達で圧縮されるため、純テキストでは32MB届かず画像が主因(従来記述の通り)。
  • MCP/スキル定義(0.3MB)は無罪なのは変わらない。テキスト削減(柱2-A等)は1M窓節約には効くが、32MB対策としては auto-compact 無効下の「ツール結果蓄積」に対してのみ寄与し得る。
  • 詳細・継続課題は [[2026-06-30_32MB問題の基礎知見と対策現況]](01_DECISIONS/claude-code/)を参照。

🎯 追訂正(2026-07-01)・真因確定: 上記(画像が犯人・auto-compact無効下のツール結果蓄積・proxy送信前弾き)は全て主因誤認だった。真因は glm-rate-proxy の aiohttp.web.Applicationclient_max_size 未設定(デフォルト1MB) で、画像添付リクエストが1MB超で 413弾き されていた。proxyログに413記録=proxy到達済み(「送信前弾き」は誤り)。CCは「max 32MB」と固定嘘表示(実効1MB)。「画像2枚1.3MBが通り3枚目で32MBエラー」の25倍跳びがこの乖離の証拠。対策は proxy.pycreate_app()client_max_size=32*1024*1024 追加の1行(commit 9ac5f24fd)で32MB問題は解消。デスクトップ版で出ないのはproxy非経由のため。詳細は [[2026-07-01_32MBエラー真因解明-proxy-client_max_size修正]]。 🔬 検証(2026-07-02・18枚画像積載): 18枚(base64想定41MB ≫ 32MB)でもproxy通過・413ゼロ。JSONL実測で画像はURL参照(maas-log-prodの短いURL・1行約30KB)で履歴保存されbase64では蓄積しないことが判明。→ 6/19「画像履歴累積で雪だるま式32MB到達」は過大評価。画像では32MB到達は構造的に不可能。残る到達経路は「巨大テキスト(ツール結果の蓄積)」のみ。


B. 落とし穴(ハマりポイント)

設定ファイルが2つ存在する(2ファイル問題)

~/.claude.json          ← CLI自動生成(隠れファイル)
~/.claude/settings.json ← ユーザー編集用

Claude Codeは両方をマージして読み込む。片方だけ編集してもう片方に古い設定が残っていると、変更が反映されない。

対策: MCPサーバーの追加・削除は手動編集ではなく claude mcp add/remove コマンドを使う。このコマンドは両ファイルを正しく更新する。

MCP削除が「復活」する

上記2ファイル問題が原因で、settings.json だけ編集してMCPサーバーを削除しても、~/.claude.json に定義が残っていれば次回起動時に復元される。

対策: 削除後は両ファイルを確認:

claude mcp list
cat ~/.claude.json | jq '.mcpServers | keys'
cat ~/.claude/settings.json | jq '.mcpServers | keys'

フックがツールを意図せずブロック

PreToolUseフックのスクリプトがエラー(exit code ≠ 0)を返すと、そのツールの実行がサイレントにブロックされる。エラーメッセージは表示されるが、「フックがブロックした」とは明示されないことがある。

対策: 予期せぬツールブロックが起きたら、まずPreToolUseフックのスクリプトを確認。

/clear しても MCP・メモリは残る

/clear がリセットするのは会話履歴のみ。以下は消えない:

完全リセットしたい場合は /clear → セッション再起動。

Read ツールで巨大ファイルを読むとコンテキスト爆発

1つのファイルでも数千〜数万行なら数万トークン消費。特にログファイル・JSON・生成コードに注意。

対策: offsetlimit パラメータで必要な範囲だけ読む。

セッション開始時にMCPが全ツール一括ロード

MCPツールは「必要になったら読み込む」のではなく、セッション開始時に全ツール定義を一括でロードする。これがコンテキストの固定消費の主因。


C. 効率テクニック

作業が長くなったら /compact か新セッション

セッションが長くなると過去の会話が蓄積し、1ターンあたりの入力トークンが増加し続ける。

手動 /compact を適度に使うのが、最もバランスが良い。

バックグラウンドエージェントで並列作業

Agent ツールを run_in_background: true で使うと、メインコンテキストを消費せずに独立タスクを実行できる。

メイン: ガイドを書く
  ├── BG Agent: リポジトリAを調査
  └── BG Agent: リポジトリBを調査

→ メインのコンテキストを節約しつつ、複数タスクを同時進行可能。

/model haiku で軽作業は高速化・低コスト化

単純な質問・フォーマット変換・短い修正等は、安価なモデルで十分。

/model haiku    # Haiku に切替
# ... 軽作業 ...
/model sonnet   # Sonnet に戻す

CLAUDE.md は短く保つ

CLAUDE.mdの内容は毎ターン読み込まれる。長すぎると毎回無駄にトークンを消費。


D. よくある誤解

「会話履歴がコンテキスト圧迫の主因」

半分正解・半分不正解

→ 短いセッションではMCP固定コストが目立つ。長いセッションでは会話蓄積が目立つ。

「MCPツールは呼んだ時だけコスト発生」

違う。ツール定義だけで毎ターン消費。呼び出しは追加コスト。

→ 使っていないサーバーを残しておくと、1ターンごとに無駄なトークンを消費し続ける。

「メモリは無料」

違う。MEMORY.md + 各メモリファイルが毎ターン読み込まれ、トークンを消費。

/clear = すべてリセット」

違う/clearがリセットするのは会話履歴のみ。

リセットされる 残る
会話履歴 システムプロンプト(CLAUDE.md)
MCPツール定義
Auto Memory
設定(permissions, hooks)

「コンパクション(compact)= 要約品質が高い」

注意が必要。自動コンパクションは古い会話を要約して捨てるが、詳細が失われる。重要な文脈は compact 前にメモリに保存するか、自分で要約を控えておく。


E. Cron管理の注意点

Cron は7日で自動失効する

Claude Code の CronCreate で登録したCronジョブは、durable=false の場合は7日後に自動削除されるdurable=true も実質7日が上限とされている(2026年6月時点)。

放置するとCronが静かに消える。

自己更新プロンプトは膨張バグを引き起こす

「このプロンプト全文をそのままコピーして再登録せよ」というプロンプトをCronに埋め込むと、再登録のたびにプロンプトが重複コピーされ続け、最終的に8倍以上の長さになる。

初回: "このプロンプト全文を..."(100文字)
1回目実行後: "このプロンプト全文を...このプロンプト全文を..."(200文字)
N回目実行後: N倍の長さに膨張

推奨: スクリプト方式で永続化する

Cron定義を外部スクリプトに書き出し、更新専用Cronがそれを読んで再登録する方式が安全。

構成例:

# ~/bin/renew-crons.sh
# このファイルは実行ではなく、Claudeがcatして読むための定義ファイル
#
# 1. Knowledge Lint
#    schedule: "3 3 * * 0,2,4"
#    prompt:   "bash ~/.claude/scripts/knowledge-lint/run-lint.sh && ..."
#
# 2. Cron更新タスク(このスクリプト自身)
#    schedule: "0 3 */6 * *"
#    prompt:   "bash ~/bin/renew-crons.sh を cat して全Cronを再登録せよ"

更新Cronのプロンプト(短く固定):

bash ~/bin/renew-crons.sh を cat して、記載された全Cronを
CronCreate(durable=true, recurring=true) で再登録せよ。
既存の同名Cronは削除してから登録すること。

ポイント:


F. APIスクリプト共通基盤(api_base.py)

外部API(Gemini・Last.fm等)をCLIから叩くとき、共通基盤 lib/api_base.py を経由するとプロバイダを増やすたびに同じパターンが使い回せる。2プロバイダで同一雛形が再利用可能なことを実証済み。

設計思想:CCはAPIを直接叩かない

SKILL.md → scripts/api/<provider>.py → lib/api_base.py → 統一JSON

スクリプトは統一JSONstatus/summary/full_data/error)を返し、CCはsummaryのみ受け取る。巨大なfull_data(生レスポンス)はキャッシュファイルに退避するのでトークン膨張を防げる

api_base.py の中身(4関数のみ)

関数 役割
run_api(call_fn, summary_fn, cache_key) API呼び出しをラップし全例外を統一JSONへ捕捉
make_error_result(error) 例外をエラーJSONに正規化
make_success_result(summary, full_data, cache_key) 成功JSON生成 + full_data~/tmp/api_cache/に退避
_cache_dir() キャッシュディレクトリ生成

核心は run_api の抽象:プロバイダ固有ロジックは call_fn(API呼び出し)と summary_fn(結果→成功JSON)の2関数に閉じ込め、基盤側は汎用的。

新しいAPIを追加する手順(5ステップ)

  1. キー取得 — ユーザーが ~/.secrets.env<PROVIDER>_API_KEY 追加(値は会話・ファイルに書かない
  2. TDD実装scripts/api/<provider>.py を新設。下記雛形の _call/_summarize だけ書き換える。tests/test_<provider>.py でparse系純粋関数を先にテスト
  3. スキル統合 — 呼び出し元SKILL.mdにPhase追加(🔷ユーザー確認ポイント付き)
  4. 実URL検証 — 本物の入力でE2Eを通す(モックじゃなく実API)
  5. 完了記録 — SSOT 01_DECISIONS/claude-code/ に完了ファイル。prev: で前フェーズにリンク

雛形(コピペして _call/_summarize だけ書き換え)

import json
from lib.api_base import run_api, make_success_result

def _call():
    # プロバイダ固有のAPI呼び出し(SDK / urllib)
    ...

def _summarize(result, cache_key):
    # result → summary文字列 + full_dataをmake_success_resultへ
    return make_success_result(summary=..., full_data=result, cache_key=cache_key)

if __name__ == "__main__":
    args = parse_args()
    cache_key = f"{provider}_{args.xxx}"
    print(json.dumps(run_api(_call, _summarize, cache_key), ensure_ascii=False))

現場で踏んだ罠

詳細(アーキテクチャ全体・フェーズ別成果): SSOT 01_DECISIONS/claude-code/2026-06-18_サードパーティAPI統合アーキテクチャ.md


G. コード行数の正確な計測

ポートフォリオや経歴書に「コード行数」を記載する際、自動生成ファイルを除外しないと数字が大きく狂う

必ず除外すべきディレクトリ

ディレクトリ 正体 実例
mutants/ ミューテーションテストの自動生成コピー NexusCoreで5.5万行が混入
evaluation/ 外部評価フレームワーク(evalplus等) 実コードとは別物
archive/ 廃止・旧版コード 現行プロダクトではない
.venv/ venv/ Python仮想環境 サードパーティライブラリ
node_modules/ dist/ JS依存・ビルド成果物 自分が書いたコードではない
__pycache__/ .git/ システム生成物 全て除外

異常値の見つけ方

計測後に以下を確認する:

「本当に読んで計測した」3層証明

数字の信頼性を担保するために:

  1. ランダムサンプル — 計測ファイルから3件抽出して冒頭5行を表示
  2. バイト整合性 — 最大ファイルの「バイト数÷行数」が10〜500の範囲か確認
  3. git log — 各リポジトリの最終コミット日時・総コミット数を表示

/code-metrics スキルがこれらを自動実行する。


H. 並行セッションの競合回避(active-sessionsボード)

問題:複数セッションが「共通ファイル」を逆向きに触る

通常4セッション程度を並行運用するが、トピックを分けていても境界が曖昧な「共通ファイル」を複数セッションが同時に逆向きに触り、矛盾・無効化が起きる。

共通ファイル(9種) — 複数セッションの境界をまたぐ設定・運用ファイル:

  1. ~/.claude/settings.json
  2. ~/.claude/CLAUDE.md
  3. SKILL.md群(skills/*/SKILL.md
  4. hook群(scripts/hooks/*scripts/obsidian/*
  5. 00★SYSTEM/自動化.md
  6. 00★SYSTEM/全体マップ_MOC.md
  7. 00★SYSTEM/repo-index.yaml / リポジトリ索引.md
  8. 00★SYSTEM/MCPツール使い分けガイド.md
  9. 00★SYSTEM/リンク運用方針.md

実例(同一日内で発生): check-link-policy.sh が3セッションで「修正 / 削除 / 活用」と分裂。どれか1人が作業しても別の1人が無効化する状態になった。

根本原因は 各セッションが他の並行セッションの「進行中方針」を知らないこと。git log には未commitの意図は載らない。

解決:作業宣言の共有ボード

00★SYSTEM/active-sessions.md に「いま誰がどの共通ファイルを・どうするか」を宣言する。

タイミング 担当スキル ボードへの書き込み
開始時 resume-session 自分の行を追加(触る予定ファイル・方針を宣言)
記録時 ssot-record 共通ファイルを触ったら自分の行を更新
終了時 new-session 自分の行に ✅終了(or削除)

競合発見時のフロー(共通ファイルを触る前):

運用のポイント

根本原則: 逆方向の変更は勝手にやらない。必ずユーザー判断。


💡 やさしい補足(初心者向け)

この章に書いてある「使ってみないと分からない実話」を、日常の言葉で言い直します。