技術 約9分で読めます

CLAUDE.mdが肥大化して困ってる人のためのトークン管理ガイド

「CLAUDE.mdは簡潔に。60行が理想」

理論記事はそう言う。でも実際にプロジェクトを進めると膨らむ。ガードレールを足す。エラーパターンを追記する。気づいたら300行超えてる。

「小さくしろ」と言われても、必要な情報は必要だ。

結局、CLAUDE.mdの長さだけを気にしても意味がない。問題の本質はトークン管理だ。

200Kのコンテキストウィンドウ。でもシステムプロンプトで1/3消費。会話が進めば圧縮が走り、重要な情報が消える。

この記事では「トークンをどう抑えるか」を軸に、Claude Codeの各機能を整理する。CLAUDE.mdを小さく保つのは手段の一つに過ぎない。

前提:なぜエージェントは長期タスクで失敗するのか

LLMはステートレス。毎セッション、記憶なしで開始する。

これが全ての問題の根源であり、典型的な失敗パターンを生む:

  • 一度に全部作ろうとする → コンテキスト枯渇で未完成のまま終わる
  • 途中で「完了」と言い出す → 部分的成功で満足してしまう
  • セッション跨ぎで迷子 → 前回の作業を忘れて同じことを繰り返す
  • テスト通ったと言うがモックだけ → 本番環境で動かない

これらは全て「コンテキストの限界」と「状態の引き継ぎ失敗」に起因する。

トークン管理:すべての基盤

まずコンテキスト消費の現実を把握する:

消費源目安
Claude Codeシステムプロンプト約50指示分(容量の1/3)
CLAUDE.md初期状態で約20%消費
ツール定義50ツール ≈ 10-20Kトークン
会話履歴蓄積して圧縮トリガー

200Kあっても、実質的に使えるのは半分程度。ここからさらに会話が進むと圧縮が走る。

4層戦略

トークンを抑えるには4つのレイヤーで対策する:

Layer 1: 静的削減(事前に減らす)

  • CLAUDE.md簡潔化(60行目標、現実的には300行以下)
  • ポインタ活用(コード埋め込みではなく file:line 参照)
  • 30%ルール:30%以上のエンジニアが使う情報のみ記載(※個人開発だと全部自分が使う情報なので、ここが肥大化の原因になりがち)

Layer 2: 遅延読み込み(必要時だけ)

  • スキル:呼ばれるまでコンテキスト消費しない
  • Tool Search:defer_loading でツール定義を遅延
  • 詳細ドキュメントは別ファイル参照

Layer 3: 状態の外部化(コンテキスト外に逃がす)

  • progress.txt:進捗をファイルに書き出し
  • git log:履歴はgitに任せる
  • features.json:完了状態を外部管理

書き出しのタイミングは2つ:

  1. 圧縮が入りそうなとき:その前に書き出させる
  2. 1タスク完了しないとき:途中でも進捗を書き出させる

書き出す内容はそこそこ詳細でいい。「全知識の中で、次回セッションで絶対に調査が入るもの」を入れておく感覚。

Layer 4: セッション管理(溢れる前にリセット)

  • /clear + /catchup:クリーンな状態から再開
  • /compact は不透明で不安定(避けるべき)
  • Document & Clear:複雑タスクは .md に保存してから再開

準備フェーズ:エージェントが迷わない環境を作る

長期タスクを成功させるには、以下のファイル群を用意する:

ファイル役割ポイント
CLAUDE.mdガードレール簡潔に、否定文+代替案(Never X, prefer Y)
features.json機能リスト完了条件を明確化、passes: true/false
init.sh環境起動Docker起動含む、毎セッション同じ状態から開始
progress.txt進捗ログセッション間の引き継ぎ

CLAUDE.md執筆の4ルール

  1. ガードレール優先:マニュアルではなく「Claudeが誤る箇所」を中心に書く
  2. @ファイル記法を避ける:埋め込みはコンテキスト肥大化の原因
  3. 否定文だけで終わらない:「Never X」ではなく「Never X, prefer Y」と代替案を示す
  4. 強制関数として使う:複雑なCLIコマンドはbashラッパーを作り、CLAUDE.mdを簡潔に保つ

