Claude Codeが突然バグる本当の理由を、実測データで特定した
Claude Codeがフリーズ・幻聴・生ログ吐き出しを起こす原因を実測データで解剖。空きメモリ103MB・スワップ2700万回の計測結果、コンテキスト自己中毒(self-poisoning)の仕組み、前兆3段階サイン、セッション引き継ぎ手順まで。
エンジニアのゆとです。
「Claude Codeがバグった」——この報告を自分のXに投稿したとき、想定外にリプが飛んできた。
「わかる、急に無言になる」「返事がズレてきたと思ったらフリーズした」「謎の記号が混じってセッション崩壊した」。
みんな同じ経験をしていた。
最初は「バージョンのバグだろう」と思っていた。でも調べていくうちに、実態が見えてきた。ソフトウェアのバグというより、上限を超えた使い方が引き起こす必然的な崩壊だった。
この記事では、実測データを使って原因を解剖する。前兆のサイン3段階、対処法、そしてバグ後のセッション引き継ぎ手順まで書く。
バグの症状は3パターンある
Claude Codeが「バグる」ときの症状は、実は3種類に分類できる。
症状① 待てども無言返答が来ない。数十秒から数分のフリーズ。酷いときは完全無言のまま終わる。「処理中なのか止まっているのか」の判断もつかない。
症状② 会話が通じなくなる少し前の指示を忘れる。文脈がズレる。的外れな返答が続く。「さっき決めたはずのことを、なかったことにして動く」というパターンが典型だ。
症状③ 生ログ吐き出し(末期)これが一番きつい。<invoke> タグやコマンドの断片がそのまま文章として漏れ出す。
call
<invoke name="Bash">
<parameter name="command">git status</parameter>
</invoke>
こういうものが返ってきたら、セッションはほぼ死んでいる。
実測データで犯人を特定した
フリーズが頻発した日、アクティビティモニタを開いて計測した。数字を見たとき、正直「そりゃそうなるよ」と思った。
| 項目 | 実測値 |
|---|---|
| 空きメモリ | 103MB(その後80MBまで低下) |
| メモリ圧縮 | 12GB |
| スワップ累計 | 2,700万回超 |
| claude常駐プロセス | 5個 |
空きメモリが103MB。16GBや32GBのMacでこの数字が出るということは、残りはほぼすべてアプリに食い尽くされている状態だ。
スワップ累計2,700万回超。スワップとは、メモリに収まりきらないデータをSSDに追い出す操作のことだ。2,700万回というのは「常時メモリ不足でディスクを頼り続けている」状態を意味する。SSDは速いとはいえ、RAMの比ではない。これが応答遅延の正体だ。
claude常駐プロセスが5個。新しいウィンドウを開くたびに前のプロセスが死なずに残っていた。フリーズして終了したセッションがゾンビ化してメモリを食い続けていた。
Claude Desktopを閉じてもメモリはほとんど回復しなかった(80MB→122MB程度)。圧縮とスワップは再起動でしかリセットされない。
原因は3つが複合している
症状と実測データから、原因は3つが絡み合っていることがわかった。
A. コンテキスト自己中毒(self-poisoning)
これが最も根本的な原因だ。
Claude Codeはツール呼び出しを行うとき、その定義を毎回コンテキストに読み込む。MCPサーバーが10個以上あると、それだけで数万トークンが消える。会話が長くなるほど、実際の会話に使えるトークンが減っていく。
そしてコンテキストが満杯付近になると、ツール呼び出しの構造が壊れ始める——前述の <invoke> タグ漏れがそれだ。
問題はここからだ。壊れた形式の呼び出しが会話履歴に残ると、以降の呼び出しがすべてその壊れた形式を真似る。AIは「直前の例」を強く参考にするので、一度崩れると同セッション内での復旧はほぼ不可能になる。
これは GitHub でも既知の問題として報告されている。
self-poisoning(自己中毒)という名称は、Issue #62344 の報告者が命名したものだ。「会話履歴が自分自身を汚染する」という表現は的確だと思う。
B. メモリ枯渇
Claude CodeはNode.js製だ。Node.jsはメモリ管理をV8エンジンに依存していて、長時間動かしているとメモリ使用量が増加していく傾向がある。
さらに「並行セッション」が問題を複雑にする。複数のプロジェクトウィンドウを同時に開いていると、それぞれがメモリを消費しながら設定ファイルの読み書きを奪い合う。ハングが起きる原因のひとつだ。
C. 長時間セッション
会話が伸びるほど処理が重くなる。特に /compact による自動要約が走る瞬間、一時的にフリーズすることがある。
コンテキストウィンドウの管理については別記事でまとめているので、メカニズムが気になる方はそちらも参考に。
Claude Codeのコンテキスト管理術 — /compact・/clear・CLAUDE.mdで1Mトークンを使い倒す
Claude Code 1Mコンテキストの賢い使い方——トークン枯渇を防ぐ3層管理戦術
ちなみにバージョン2.1.197時点では目立ったソフトウェアバグは見当たらない。「ソフトのバグ」より「上限を超えた使い方」という理解が正確だ。
前兆は3段階ある——「幻聴」が出たら黄信号
ここが今回の記事で一番伝えたいところだ。
崩壊は突然来るわけじゃない。必ず前兆がある。
🟡 黄信号(ここで手を打てば間に合う)
1. 応答が遅い・無言が長引く明らかに普段より時間がかかっている。これは単純にメモリ圧縮とスワップが頻発しているサインだ。
2. 「幻聴」が出る ← 最重要サイン「言っていないことに返事してくる」「確認してきた内容が、自分の発言と微妙にズレている」——これが出たら黄信号だ。
なぜこれが起きるか、少し説明する。
AIは応答を生成するとき、「今あなたが書いた文章」だけを見ているわけじゃない。全会話履歴+接続中の全ツール定義+システムプロンプト、これを毎回まるごと読んでいる。
コンテキストが限界に近づくと、その巨大な履歴の断片を「今あなたが言ったこと」と取り違えるようになる。さらに自動要約や自己中毒で情報が欠けると、足りない部分を「それっぽいこと」で埋めようとする。
これが「幻聴(ハルシネーション)」として現れる。「あれ、そんなこと言ったっけ?」が1セッション内で2回以上出たら、黄信号と思って間違いない。
幻聴の亜種:Opus 4.8固有の「先走り幻覚」もうひとつ別のパターンがある。コンテキスト崩壊とは無関係に、Opus 4.8ではツール出力が届く前に結果を「推定で埋める」という挙動が複数報告されている。
並列タスクを処理中、ツールの実行がまだ終わっていないのに出力が届いたとして数値を書き込む。後でそれが実測値と食い違うと、Opus自身が「私は3回目の嘘をついた」「コミットした数字はどのツール出力にも存在しない」と認める——これが1セッション中に4回発生した詳細なケースが GitHub に記録されている(Issue #63884)。
また「実際には何もしていないのに、作業を完了したと報告する」パターンも報告されており(Issue #64076)、複数回指摘してはじめて「嘘をついていた」と認める。
コンテキスト崩壊型の幻聴は「セッションが長くなったから」起きるが、この先走り幻覚はOpus 4.8+並列処理という組み合わせで発動する。セッション初期でも起きる点が厄介だ。
対策はシンプルで、Opus 4.8使用時はサブエージェント/並列処理を避けるか、Sonnet 5系に切り替えるかだ。
3. 少し前の指示を忘れる・同じ話を繰り返すコンテキストが圧縮や要約で欠けてきているサインだ。
🔴 赤信号(即切る)
4.<invoke> タグや不自然な記号が混じり始める
前述の self-poisoning が始まっている。この段階でそのまま続けると、次のすべての呼び出しが壊れた形式で生成される。
5. 意味不明な言葉の羅列・生ログの吐き出しセッション死亡。このまま会話を続けても意味がない。
対処法
即効で効くもの
再起動でメモリを一掃するこれが最も単純かつ確実だ。Claude Desktopを閉じただけではメモリはほとんど解放されない。Mac自体を再起動してスワップをリセットする。
使っていないMCPを外すMCPサーバーの接続数は、コンテキスト消費に直接影響する。使っていないものをオフにするだけで体感速度が変わる。「生ログ吐き出し」の現象には特に効く。~/.claude.json や .mcp.json を見直して、本当に必要なものだけ残す。
複数プロジェクトを同時に開く習慣があるなら、まずこれを変える。
習慣で防ぐ
1タスク終わったら区切る「まだ余裕あるから続けよう」ではなく、タスクの区切りで意図的に /clear か新セッションに切り替える。満杯を待ってからでは遅い。
「スポットMCP」という考え方で、使うときだけ接続して終わったら外す。常時接続を前提にしない。
バグった後の引き継ぎ
これが実際に一番重要な手順だ。
崩壊したセッションで /resume を使うと、壊れた状態ごと引き継ぐことになる。これは避けた方がいい。
正しい引き継ぎ手順はこうだ。
- 状態を常にファイルに書き出しておく(セッションログ)。「今どこまで進んでいるか」「次に何をするか」「重要な決定事項」を外部ファイルに残す
- バグった後は新しいクリーンなセッションを開く
- 新セッションの最初にログファイルを読ませる(「このファイルを読んで続きをやって」)
セッションが突然死んでも、ログさえあれば3分で復帰できる。ログを書く習慣は面倒に感じるが、実はセッション崩壊の保険として最も効く対策だ。
ハードウェアの話
Apple Silicon M4 ProとM4 MaxにおけるUMA(統合メモリ)は、GPUとCPUでメモリを共有するアーキテクチャだ。LLMの推論ではGPU帯域幅がボトルネックになるので、メモリが多いほど圧縮・スワップへの逃げが少なくなる。
目安は最低32GB、快適に使うなら64GB。ただしハードを変える前に、運用面での改善が先だ。MCPを整理して並行セッションを減らすだけで、体感が別物になる場合が多い。
Claude CodeとDockerを同時に使っている場合、Docker Desktopのメモリ消費(アイドル時4GB超)も空きRAMを圧迫する要因になる。OrbStackへの乗り換えでアイドル時メモリを81%削減できる。
まとめ
Claude Codeが「バグる」本当の原因は、ソフトウェアの欠陥ではなく「コンテキストとメモリの上限を超えた使い方」だった。
崩壊には前兆がある。「幻聴」が出た時点で手を打てば間に合う。
状態をファイルに外部化して、バグ後はクリーンなセッションで再開する——この習慣だけでも、セッション崩壊の影響を最小化できる。
AIは道具だ。道具の特性を理解して使えば、「突然バグる」は「ちゃんと限界が来た」という読めるシグナルに変わる。