Claude Codeでレガシーコードを直すときにセッショントークンを80%節約する隔離ルール
1人手で製品を作る1年目未満の開発者が巨大なレガシーコードベースにClaude Codeを導入すると、1時間も経たずにトークン予算が底をつきます。社内で質問できるシニアはおらず、基本CLIコマンドだけを覚えた状態でターミナルを開くと、クレジットカードの決済通知ばかりが届くことになります。
Claude Codeは会話の状態をサーバーに残りしません。システムプロンプト、プロジェクト設定ファイルのCLAUDE.md、累積会話履歴、ツール呼び出しの結果を毎ターンごとに単体ペイロードにまとめ、Anthropic APIに再度送信します。セッション開始直後の1〜2ターンには15,000トークン前後にとどまりますが、エージェントが探索を始めるにつれてビルド成果物や数万行に及ぶログを読み込む瞬間、ペイロードは80,000トークンまで膨れ上がります。6〜10ターンを超えると、毎ターン120,000トークンから200,000トークンが行き来します。ターンごとにコストが複利で請求される構造です。
Anthropicの公式プロンプトキャッシュ単価を見ると、原因がさらに明確になります。同じ接き頭辞コンテキストが維持されていれば、基本入力トークンと比較して10%のコストだけで済みます。一方、エージェントが数万行のコードを不規則に読み込みキャッシュ接頭辞が壊れると、5分のTTL基準で1.25倍のキャッシュ生成コストが新しく発生します。何度か検索を回すだけで、1人では負担しきれない料金が記録される理由です。
.claudeignoreは機能しない
ルートディレクトリに.claudeignoreファイルを作成して安心する開発者が多くいます。結論から言うと、Claude Codeの公式CLIエンジンにはそのような設定ファイルは存在しません。CLAUDE.mdに「ログフォルダは読み込まないこと」と記載しておく方式も、モデルが必要だと判断すれば無視してしまいます。
エージェントのファイルアクセスをエンジン段階で物理的に遮断するには、.claude/settings.jsonファイルのpermissions.deny設定を使用する必要があります。
プロジェクトルートの.claude/settings.jsonにビルド成果物とセキュリティファイルをあらかじめまとめておきます。
json { "permissions": { "deny": [ "Read(./.env*)", "Read(./secrets/**)", "Read(**/node_modules/**)", "Read(**/dist/**)", "Read(**/build/**)", "Read(**/coverage/**)", "Read(**/target/**)", "Read(**/*.log)", "Read(**/*.map)", "Read(legacy-backups/**)", "Edit(**/dist/**)", "Write(**/dist/**)" ], "ask": [ "Bash(git push *)", "Bash(npm publish)", "Bash(rm -rf *)" ], "allow": [ "Read", "Edit", "Bash(npm test)", "Bash(npm run lint)", "Bash(git status)", "Bash(git diff *)" ] } }
バックエンドロジックを修正する際にフロントエンドのコードまで収集する動作を防ぐため、ローカル専用設定である.claude/settings.local.jsonを別途用意します。
json { "permissions": { "deny": [ "Read(apps/web/**)", "Read(frontend/**)", "Read(public/**)", "Edit(apps/web/**)", "Write(apps/web/**)" ] } }
エージェントがcatやheadなどのシェルコマンドで巨大なログをターミナルに丸ごと出力する事態も防ぐ必要があります。.claude/settings.jsonにPreToolUseフックをかけ、コマンドを事前にインターセプトします。
json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "bash", "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/block-large-reads.sh"] } ] } ] } }
.claude/hooks/block-large-reads.shファイルを作成し、chmod +xで実行権限を付与します。
`bash
#!/usr/bin/env bash
PAYLOAD=(cat)COMMAND=(echo "$PAYLOAD" | jq -r '.tool_input.command // empty')
if echo "$COMMAND" | grep -Eq '(cat|head|tail|less)\s+.*(.log|.map|.lock|dist/|build/)'; then
echo "大容量ファイルの直接出力が検知されたため、実行を中断します。" >&2
exit 2
fi
exit 0
`
OSプロセスレベルでExit code 2を返すと、エージェントのファイル出力が即座に停止します。不要なファイルスキャンをブロックし、初期ターンのトークン消費量を半分以下に引き下げます。
ファイル全体の書き直しを禁止し、関数単位で渡す
1,000行を超えるレガシーファイルで変数を1つ変更するためにファイル全体を新しく書き直させると、バグが発生し、出力トークンも無駄になります。Claude Codeの内部にはファイルを上書きするWriteツールと、特定の文字列ブロックのみを置換するEditツールが分かれています。
プロジェクトルートのCLAUDE.mdに変更ルールを書き留めておく必要があります。
`markdown
Code Modification Constraints
- 絶対にファイル全体を新しく作成(Write)しないこと。
- 必ず変更が必要な最小単位のみを Edit ツール (old_string -> new_string) で変更すること。
- バグ修正時に周辺コードのフォーマットや空白を勝手に触らないこと。
- 作業完了前に git diff を確認し、意図した変更のみが反映されているか検証すること。
`
巨大なファイル全体をエージェントに渡す代わりに、対象の関数だけを抽出する方が望ましいです。ASTパーサーツールであるast-grepを使用するシェルスクリプト(extract-func.sh)です。
`bash
#!/usr/bin/env bash
TARGET_FILE=1FUNCNAME=2
if [ -z "TARGETFILE"]∣∣[−z"FUNC_NAME" ]; then
echo "使用法: ./extract-func.sh <ファイルパス> <関数名>" >&2
exit 1
fi
if command -v sg &> /dev/null; then
sg run --pattern "function FUNCNAME($$$ARGS)$$$BODY""TARGET_FILE"
else
LINE_START=(ctags−x−−c−kinds=f"TARGET_FILE" 2>/dev/null | grep -w "$FUNC_NAME" | awk '{print 3}')
if [ -n "LINE_START" ]; then
sed -n "LINESTART,((LINE_START + 100))p" "$TARGET_FILE"
else
grep -n -A 60 "function FUNCNAME""TARGET_FILE"
fi
fi
`
抽出した関数やステージングされたgit diffのみをヘッドレスモード(claude -p)で渡し、修正を要求します。
`bash
特定の関数のみを注入して修正コードを抽出
./extract-func.sh src/billing.js processRefund | claude -p "上記関数の計算エラーを修正した Edit 用の代替コードブロック(new_string)のみを出力すること。"
ステージングされた変更点のみを検証
git diff --staged src/services/OrderService.js | claude -p "この diff で発生し得る並行性の不具合や null 参照の可能性のみを指摘すること。"
`
ソースコード全体ではなく、50〜100行程度のスライスのみを入力として与えると、ターンあたりのトークン消費量を90%近く削減できます。
HANDOFF.mdでセッション状態を保存してクリアする
作業を1つのセッションで長く引き延ばす理由はありません。会話履歴が蓄積されるほど、毎ターン支払うべき基本料金が増大します。Claudeモデルは約967,000トークンに達すると会話履歴を自動的に要約する/autocompactをサポートしていますが、システムがコードを縮小する過程で重要なパラメータやエッジケースの文脈を飛ばしてしまうことがよくあります。自らコンテキストをクリアする必要があります。
ターミナルで3つの組み込みコマンドを使用して現在の状態を確認します。
/context: システムプロンプトと会話履歴が占めるメモリの割合を表示します。
/usage: セッションのトークン使用量とプラン上限の消化率を確認します。
/cost: 現在のセッションまでに累積された実際のドルコストを点検します。
トークンが100,000個を超えたり、特定の作業単位が完了したりした場合は、セッションを終了する前にClaude CodeにHANDOFF.mdの作成を指示します。
text 現在のセッションの作業状態をプロジェクトルートの HANDOFF.md に以下の形式で記録すること: Goal: 作業目標および対象モジュール Current Progress: 修正したファイルと具体的な行 What Worked: 検証が完了したロジックおよび通過したテスト What Failed: 失敗したアプローチおよび注意事項 Immediate Next Step: 次のセッション開始直後に実行すべき単一の作業
記録が完了したら、/clearコマンドでコンテキストウィンドウをクリアします。新しいセッションを開き、前のセッションの要約のみを渡します。
text HANDOFF.md ファイルを読み込み、Immediate Next Step の項目から作業を継続すること。以前に失敗したアプローチは試さないこと。
同一のエラーで3回以上空転し始めたら、直ちにEscapeキーを押して停止しなければなりません。セッション全体をクリアするのが微妙な状況であれば、/rewindで正常に動作していた直前のターンに戻ります。/rewindは確立されたシステム接頭辞プロンプトキャッシュを維持するため、追加のキャッシュ書き込みコストを支払わずに正常な分岐に復帰できます。
防御レイヤー別の制御レベル
| 防御レイヤー |
設定場所 |
制御レベル |
実測トークン削減効果 |
| ハネスファイルフィルタリング |
.claude/settings.json (permissions.deny) |
CLIエンジン強制 |
セッションあたりの初期スキャンセルトークン 50%〜80%遮断 |
| シェルコマンド防御壁 |
PreToolUse Hook (block-large-reads.sh) |
OSプロセス遮断 (Exit 2) |
ログおよびバンドルファイルの大規模出力 100%防御 |
| コンテキストスライシング |
ast-grep, git diff パイプライン |
入力範囲制限 |
ファイル分析および修正ターンあたりのトークン 90%削減 |
| セッション寿命管理 |
/context, /clear, HANDOFF.md |
手動状態永続化 |
セッション後半の累積複利トークン請求額 60%以上削減 |
.claude/settings.jsonで不要なパスを遮断し、巨大なファイルの代わりにスライスしたコードのみを渡すルールを守ってこそ、1人開発環境でClaude Codeを実用的な開発ツールとして運用できます。