features.json の例

{
  "features": [
    {
      "category": "functional",
      "description": "ユーザー登録フォームの実装",
      "steps": ["フォームUI作成", "バリデーション追加", "API連携"],
      "passes": false
    },
    {
      "category": "functional",
      "description": "ログイン機能の実装",
      "steps": ["認証ロジック", "セッション管理", "リダイレクト"],
      "passes": false
    }
  ]
}

実行フェーズ:二段階ハーネス設計

Anthropic公式が推奨する設計パターン:

初期化エージェント(最初のセッション)
  ├── init.sh 作成
  ├── features.json 作成
  ├── progress.txt 初期化
  └── 初期gitコミット

コーディングエージェント(後続セッション)
  ├── 1機能ずつ実装
  ├── 各機能完了時にgitコミット
  ├── 進捗ファイル更新
  └── テスト検証してから完了マーク

セッション開始の標準手順

毎セッション、以下の手順で状態を把握させる:

  1. pwd で作業ディレクトリ確認
  2. git log + progress.txt で最近の作業把握
  3. features.json から次の目標選定
  4. init.sh で開発サーバー起動

これにより「前回どこまでやったか」を毎回確実に引き継げる。

並列実行と結果統合

サブエージェントを並列で走らせると処理時間を短縮できる。ただし結果統合のパターンを理解していないと混乱する。

Master-Clone アーキテクチャ

メイン(フルコンテキスト)

    ├─→ Clone A:「○○だけ調べて結果を3行で返せ」
    ├─→ Clone B:「△△だけ調べて結果を3行で返せ」
    └─→ Clone C:「□□だけ調べて結果を3行で返せ」

ポイント:

  • サブエージェントにはタスク特化の最小指示だけ渡す
  • 結果は圧縮して返させる(トークン節約)
  • メインが統合判断(フルコンテキストで)

専門サブエージェントの落とし穴

事前に専門化したサブエージェントを定義するアプローチには問題がある:

  • コンテキスト隔離:専門化したサブエージェントは全体像を失い、結果が噛み合わない
  • ワークフロー硬直化:人間が委譲方法を決めると、エージェント自身の最適化を阻害

推奨は「Master-Clone」方式。メインエージェントに全コンテキストを与え、必要に応じて同じ能力を持つクローンを起動させる。

知識読み込みの使い分け

エージェントに知識を渡す方法は複数ある。それぞれトークン消費が異なる:

方式トークン消費用途
CLAUDE.md毎回消費全セッション共通のガードレール
スキル呼ばれた時だけ特定タスク用の知識
MCPツール定義が常時消費認証・ネットワークが必要な操作のみ
別ファイル参照Readで読んだ時だけ詳細ドキュメント
Tool Search検索時に必要分だけ大量ツール(50+)の管理

MCPの新しい役割

MCPを「API鏡像」(1API = 1ツール)として使うとツール数が爆発し、コンテキストを圧迫する。

推奨は「ゲートウェイ」として使うこと:

❌ 従来: 1API = 1MCPツール(ツール数爆発)

✅ 推奨: 高レベルツール3つに集約
   - download_raw_data(filters...)
   - take_sensitive_gated_action(args...)
   - execute_code_in_environment_with_state(code...)

知識を渡すだけならMCPよりスキル/別ファイル参照の方がトークン効率が良い。

スキルの注意点

  • デフォルトでブロック状態。明示的に許可が必要
  • 発動率25%問題:CLAUDE.mdで起動条件を明記すると100%になる
<!-- CLAUDE.md に追記 -->
ユーザーが「技術スタックは?」と聞いたら、
必ず tech-stack スキルを使用すること。

検証の深さ

エージェントが「できた」と言っても、どのレベルで検証したかを確認すべき。

フロントエンド検証レベル

Level 1: スクリーンショット確認(見た目OK)
Level 2: + コンソールエラーなし
Level 3: + ネットワークエラーなし
Level 4: + パフォーマンス基準クリア
Level 5: + アクセシビリティ監査パス

Playwright MCPは現状Level 1止まり(スクリーンショットのみ)。DevTools情報も取得すべき:

// コンソールログ取得
page.on('console', msg => console.log(msg.text()));

