はじめに
Claude Codeを使い始めた頃は使い方がわからず、技術スタックのベストプラクティスをCLAUDE.mdにベタ書きしていた。CLAUDE.mdはかなりの量になっていた。
その後「段階的開示(Progressive Disclosure)」という考え方とAgent Skillsを知り、CLAUDE.md・スキル・サブエージェント・MCP・Hooksの使い分けが見えてきた。自分はこのブログの記事の企画・執筆・公開までを、Claude Codeを使った1つのプロジェクトで管理している。この記事では、そのプロジェクトを例に、今どう分けているかと、その基準を書く。
段階的開示という考え方
段階的開示とは必要な情報を必要になったときにだけ読み込ませる考え方だ。Claude Codeのコンテキストウィンドウは有限なので、使わない情報を最初から全部載せておく理由はない。
自分はこれを次の基準に落とし込んでいる。
- 即時または常時認識しておくべきこと → コンテキストファイル(CLAUDE.md)
- それ以外 → スキルなどで、必要になったときに読み込ませる
5つの仕組みを、コンテキストへの載り方で並べると次のようになる。
仕組み | コンテキストへの載り方 | 記事制作プロジェクトでの使い方 |
|---|---|---|
CLAUDE.md | セッション開始時に常に読み込まれる | フォルダ構成・スクリプト・ブログやnoteなど投稿先ごとの公開フロー |
スキル | 普段は名前と説明文だけ。呼ばれたときに本文が読み込まれる | 執筆・分析・公開など44個の手順書 |
サブエージェント | メインとは別のコンテキストで動き、結果だけを返す | 企画・リサーチ・執筆などの工程(10個) |
MCP | ツール定義。現在は必要になったときに読み込む仕組みが既定 | microCMSだけ |
Hooks | コンテキストではなく、決まったタイミングでコマンドを実行する | 自分ではまだ書いていない(勉強中) |
CLAUDE.md:常に必要なことだけを書く
CLAUDE.mdはセッションを始めるたびに必ず読み込まれるファイルだ。プロジェクトのルートに置くほか、~/.claude/CLAUDE.mdに書けば全プロジェクトに効く。
常に読み込まれるということは書いた分だけ毎回コンテキストを消費するということだ。
今の記事制作プロジェクトのCLAUDE.mdに書いているのはどの作業でも前提になる情報だ。
- フォルダ構成と、それぞれの用途
- よく使うスクリプトのコマンド
- ブログやnoteなど投稿先ごとの公開フローの概要
一方で、記事の書き方や公開の細かい手順は書いていない。それらはスキルに分けている。
なお、公式ドキュメントでは1ファイル200行未満が目安とされている。自分のCLAUDE.mdは現時点で204行ある。
スキル:繰り返す指示を手順書にする
スキルは特定の作業の手順をまとめた.claude/skills/<スキル名>/SKILL.mdだ。CLAUDE.mdとの違いは普段は名前と説明文だけがコンテキストに載り、本文は呼び出されたときに読み込まれる点にある。まさに段階的開示の仕組みだ。
---
name: schedule-check
description: 記事のストック状況と今週の投稿スケジュールを確認するとき
---
# Steps
1. 予約公開の状況を同期する
2. ...
記事制作プロジェクトには今44個のスキルがある。最初にどの作業をスキルにしたかは覚えていない。ただ、スキルにする前と後では、毎回の説明が要るかどうかが違う。手間が減った気がする。
スキルの設定にも、段階的開示を効かせる項目がある。
disable-model-invocation: true:Claudeが自分の判断で呼び出さなくなり、説明文もコンテキストに載らない。自分の環境では記事の公開処理などのスキルに付いているcontext: fork:スキルをメインとは別のコンテキストで実行する。自分の環境では公開スケジュールの確認やアクセス分析などのスキルに付いている
本業でも同じ説明をした
この使い分けは本業でAI導入に関わったときにも役立った。個人開発で身につけたコンテキストファイルとスキルの構成や使い方が役に立った。
説明したのは次のような内容だ。
- 開発で何度も同じような指示をするなら、スキルにする
- スキルにしておけば、別のプロジェクトでも流用できる
- なぜスキルにするのか、コンテキストファイルとは何が違うのか
サブエージェント:メインのコンテキストを汚さない
サブエージェントはメインの会話とは別のコンテキストで動くエージェントだ。途中で読んだファイルや検索結果はメインに残らず、最終的な結果だけが返ってくる。
記事制作プロジェクトでは、工程ごとにサブエージェントを分けている。企画を出すエージェント、検索需要や競合を調べるエージェント、本文を書くエージェントなどで、今10個ある。
工程を分けたのはサブエージェントにするとメインのコンテキストが汚染されないと知ってからだ。コンテキストに情報が多すぎると、ハルシネーションの原因にもなる。なので、それぞれのエージェントには極力余計な情報を与えないようにしている。
ツールを絞っておくと、役割がはっきりする。たとえば調べるだけのエージェントなら、読み取り系のツールだけを渡す。
---
name: researcher
description: 検索需要・検索意図・競合分析を担当する
tools: Read, WebSearch, WebFetch
---
MCP:今はmicroCMSだけ
MCPは外部のサービスやデータにClaude Codeをつなぐ仕組みだ。今使っているMCPはブログのCMSであるmicroCMSだけだ。
以前は「MCPはつないでいるだけでツール定義がコンテキストを消費する」ものだった。現在のClaude Codeでは、ツール定義を必要になったときに読み込む仕組み(tool search)が既定で有効になっている。そのため、使っていないツールの定義が常に載り続けるわけではない。ただし、この仕組みを無効にした環境などでは、従来どおり接続時に定義が読み込まれる(公式ドキュメント)。
また、microCMSのMCPから公開や削除をするツールを設定で禁止し、下書きの作成と予約だけを使えるようにしている。
Hooks:まだ使いこなせていない
HooksはClaude Codeの決まったタイミング(ツールの実行前後、セッション開始時など)で、AIの判断とは関係なく必ずコマンドを実行する仕組みだ。コンテキストに情報を載せる仕組みではないので、ほかの4つとは性格が違う。
正直に書くと、Hooksはまだ使いこなせておらず勉強中だ。設定ファイルを確認してみると、自分で書いたHooksは1つもなかった。動いていたのは入れているプラグインに含まれるHooksだけだった。たとえば、セッション開始時やコンテキストの圧縮後に、スキルの使い方の案内を読み込ませるHookがある。
書き方で注意が必要なのは設定の入れ子だ。matcherごとのグループの中にhooksの配列を置く形になっている。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
これはファイルを編集した後にPrettierで整形する例だ(公式ドキュメント)。
まとめ
CLAUDE.mdにベストプラクティスを詰め込んでいた頃から変わったのは「いつ必要になる情報か」で置き場所を決めるようになったことだ。
仕組み | 置くもの | 判断の基準 |
|---|---|---|
CLAUDE.md | 即時・常時認識しておくこと | どの作業でも前提になるか |
スキル | 繰り返す作業の手順 | 同じ説明を何度もしているか |
サブエージェント | 途中経過の多い工程 | メインのコンテキストに残す必要があるか |
MCP | 外部サービスとの接続 | 本当に必要なサービス・ツールだけか |
Hooks | AIの判断に任せず必ず実行したい処理 | (勉強中) |
自分のCLAUDE.mdを開いてみて、毎回読み込む必要のない手順が混ざっていないかを一度見直してみてはどうだろうか。