Claude Codeが期待通りに動かない10シナリオ — 根本原因と回避レシピ
Claude Codeが「急にバカになった」「指示通りに動かない」と感じる代表10シナリオを、根本原因と具体的な回避策(設定 / Hook / Skill / 運用ルール)とセットで整理します。
要点
Claude Codeを本格運用していると、ほぼ全員が遭遇する挙動の落とし穴があります。「急にバカになった」「指示と違うことをした」と感じる現象の多くは、Claudeのモデル性能ではなくコンテキスト構造・ツール使用パターン・運用設計の問題に起因します。
10シナリオを根本原因 → 具体的な回避策のセットで順に見ていきます。各シナリオには再現条件 / 症状 / 根本原因 / 対策の4つを揃えます。トラブルシューティング記事として参照する形でも使えるよう構造化しました。
落とし穴の早見表(全10シナリオ)
| # | シナリオ | 主な対策 |
|---|---|---|
| 1 | 長セッションで急に文脈を見失う | コンテキスト圧縮の前に手動セーブ、/clear を計画的に使う |
| 2 | 大きなファイルをReadしてから挙動が劣化 | offset / limitを必ず指定、サブエージェントに分離 |
| 3 | 並列タスクで同じファイルが上書き衝突 | 担当ファイルを事前にプロンプトで分割明示 |
| 4 | 危険コマンドが実行されてしまう | PreToolUse Hook + skip-permissionを分離 |
| 5 | Subagentが要約しすぎて重要情報を捨てる | 結果テンプレを指定 + 中間ログをstrderで保持 |
| 6 | Planが立派でも実装で違うことをする | PlanをReadで確認 → 別Taskで実装 |
| 7 | Editが失敗し続ける(old_string 不一致) | Readを先にして全文をcontextへ |
| 8 | Hookが無限ループする / 応答が極端に遅い | matcherを絞る、stderrに流す、重い処理を別経路へ |
| 9 | Bashの長時間プロセスでセッションが固まる | run_in_background を使う、Monitorで観測 |
| 10 | gitのdestructive操作で履歴を壊す | force push / reset --hardを運用ルールで禁止 |
以下、各シナリオを詳細に解説します。
シナリオ1: 長セッションで急に文脈を見失う
再現条件
3時間以上の長セッション。複数の調査 → 実装 → レビューを連鎖させていて、context残量が30% を切ったあたり。
症状
直前まで覚えていたファイルパスを忘れる、別のディレクトリのコードを混ぜる、変数名がブレる。
根本原因
Claude Codeはcontextが逼迫すると 自動圧縮(auto-compacting)を走らせます。圧縮は会話を要約して残すため、具体的なコード片やパス情報が失われることがあります。
対策
/clearを計画的に使う: 大きなフェーズの切れ目で明示的にcontextをクリーンにする(直前の変更内容はgit logやTODOファイルに残しておく)- PreCompact Hookでsnapshot保存: Hooks実例カタログのレシピ8を参照
- 重い調査はサブエージェントに移譲: Subagents並列パターンのパターン2(コンテキスト隔離)を活用
- 長期記憶は
CLAUDE.md/ Skillsへ: 会話contextは揮発するが、Markdownファイルは残る
シナリオ2: 大きなファイルをReadしてから挙動が劣化
再現条件
5,000行を超えるファイルを Read ツールで一度に読み込んだ後。
症状
その後の応答が遅くなる、関係ない部分を引用する、別ファイルの編集ミスが増える。
根本原因
Read は読み込んだ内容をそのままcontextに積みます。10,000行のソースを丸ごと読むとcontext windowの半分以上を消費し、以降の作業余地が激減します。
対策
offset/limitを必ず指定: 「最初の200行」「特定関数の前後」だけ取るGrepで先に該当行を絞る: 全ファイル読みではなく、該当部分だけRead- 大ファイル調査は
Exploreサブエージェントに: 結果は要約だけが返る
シナリオ3: 並列タスクで同じファイルが上書き衝突
再現条件
2〜3体のサブエージェントを並列起動して、同じファイルを編集させた場合。
症状
最後に書いたエージェントの内容だけが残り、他の変更が消える。
根本原因
サブエージェントは互いの状態を知りません。同じファイルへの書き込みは後勝ちで上書きされます。
対策
- 担当ファイルを事前にプロンプトで明示: 「Agent Aは
lib/foo.tsのみ、Agent Bはlib/bar.tsのみ」と切り分ける - 書き込みが衝突する作業は順次実行: 1体目を待ってから2体目を起動
- 読み取り専用なら
Exploreを並列起動: ファイル衝突は起きない
シナリオ4: 危険コマンドが実行されてしまう
再現条件
--dangerously-skip-permissions 等でauto-permissionを効かせた状態で、誤って rm -rf 系のコマンドが入ってしまう。
症状
開発環境のファイル削除、本番接続のDBに対するDROP、gitのforce push等で意図しない破壊的操作が走る。
根本原因
Auto-permissionは便利な反面、Claudeが判断ミスをした際の最後の砦が無くなります。
対策
PreToolUseHookで危険コマンドをブラックリスト: Hooks実例カタログレシピ3- 本番接続のシェルではauto-permissionを切る: 確認画面を必ず挟む
- コンテナ / sandboxで動かす: ローカルではなくDocker内でClaude Codeを走らせ、ホストへの影響を遮断する
シナリオ5: Subagentが要約しすぎて重要情報を捨てる
再現条件
Task ツールでサブエージェントに調査を任せたが、返ってきた要約に重要な数値 / ファイルパスが落ちている。
症状
「で、具体的にどのファイルが該当したの?」と聞き返すことになり、二度手間。
根本原因
サブエージェントは何を要約するか自己判断します。プロンプトで成果物の構造を指定しないと、エージェントの判断に任せた要約になります。
対策
- 成果物テンプレートをプロンプトに明示: 「次のMarkdown表形式で返す: ファイルパス | 該当行 | 内容」
- 「以下を必ず含める」リストを書く: 数値 / 固有名詞 / コードスニペット等
- 重要detailは別に取得し直す: 要約 + 元ファイル参照のハイブリッド運用
シナリオ6: Planが立派でも実装で違うことをする
再現条件
Plan モードで詳細な計画を立てさせ、その後 general-purpose で実装させたが、実装が計画と違う方向に行く。
症状
「計画ではこのファイルを編集する予定だったのに、別のファイルが触られている」「変数名が計画と違う」。
根本原因
Planセッションと実装セッションは別のcontextで動きます。計画書をMarkdownでメインに返してもらい、実装セッションがそれを改めて読み直さないと、計画は実装に反映されません。
対策
- Planの出力をファイル化: 実装セッションに「
docs/plan.mdをReadしてから実装」と指示 - 実装前にPlanを人間がレビュー: 計画段階で齟齬を潰す
- Plan + 実装を1セッションでやらない: 分離するからこそ「中断 → 再開」「人間による確認」が可能になる
シナリオ7: Editが失敗し続ける(old_string 不一致)
再現条件
Edit ツールでold_stringを指定して書き換えようとするが、String not found エラーが出続ける。
症状
何度書き直してもold_stringがマッチせず、無限ループに近い試行が起きる。
根本原因
ファイルを最後にReadしてから時間が経ち、その間にファイルが他者(Hook / 別のEdit / 別エージェント)によって書き換えられている。または、context内のファイル内容と実ファイルが微妙にズレている(空白文字の差等)。
対策
- Editの直前でReadし直す: 最新内容をcontextに入れてからEdit
- 複数行のold_stringで一意性を担保: 1行だと同じ文字列が複数箇所にあって失敗しがち
- Writeで全置換も検討: 軽微な変更が続くより、思い切ってWriteで書き直す方が早い場合もある
シナリオ8: Hookが無限ループする / 応答が極端に遅い
再現条件
PostToolUse で重い処理(フルテスト、フルビルド)を仕込んだ場合、または * matcherで全toolにhookを張った場合。
症状
Claude Codeの応答が常に遅い、Readする度に30秒待たされる、テストが終わらないうちに次の編集が走って二重実行される。
根本原因
Hookは同期実行され、終わるまでメインの応答が止まります。matcherが広すぎると 副作用のないtool(Read / Grep / LS)にもhookが掛かり、無駄な待ちが発生します。
対策
- matcherを
Write|Edit等の副作用toolに絞る - 重い処理は
1>&2でstderrに流してcontext汚染を避ける - 重テストは
SessionEndや手動CLIに分離: 応答性を犠牲にしない
シナリオ9: Bashの長時間プロセスでセッションが固まる
再現条件
Bash ツールで npm run dev や python serve.py のような長時間プロセスをforegroundで起動した場合。
症状
Claude Codeが Bash の完了を待ち続けて応答しない。Ctrl+Cしないと先に進めない。
根本原因
Bash のforeground実行はプロセスが終了するまでblockします。常駐プロセスをforegroundで起動すると永久に終わりません。
対策
run_in_background: trueを使う: 完了通知が来るまで他の作業を続けられる- 完了条件のあるコマンドだけforeground:
npm test、tsc --noEmit等 - Monitorツールで状態確認: 長時間処理は別ツールで観測する
シナリオ10: gitのdestructive操作で履歴を壊す
再現条件
git push --force git reset --hard git branch -D 等をClaude Codeに任せた場合。
症状
公開済みcommitが消える、PRの履歴が変わる、他者の作業が上書きされる。
根本原因
Claude Codeは Bash 経由で任意のgitコマンドを実行できる。禁止リストが無ければそのまま走る。
対策
- CLAUDE.mdに運用ルールを明文化: 「force pushとreset --hardは使わない」「rebaseよりmerge」
- PreToolUse Hookでgit destructiveをblock: 設定例はHooks実例カタログレシピ3と同パターン
- 権限sandboxで隔離: Claude Code用ユーザーにはpush権限を与えない構成
共通する設計原則
10シナリオを通して見えてくる原則は次の3点です。
- Contextは有限資源として扱う: Read / Bashの出力 / 並列の結果すべてがcontextを圧迫する。サブエージェントで隔離する設計が長セッションでは必須
- 副作用のある操作には必ずガードを置く: Hook / 権限sandbox / CLAUDE.mdルールの三段構えで、AIの判断ミスが本番に届かないようにする
- 暗黙の状態を明示のcontextにする: PlanをReadし直す、Edit前にReadする、サブエージェント結果のテンプレを指定する。「覚えてるはず」に頼らない
まとめ
Claude Codeの挙動の不具合のうち、モデル能力の限界に起因するものは実は少数です。多くはcontext設計・ツール使用パターン・運用ルールの問題で、本記事の10シナリオに収まります。それぞれの根本原因が分かれば、HookやSkillやCLAUDE.mdルールで仕組み化できます。「Claude Codeが期待通りに動かない」と感じたら、まず本記事の早見表を辿ってみてください。
関連する記事
Claude Code をもっと見る →Claude Code導入を検討するCTO / Tech Leadのための評価軸6つ
Claude Code Routines完全実践ガイド — クラウド側で動く「予定されたClaude」
Claude Code Worktree完全活用 — エージェント並列開発のための隔離戦略
Claude Codeのサブエージェント完全活用 — Taskツールで作る並列開発パターン
Claude Codeで個人メディアを24時間自走させる — 運営の1日と内部構造
Claude Codeのメモリ三層構造 — CLAUDE.md / Settings / Skillsの使い分けと組み合わせ
Claude Code Hooks実例カタログ — 9つのユースケース別レシピと避けたい落とし穴
Claude CodeをDevContainerで安全に動かす完全実装 — sandbox設計と認証情報の遮断