// JSエラー取得
page.on('pageerror', error => console.log(error.message));

// ネットワーク失敗
page.on('requestfailed', request =>
  console.log(request.url(), request.failure().errorText)
);

バックエンド検証レベル

Level 1: ユニットテスト(モック使用)
Level 2: + 実DB接続テスト
Level 3: + 本番同等環境での統合テスト

「テスト通った」と言われたら確認すべきこと:

  • モック/スタブで通っただけかも
  • SQLiteで通ってもMySQL/PostgreSQLで失敗する可能性
  • リポジトリ層がテストダブルになっていないか

テスト環境戦略

アプローチ1: 抽象化(ZTD等)

CTEでテーブル参照をシャドウイングし、実テーブルに触らずにSQLテストする手法。

  • 軽量で並列実行可能
  • ただしストアドプロシージャ/トリガー非対応
  • シンプルなCRUD向き

アプローチ2: 環境再現(Docker)

本番同等環境をコンテナで用意する。

  • 壊しても docker-compose down で消せる
  • 本番と同じDB方言でテスト可能
  • エージェントに権限を与えても安全

エージェント開発にはDocker推奨。失敗しても消せる、本番と同じ環境でテストできる、というメリットが大きい。

デザイン品質:AIっぽさを排除

Claude Codeにフロントエンドを作らせると、どうしても「AIっぽい」デザインになりがち。

frontend-design SKILLの思想

コーディング前に4つのコンテキストを確認させる:

  1. Purpose: 何を解決するか
  2. Tone: 美学的方向(brutally minimal / maximalist chaos / retro-futuristic 等)
  3. Constraints: 技術的制約
  4. Differentiation: 何がUNFORGETTABLEか

避けるべき「AI slop」

  • Inter, Roboto, Arial などの汎用フォント
  • 紫グラデーション on 白背景
  • 予測可能なレイアウト

重要なのは意図的な選択。大胆でも洗練でも、一貫性があればOK。

筆者のアプローチ

筆者はこれまでAtlassian Design Systemを参照して最低限整える方式でやってきた。既存のデザインシステムに乗っかれば、少なくとも破綻はしない。

Claudeのfrontend-design SKILLは今度試してみたい。「意図的な選択」を強制してくれるなら、デザインの質が上がる可能性がある。

自動化とブレーキ

ツールの自動許可は便利だが、やりすぎると止まらなくなる。

筆者のAI使い分け

前提として、筆者は以下のように使い分けている:

  • Claude Code: メイン開発。コード生成、ファイル操作、ビルドまで一貫して任せる
  • Gemini: 壁打ち・相談用。設計の方向性を議論したり、別視点が欲しいとき
  • ChatGPT: 雑談。プログラムにはほぼ使っていない
  • Manus: 以前使っていたが、手元でやった方がやりやすいので今は使っていない

この使い分けを踏まえて、以下の「止まらない問題」を読んでほしい。

自動許可の設定

// .claude/settings.json
{
  "permissions": {
    "allow": [
      "WebFetch(*)",
      "Bash(docker-compose:*)",
      "Skill(*)"
    ]
  }
}

止まらない問題

毎回「Allow?」と聞かれるのは面倒なので自動許可したくなる。だがやりすぎると止まらない。

  • Geminiは途中で「大丈夫?」と確認してくる
  • Claude Codeは黙々と実行し続ける
  • API経由で駆動させると延々と動いて怖い

対策

  • 破壊的操作(rm -rf, DROP TABLE 等)は自動許可しない
  • Hooksで特定操作をブロック
  • 定期的に /context でトークン消費を確認
  • 長時間タスクはタイムアウト設定

まとめ

Claude Codeでサービスを稼働状態まで作らせるには、CLAUDE.mdの書き方だけでなく、トークン管理全体を設計する必要がある。

  1. トークンは有限:4層戦略で消費を抑える
  2. 状態は外部化:progress.txt、features.json、gitで引き継ぐ
  3. 検証は深く:スクリーンショットだけでなくDevTools、実DBも確認
  4. 自動化にはブレーキ:止まらなくなるリスクを理解する

実践例(実際に何か作らせてみる)は別記事で。

参照元