Claude Codeの原則 第1回 コンテキストウインドウという制約
Claude Codeのすべての設計思想は「コンテキストウインドウは有限で、埋まるほど性能が落ちる」という1つの制約から導かれます。第1回ではその制約の正体を整理し、「この情報を、どこに置くか」という問いへの最初の回答としてCLAUDE.mdの設計原則を読み解きます。
はじめに
Claude Codeは、Anthropicが提供するコマンドライン向けのコーディングエージェントです。ターミナルから自然言語で指示を出すと、ファイルを読み、コードを書き、テストを走らせるまで、人間の開発者がやるような一連の作業を自律的に進めてくれます。
その公式ドキュメントに「ベストプラクティス」というページがあります。実践例やワークフローの紹介ではなく、もう少し手前の、Claude Codeを使うときの「視点」や「マインドセット」を整える内容が淡々と書かれています。
Claude Codeは自然言語で操るツールなので、極端な話、ドキュメントを読み込まなくても触れてしまいます。だからこのページも、見た人の多くは機能カタログのつもりで流し読みしてしまうのではないでしょうか。しかし実際には、ここに書かれている原則こそ、「なぜこの機能があるのか」「なぜこの使い方が推奨されるのか」を身につけるための鍵になっています。
ベストプラクティスの冒頭には、こう書かれています。
ほとんどのベストプラクティスは1つの制約に基づいています。Claudeのコンテキストウインドウはすぐにいっぱいになり、満杯になるにつれてパフォーマンスが低下します。
CLAUDE.mdをなぜ軽く保つのか、なぜSkillsという仕組みが後から追加されたのか、なぜサブエージェントが「並列処理のためだけではない」と強調されるのか。コンテキストウインドウという1つの制約を軸に見直すと、バラバラに見えた項目がひとつながりの思想として理解できます。
Claude Codeは週単位で進化していて、「昨日のベストなやり方」が今日にはもう最適ではない、という話もよく聞きます。ただ、本記事で扱う原理原則は、機能ではなくLLMそのものの性質に根ざしています。だから、しばらくは通用するはずです。
前提知識としては、Claude Codeを少し触ったことがある人を想定しています。とはいえ初めての方でも読めるよう、用語はその都度かみくだいていきます。
Claude Codeはチャットボットではない
話を始める前に、誤解を1つ解いておきましょう。Claude Codeは「ターミナルで動く高性能チャットボット」ではありません。
チャットボットは、質問を受け取って応答を返しますが、Claude Codeは違います。タスクを受け取ると、自分でファイルを読み、コマンドを実行し、結果を見て、軌道修正しながら、問題が解決するまで走り続けるのです。公式ドキュメントではこの動きを「agenticループ」と呼んでいて、3つのフェーズで構成されています。
- コンテキストの収集:関係ファイルを検索し、読み込んで理解する
- アクションの実行:コードを書き、コマンドを走らせる
- 結果の検証:テストを実行する、出力を見る、スクリーンショットを比較する
この3つは固定順ではなく、状況に応じて何度も往復します。デバッグなら3フェーズを何周もするし、コードベースへの単純な質問ならコンテキスト収集だけで完結します。Claudeは前のステップの結果を見て、次に何をすべきか自分で判断します。
この「自律性」こそがチャットボットとの本質的な違いです。だからこそ「どのファイルを読んで」「次にこのコマンドを叩いて」と細かく手順を指示するのは、むしろ逆効果になります。公式ドキュメントには次のように書かれています。
有能な同僚に委譲することを考えてください。コンテキストと方向を与え、Claude が詳細を理解することを信頼します。
Anthropic自身が社内のエンジニア・研究者を対象に実施した調査(How AI Is Transforming Work at Anthropic)では、Claude Codeの導入によってエンジニア一人あたり1日のマージ済みPR数が67%増加したと報告されています。単にスピードが上がるというより、委譲できる相手がいることで仕事の進め方そのものが変わる、という変化です。
ここからが本題です。自律的に動くエージェントを手なづけるには、それが何に縛られているかを理解する必要があります。
コンテキストウインドウという制約
まずは、コンテキストウインドウを理解し、それがどのような制約になるのかを概観します。そして、その制約に基づいた設計のポイントを考えましょう。
コンテキストウインドウとは何か
コンテキストウインドウは、LLMの作業メモリだと捉えれば十分です。Claudeがやり取りで参照できるすべての情報 ―― 会話履歴、読み込んだファイル、コマンドの出力、CLAUDE.md、読み込まれたSkill、システムプロンプト ―― を保持しておく場所で、人間で言えばワーキングメモリに近いものです。
Claude Codeのコンテキストウインドウは、Claude 4系のOpus 4.7・Opus 4.6・Sonnet 4.6で最大1,000,000トークンです(モデルやプランによって異なり、対象外のモデルや一部プランでは200,000トークン)。数字だけ見ると巨大ですが、実際には驚くほど速く埋まります。単一のデバッグセッションやコードベース探索だけで数万トークンが動きますし、MCPサーバー(外部ツールをClaudeに接続する仕組み)の設定や使い方によっては、ツール定義だけでもまとまったトークンを消費します。現在の使用量は/contextコマンドで確認できます。
補足:スラッシュコマンドについて
Claude Codeでは、プロンプト欄のメッセージ先頭で/から始まる文字列を入力すると、組み込みの機能を呼び出せます。/contextは現在のコンテキスト使用量を表示、/clearは会話をリセット、/compactは要約圧縮、などです。途中に/を書いても通常の文字として扱われます。以降の章で複数のスラッシュコマンドが登場しますが、いずれもこの同じ仕組みです。
補足:MCPツール定義のコンテキスト消費
MCPサーバーのツール定義は、以前は接続した時点でコンテキストに常駐していました。複数のMCPサーバーをつないでいると、それだけでまとまったトークンを消費してしまうのが定番の悩みだったのです。
これは現行のClaude Codeでは改善されており、MCPツール定義はデフォルトで遅延ロードされるようになっています。セッション開始時点ではツール名のみがコンテキストに乗り、実際にそのツールが使われたタイミングで初めて完全な定義が読み込まれます。/mcpコマンドで、サーバーごとのコンテキストコストを確認できます。
それでもMCPサーバーを大量に接続している場合や、明示的にツール定義を常時ロードする設定にしている場合は、無視できない消費になります。MCPの設定を見直すときは、まず/contextと/mcpで実際の消費量を見るのが出発点です。
なぜ満杯にしてはいけないのか
コンテキストが埋まると何が起きるのか。公式ドキュメントは端的にこう書いています。
コンテキストウインドウがいっぱいになると、Claude は以前の指示を「忘れる」か、より多くの間違いを犯す可能性があります。
これは経験則ではなく、LLMの性質として研究でも知られています。Liu氏らの論文 "Lost in the Middle: How Language Models Use Long Contexts"(2023年、TACL 2024掲載)は、長文の中盤に置かれた情報が、冒頭や末尾に置かれた情報より明らかに取り出されにくいことを示しました。
Claude Codeのセッションでも、症状として現れます。よく報告されるのは次のようなものです。
- セッション前半で伝えたコーディング規約を、30ターン後には守らなくなる
- 1時間前に決めたアーキテクチャと矛盾するコードを書き始める
- 同じ関数をすでに書いたことを忘れて重複実装する
- 存在しないファイルパスを幻覚する
いずれも「気まぐれ」ではなく、コンテキスト飽和から予測可能な形で起きる現象です。公式ベストプラクティスが「コンテキストウインドウは管理すべき最重要リソース」と明言するのはこのためで、トークン消費量(お金の話)以前に、品質の話として重要なのです。
この制約から導かれる「設計の問い」
ここまでで、コンテキストウインドウが有限で、埋まるほど性能が落ちる資源だとわかりました。すると、Claude Codeを使ううえで繰り返し問われるのは次の一点になります。
この情報を、どこに置くか?
毎回コンテキストに読み込ませるのか(CLAUDE.md)。使うときだけ展開されればいいのか(Skill)。そもそも別のコンテキストで処理したほうがいいのか(サブエージェント)。外部ファイルに書き出して必要に応じて読み込むのか。
以降の章は、すべてこの問いへの答えです。なお、コンテキストが汚れてきたときの具体的な対処法(/clearや/compactの使い分け)は、次回以降の記事でまとめて扱います。
CLAUDE.mdはなぜ「軽く」保つのか
CLAUDE.mdは、Claude Codeがセッション開始時に自動で読み込む特別なマークダウンファイルです。「このプロジェクトではES Modulesを使う」「テストはpnpm testで動かす」といった、Claudeがコードだけからは推測できない情報を渡すために使います。Claude Codeを使い始めると、まずここを整えることになるでしょう。
仕組み:書いた分だけ毎回コンテキストを消費する
重要なのは、CLAUDE.mdは毎回のセッションで全文が読み込まれるという点です。Skillsのように「必要なときだけ」ではありません。つまり、そこに書いた内容はこのプロジェクトで動くすべての会話でコンテキストを消費し続けます。
この性質から、運用原則は自動的に決まります。CLAUDE.mdはできるだけ小さく保つ。 これが原則です。
定量的な指針
では、どれくらいが「小さい」のか。実践者のあいだでよく言われる経験則がいくつかあります。
Claude Codeの実践ガイドを公開しているStan Sedberry氏は、ファイル別に次のようなサイズの目安を挙げています。
~/.claude/CLAUDE.md(個人用グローバル設定):50行未満- プロジェクトルートの
CLAUDE.md:300行未満(短いほどよい) - 読み込まれるファイル全体の合計:2,000トークン未満
500行を超えるCLAUDE.mdを書いてしまっている場合は、ほぼ確実に肥大化していると見て間違いありません。
よくある落とし穴が、/initコマンドで自動生成したCLAUDE.mdをそのまま使い続けてしまうことです。/initはプロジェクト構造を分析してスターターを作ってくれますが、冗長でノイズの多いドキュメントになりやすい。土台として使い、そこから削り込んでいくのが正解です。
補足:日本語で書くCLAUDE.mdはトークン数に注意
Sedberry氏の数値は英語ベースの目安です。日本語の文章は、英語より1文字あたりのトークン数が多くなりがちです(ざっくり英語は1単語あたり1〜2トークンなのに対し、日本語は1〜2文字で1トークンになることが多い)。
そのため、同じ「2,000トークン以内」を目指す場合、日本語のCLAUDE.mdは英語より行数を絞る必要があると思っておくとよいでしょう。実際のトークン数は/contextで確認できます。
CLAUDE.mdに何を含めるべきか
CLAUDE.mdに何か書き足そうとしたとき、自分に問うべき質問があります。公式ドキュメントが示している基準はシンプルです。
「これを削除するとClaudeが間違いを犯しますか?」
迷わず「YES」と言えないなら、書かない。あるいは削る。これだけです。
具体的な判断例を並べると次のようになります。
| 含める | 除外する |
|---|---|
Claudeが推測できないBashコマンド(pnpm prisma migrate devなど) |
Claudeがコードを読めばわかること |
| デフォルトと異なるコードスタイル規約 | 一般的な言語規約(「関数名はキャメルケース」など) |
| テスト実行方法と推奨ランナー | 詳細なAPIドキュメント(リンクで十分) |
| リポジトリのエチケット(ブランチ命名、PR規約) | 頻繁に変わる情報 |
| プロジェクト固有のアーキテクチャ決定 | ファイル単位のコードベース説明 |
| 環境変数など開発環境の癖 | 「きれいなコードを書く」のような自明な原則 |
| 明白でない動作、踏みやすい地雷 | 長い説明やチュートリアル |
症状と診断
CLAUDE.mdの運用がうまくいっているかは、Claude自身の挙動で診断できます。
- 「書いてあるのに守らない」 → ファイルが長すぎて、重要なルールがノイズに埋もれている。削る時期です。
- 「書いてある内容を聞き返してくる」 → その書き方が曖昧。トリガー条件を明示する表現に直しましょう。
CLAUDE.mdはコードと同じく、書きっぱなしではなく、レビューして削ってテストする運用対象として扱うのがよさそうです。
「トリガー + アクション」形式で書く
ルールの書き方にも作法があります。実践者のあいだで定着している形は「いつ(トリガー)、何をするか(アクション)」をセットで書くことです。
- NG:
schema.prismaの直接編集は禁止 - OK:
schema.prismaを変更したいときは、schema/*.prismaを編集してpnpm build:schemaを実行する
禁止事項だけを並べると、Claudeはそのルールを守るべき場面を判断できません。「いつ、どうする」という行動指示に翻訳すると、遵守率が劇的に上がります。人間の新メンバーに地雷マップを渡すイメージです。
補足:CLAUDE.mdは階層的に配置できる
CLAUDE.mdは1箇所にしか置けないわけではありません。Claude Codeは複数の場所を自動で探索します。
~/.claude/CLAUDE.md:すべてのプロジェクトに適用される個人設定<プロジェクトルート>/CLAUDE.md:チームで共有するプロジェクト設定(git管理)<プロジェクトルート>/CLAUDE.local.md:個人用のプロジェクト設定。.gitignoreに入れてチームと共有しない- 親ディレクトリの
CLAUDE.md:モノレポで共通ルールを置くのに便利 - 子ディレクトリの
CLAUDE.md:そのディレクトリで作業するときだけオンデマンドで読み込まれる
モノレポなら、ルートに全体共通のルール、各パッケージ配下にそのサービス固有のルール、という階層設計ができます。全部を1ファイルに詰め込まないのがコツです。
ここまでのまとめ
Claude Codeはチャットボットではなく、agenticループで動く自律的なエージェントです。そのすべての設計思想は1つの制約から派生しています。コンテキストウインドウは有限で、埋まるほど性能が落ちる、という事実です。
Claude Codeを使ううえで繰り返し問われるのは「この情報を、どこに置くか」という1点です。CLAUDE.mdを軽く保つのも、この問いへの最初の回答でした。
次回は、同じ問いへのさらなる回答として、Skillsとサブエージェントのコンテキスト管理を扱います。