CLAUDE.mdに「圧縮後はSkillを再読み込みしてください」という指示を書いたのに、なぜそれでも機能しないのですか?
これはまさにissue #13919が報告している現象だ:~/.claude/CLAUDE.mdに書かれた明確な「圧縮後に再読み込み」の指示さえ、圧縮後に無視されてしまう。理由は、圧縮という動作自体が「contextを消去して再構築する」ことを本質としており、CLAUDE.mdのような起動時読み込みコンテンツは確かに再読み込みされるものの、Claudeがその指示を読んだからといって、「特定のSkillファイルを再読み込みする」という追加の動作を自発的に実行するとは限らないからだ。フックを別途設定してこの動作を自動化しない限り、ドキュメントに書かれた一文だけでは、実際に実行される保証はない。
なぜ公式は、毎回の圧縮時にSkill一覧を自動的に再注入して、みんながこの落とし穴を避けられるようにしないのですか?
Anthropicのエンジニア@bchernyがissue #74990で述べている理由はコストだ:Skill一覧全体を再送信すると、圧縮ごとに数千トークンの余分なコストがかかり、当初の評価は「すでに呼び出されたSkillの内容が保持されれば十分だろう」というものだった。この判断は「ユーザーが会話を通じて同じSkillを使い続ける」というシナリオでは合理的だが、「ユーザーがその会話でまだ呼び出していない別のSkillに切り替えたい」というよくあるケースをカバーしていない。このギャップこそが、この挙動が単純な設計上のトレードオフとして受け入れられるのではなく、バグとして報告され続けている理由だ。
手動で/reload-skillsを実行する以外に、最初からこの問題が起きないようにする方法はありますか?
タスク自体がそれほど長くならないなら、単純に会話の長さが自動圧縮の閾値に近づかないようにすること(issue #13919が報告した事例ではVS Code拡張機能で約55Kトークン付近でトリガーされていた)が最も直接的な方法だ——例えば、明らかに新しいサブタスクに切り替わったタイミングで/clearを積極的に使って新しい会話を開始し、同じ会話を無制限に延長して自動圧縮させないようにする。
しかし、タスクそのものが長時間にわたり、複数のステップで同じSkillに依存する必要がある場合、圧縮を避けることよりも、SessionStartフックを設定し、matcherを"compact"に設定して"reloadSkills": trueを返すようにする方が現実的だ。これにより、再読み込みの動作が圧縮イベント自体に結びつけられ、毎回自分で思い出す必要なく自動的に発火する。
Claude Codeを使い始めたばかりで、フックの設定方法が全くわかりません。もっと手間のかからない対処法はありますか?
ある。設定ファイルに一切触れる必要もない。覚えておくべきシンプルな対応関係は一つだけだ:ターミナルに「Conversation compacted」という行が表示された後、その後のClaudeの振る舞いが以前と明らかに違うと感じたら(以前すでに明確に解決していた間違いを再び繰り返すなど)、まず手動で/reload-skillsを一度実行し、問題が消えるかどうかを確認する。
このコマンドはプロジェクトに何の変更も加えない。純粋にClaudeに「今利用可能なSkill」を再び伝えるだけなので、リスクは低く、圧縮後の習慣的な確認動作として扱える。慣れてきたら、この動作をフックで自動化するかどうかを検討すればいい。
セッションの途中で、ターミナルに「Conversation compacted」というメッセージが表示される——これは/compactが長くなった会話を要約に圧縮して、context windowの空間を解放しているところだ。しかし、その会話の中で以前Skillを使っていた場合、圧縮直後にClaudeが突然そのSkillをまったくインストールしていなかったかのように振る舞うことがある——同じ間違いが再び現れ、そのSkillが防ぐはずだった悪い習慣が戻ってくる。これはバグではない。圧縮メカニズムの意図的な設計上のトレードオフであり、ただそれがほとんど明確に説明されていないだけだ。
公式のcontext windowドキュメントは、圧縮後の状態について具体的に説明している:システムプロンプト、CLAUDE.md、メモリファイル、MCPツール一覧といった起動時に読み込まれる内容は、圧縮後に自動的に再読み込みされる。Claude Codeはさらに、最近変更された最大5つのファイルを再読み込みし、圧縮前に実際に呼び出したSkillの内容を再注入するが、Skillごとの内容は5,000トークンが上限だ。圧縮要約自体が保持するのは「あなたのリクエストと意図、主要な技術的概念、確認または変更したファイルと重要なコードスニペット、エラーとその修正方法、保留中のタスク、現在の作業状況」であり、代わりに失われるのは逐語的な会話記録——完全なツール出力と中間の推論過程は消える。
ここで最も見落とされやすい点はこうだ:Skill一覧そのもの(最初に「今どのSkillが使えるか」を示していたインデックス)は、圧縮後に再注入されない。公式ドキュメントはこれを直接的に述べている——この一覧を除けば、起動時の他の内容はすべて再読み込みされるが、この一覧だけは例外であり、実際に「呼び出した」Skillの内容だけが保持される。
GitHub issue #74990はこの挙動を完全に記録している:圧縮前、Claudeは正しく27から33個の利用可能なSkillを報告できる。圧縮後、今どのSkillが使えるかを直接尋ねると、「Available skillsのシステムリマインダーブロックが見つからない」という答えが返ってくる——Skillの数が減ったわけではなく、この一覧全体が消えてしまったのだ。/reload-skillsを実行すると、Claudeは即座に33個すべてのSkillを再び見られるようになり、コマンドの応答メッセージは「33 skills available (no changes)」となる。この「no changes」という一言が重要で、Skill自体は最初から最後まで無事であり、削除も破損もしていなかったことを示している。問題は純粋に「この一覧がcontextに再び入れられるかどうか」という一点にある。
Anthropicのエンジニア@bchernyはこのissueで、より直接的な公式説明を与えている:これは意図的な設計上の決定だ——Skill一覧全体を再送信すると、圧縮ごとに数千トークンの余分なコストがかかる。当初の判断は「すでに呼び出されたSkillの内容が保持されれば十分だろう」というものだった。この判断が考慮していなかったのは、ユーザーが次に呼び出したいのが「この会話でまだ使っていない」別のSkillだった場合だ。この場合、一覧がすでにcontextに存在しないため、ClaudeはそのSkillの存在すら知る方法がない。
issue #13919は、さらに厄介な事例を記述している:VS Code拡張機能において、約55Kトークン付近で自動圧縮がトリガーされると、Claudeはどのスキルが利用可能かを忘れるだけでなく、すでに使用中だったSkillが教えていた具体的な方法論そのものも忘れてしまう。報告者が挙げた例は、あるSkillが「ABC(よくある間違い)を絶対にしてはいけない」と規定し、Claudeに毎回の応答の冒頭で「Skill ACTIVE」と言うよう求めていたケースだ。圧縮後、Claudeはその発言をしなくなり、そのSkillが明示的に禁止していたABCという間違いを再び犯すようになった。ユーザーが~/.claude/CLAUDE.mdに「圧縮後はSkillを再読み込みしてください」という明確な指示を書いていても、その指示自体も圧縮後に無視された。報告者の見積もりでは、本来1時間で終わるはずのタスクが、この循環的なエラーのせいで5〜6時間以上に延びたという。
issue #74990で示されている対処法は直接的だ:圧縮が発生するたびに手動で/reload-skillsを実行する、あるいはSessionStartフックを設定し、matcherを"compact"に設定して"reloadSkills": trueを返すようにすれば、この作業を毎回手動で思い出す必要がなく自動化できる。ワークフローが特定のいくつかのSkillに大きく依存している場合、このフックを設定するコストは、Claudeが何かを「忘れた」ことを後から何度も発見するコストよりもはるかに低い。
最もわかりやすい兆候は、圧縮前はClaudeの動作が完全に正常で、あるSkillが教えた方法を積極的に適用していたのに、圧縮後に突然同じ種類の間違いをし始める、あるいは「今どのSkillが使えるか」を直接尋ねると、圧縮前と比べて明らかに少ない答えが返ってくることだ。このような状況が発生したら、まず自分がちょうど/compactか自動圧縮を経験したかどうかを確認し(ターミナルに「Conversation compacted」というメッセージが表示される)、次に/reload-skillsを一度実行して復元されるかを確認するとよい。復元されれば、これが原因であり、Skill自体の設定ミスではないと確認できる。