この記事のポイント
- Claude Code Skills は便利ですが、1 ヶ月ほど運用していると「成功事例の裏側」で静かに溜まる負債が見えてきます
- アンチパターンを単に列挙するのではなく、そもそも「なぜ Skills という仕組みが生まれたのか」「なぜアンチパターンが構造的に発生するのか」を先に押さえると、対処の優先順位が変わってきます
- 鍵になる思想は「progressive disclosure(段階的開示)」で、コンテキストウィンドウの経済学から逆算すると、肥大化・多責務・曖昧な発火条件がなぜ問題なのかが一本の線でつながります
はじめに
Claude Code に Skills が登場してから、X や Zenn では「便利な Skill 20 選」や「自己改善ループの構築」など、成功事例の紹介が一気に増えました。自分でも 1 ヶ月ほど業務と個人プロジェクトで Skills を運用してきて、開発の進め方そのものが変わったと感じています。
一方で、運用が進むにつれて「これは設計を間違えたな」と思う場面も増えてきました。Skills は CLAUDE.md とは違って必要なときだけロードされるおかげでコストは抑えられるのですが、それゆえに「動いてしまえば気づきにくい負債」が静かに溜まっていきます。
ただ、アンチパターンをただ並べるだけだと「気をつけましょう」で終わってしまい、いざ自分の Skill を直すときに優先順位がつけにくいと感じていました。そこでこの記事では、まず 「なぜ Skills という仕組みが生まれたのか」「なぜアンチパターンが構造的に発生するのか」 という背景から入り、そのうえで各アンチパターンを「なぜそれが問題を生むのか」というメカニズムから説明してみます。
これから Skills を社内展開しようとしているテックリードや、Skills を作り始めて 1〜3 ヶ月の方の参考になればうれしいです。なお、ここで取り上げるのはあくまで自分の運用で見えてきた傾向で、プロジェクトの規模や利用形態によっては当てはまらないケースもあるはずなので、その点は割り引いて読んでいただければと思います。
第 1 部:なぜ Skills は生まれたのか
アンチパターンの話に入る前に、少し遠回りに見えるかもしれませんが、Skills がどんな課題を解くために生まれたのかを整理させてください。ここを共有しておくと、後半のアンチパターンが「なぜ問題なのか」が腑に落ちやすくなると感じています。
コンテキストウィンドウの経済学
LLM を使った開発で、まず効いてくる制約がコンテキストウィンドウです。モデルが一度に読める情報量には上限があり、そして読ませた情報には、おおよそ次の二つのコストがかかります。
- 金銭的コスト — 入力トークンに比例して課金されます。毎ターン同じ大量の前提を読ませていれば、その分だけ費用が積み上がっていきます
- 精度のコスト — これが見落とされがちなのですが、コンテキストに情報を詰め込むほど、モデルが「今この瞬間に本当に必要な情報」を取り出す精度は下がっていく傾向があります。長い文脈の中で重要な指示が埋もれてしまう、いわゆる注意の希薄化のような現象です
つまり「とりあえず全部プロンプトや CLAUDE.md に書いておけばよい」というアプローチは、コストと精度の両面で割に合わなくなりやすい、ということになります。常に全部を読ませる設計は、知識が増えれば増えるほど不利になっていくわけです。
progressive disclosure(段階的開示)という解
ここで出てくる発想が「段階的開示(progressive disclosure)」です。ひとことで言うと 「必要になったときに、必要な分だけ知識を読み込む」 という設計思想です。
Skills はこの思想をかなり素直に形にした仕組みだと感じています。具体的には、おおむね次のような多段構造になっています。
-
常に見えているのは
description(とwhen_to_use)だけ — Skill の本体はロードされておらず、「この Skill は何のためのもので、いつ使うか」という見出し情報だけが Claude から見えています -
発火したら SKILL.md 本体が読まれる — ユーザーの依頼や文脈が
descriptionにマッチして初めて、SKILL.md の中身がコンテキストに乗ります -
さらに必要なら参照ファイルが読まれる — SKILL.md の中で
references/security.mdのような別ファイルを指していれば、本当に必要になった段階でそこだけが追加で読まれます
この三段構えのおかげで、「知識の総量」は無限に増やせるのに、「実際にコンテキストを圧迫する量」は最小限に抑えられます。図書館の蔵書をすべて頭に入れておく必要はなく、背表紙(description)を見て必要な本だけを開けばよい、というイメージに近いです。
ここがいちばん大事なところで、後述するアンチパターンの多くは、この「段階的開示」という前提を壊してしまうことから発生します。肥大化した SKILL.md は「背表紙を見て開いたら、関係ない章まで全部読まされる本」のようなものです。
Skills / プロンプト / ツール(MCP)/ サブエージェントの役割分担
「段階的開示」の発想がわかると、Claude Code まわりの各要素が「いつ呼ばれるか」で役割分担されていることも見えてきます。自分の理解では、おおまかに次のように整理しています。
| 要素 | 何を担うか | いつコンテキストに乗るか |
|---|---|---|
| プロンプト / CLAUDE.md | 常に効かせたい「事実」「前提」「制約」 | 常時 |
| Skills | 特定の場面で使う「手順」「やり方」の知識 | 発火したときだけ |
| ツール(MCP) | 外部システムへの「実際の操作」 | Claude が呼び出したときだけ |
| サブエージェント | 文脈を分離したい「重い調査・並列タスク」 | 委譲したときだけ(別コンテキスト) |
ポイントは、それぞれが「いつコンテキストに乗るか」が違うことです。常に効かせたい前提なら CLAUDE.md、特定の場面で読ませたい手順なら Skills、メインの文脈を汚したくない調査ならサブエージェント、という具合に、コンテキストへの載せ方 で使い分けるという設計意図だと受け止めています。
逆に言えば、この役割分担を無視して「手順なのに CLAUDE.md に常時置く」「重い調査をメインの Skill に直書きする」といったことをすると、段階的開示のメリットが消えてしまいます。
この分け方は厳密なルールというより、自分が運用しながら落ち着いた整理です。チームや用途によっては別の切り方のほうが合うこともあると思います。
第 2 部:なぜ SKILL.md には実質的な行数の限界があるのか
公式ドキュメントでは SKILL.md は 500 行未満に収め、詳細な参照資料は別ファイルに移すこと と推奨されています。ただ、この「500 行」という数字の裏側を理解しておくと、アンチパターン①(肥大化)への向き合い方が変わってきます。
読み込みコストとしての行数
第 1 部で触れたとおり、SKILL.md が発火するとその中身はコンテキストに乗り、ターンをまたいで残り続けます。つまり SKILL.md の行数は、そのまま「発火している間ずっと払い続けるトークンコスト」になります。500 行という上限は、段階的開示の効果を保てる現実的なラインとして引かれた目安だと理解しています。
description による発火判定の仕組み
もうひとつ重要なのが、description が「発火判定の材料」だという点です。Claude は Skill 一覧の description(と when_to_use)を見て、どの Skill を読み込むかを判断しています。仕様上、この判定用テキストは Skill 一覧で 1,536 文字程度に切り詰められます。
ここから逆算すると、発火判定に効くのは本体の中身ではなく description のほうだ、ということになります。本体をいくら丁寧に書いても、description が薄ければそもそも開かれません。後述するアンチパターン③が「曖昧な発火条件」になるのは、この構造に起因しています。
モデルごとの実装差 — Codex が 220 行で打ち切る背景
行数の話で具体的だったのが、@haru0416 さんが報告されている「Codex が SKILL.md を 220 行で打ち切っていた」観察です(参考リンク参照)。これは Codex CLI 側の固定値というより、モデルが学習データから引き出した「SKILL ファイルの典型的な長さ」に基づいて、sed -n '1,220p' のような形で読み込んでいたという見立てでした。
ここから読み取れるのは、SKILL.md がどう読まれるかはツール(モデル)によって差がある ということだと思います。公式仕様で 500 行まで許容されていても、別の AI ツールから読まれる前提だと、本体は 200 行程度に寄せておくほうが安全側に倒せます。
自分の場合も、社内向けに作ったレビュー Skill が 350 行ほどになってしまい、後半に書いた「セキュリティ観点」がほぼ参照されていなかったことに後から気づきました。500 行に収まっていても、実際に読まれていなければ意味がなかった、というわけです。
「SKILL.md には読まれない部分があるかもしれない」という前提で設計しておくほうが安全だと感じています。冒頭 200 行に「使う場面・最小手順・最低限の例」を寄せ、詳細は別ファイル(references/ など)に分離しておくと安心しやすいです。
第 3 部:なぜアンチパターンは「構造的に」発生するのか
ここがこの記事でいちばん書きたかったところです。アンチパターンは、不注意な個人がたまたま起こすものというより、インセンティブのミスマッチ によって構造的に発生しやすいものだと感じています。
個人の合理が、全体の負債になる
Skill を作る瞬間、手を動かしている人の合理は、たいてい次のようなものです。
- とりあえず動けばよい — 目の前のタスクが片付くことが最優先で、再利用や発火精度は後回しになりがちです
- 後で直すが、来ない — 「あとでリファクタしよう」と思った肥大化や多責務は、動いている限り優先度が上がらず、放置されやすいです
- 共有設計より個人最適 — 自分のリポジトリで自分が使う分には、共通化や命名規則よりも、今すぐ動くことのほうが価値が高く見えます
一つひとつは合理的なのですが、これらが積み重なると、組織全体では「肥大化した、多責務で、発火条件が曖昧で、共通化されていない Skill 群」という運用負債になります。コードの技術的負債とまったく同じ構図で、しかも Skills は「Markdown だから気軽」という空気がある分、負債が溜まる速度はむしろ速いかもしれない、と感じています。
だから「メカニズム」で考える
このミスマッチがある前提に立つと、対策は「気をつけましょう」では足りません。各アンチパターンについて「放置すると、どういうメカニズムで、どんな実害が出るのか」を理解しておくと、忙しいときでも「これは後回しにできない」という判断がつきやすくなります。
以下では、各アンチパターンを 「症状」ではなく「なぜ問題を生むのか」というメカニズム から説明していきます。
アンチパターン①:SKILL.md を肥大化させる
なぜ問題か(メカニズム)
肥大化が生む実害は、大きく二つです。
ひとつは 発火精度の低下 です。前述のとおり、行数が増えてもそれが直接 description の精度を上げるわけではなく、むしろ本体に「いつ使うか」の情報を埋め込んでしまうと、判定材料が分散してかえって発火が読みづらくなります。さらにモデルによっては途中で打ち切られ、後半に書いた重要な指示(自分の場合はセキュリティ観点でした)が事実上参照されない、ということが起きます。
もうひとつは コスト増 です。発火している間、本体の全行がコンテキストに乗り続けるので、長い SKILL.md はそのまま毎ターンのトークンコストになります。「全部のせ」は、段階的開示というそもそもの設計意図を裏切る形になり、コストと精度の両方で割に合わなくなりやすいです。
どう向き合うか
冒頭 200 行に「使う場面・最小手順・最低限の例」を寄せ、詳細は references/ などに分離します。本体は「目次と最小手順」、参照ファイルは「必要になったら開く詳細」という役割分担にしておくと、段階的開示の効果が保てます。
アンチパターン②:1 スキルに多責務を詰め込む
なぜ問題か(メカニズム)
たとえば「リリース」という Skill に、ついでにテスト実行・チェンジログ生成・Slack 通知・社内ドキュメント更新まで全部入れてしまう、というケースを社内でも見かけました。最初は便利に見えるのですが、多責務が生む実害は 再利用不能 に集約されると感じています。
- 一部だけ実行したいときに、不要な処理まで走ってしまう
- 失敗したときの原因切り分けが難しくなる
- 修正したい箇所のレビューが、ファイル全体のレビューになってしまう
責務が混ざっていると、「テスト実行だけ別の場面で使いたい」と思っても切り出せません。再利用したい単位とユーザーが一括で呼びたい単位が一致していないことが、根っこの問題だと思います。
どう向き合うか
@misakiito さんの記事では、エントリーポイント層・ルール層・エージェント層を分離する 3 層構造が紹介されていました。発想は近いと思っていて、/release のような統制スキルは「順序とユーザー承認のゲート」だけに責任を持たせ、個別の処理は別 Skill やサブエージェントに委譲する設計のほうが扱いやすいと感じます。
自分の場合も、最初に作った「記事執筆 Skill」がトレンド収集・構成案・本文執筆・タイトル生成・公開チェックまで一本でやろうとしてしまい、途中でいつでも止められない使いにくいものになっていました。後から /trend-check /write-draft /title-gen のように切り出したところ、組み合わせの自由度が上がり、Skill 単体の責務もはっきりしました。
your-app/.claude/skills/
├── trend-check/SKILL.md # トレンド収集だけに責任を持つ
├── write-draft/SKILL.md # 下書き生成だけに責任を持つ
├── title-gen/SKILL.md # タイトル候補生成だけに責任を持つ
└── publish/SKILL.md # 公開フローの統制だけに責任を持つ
ただし、過剰に細かく分けると今度は呼び出し側が複雑になります。「ユーザーが 1 コマンドで完結したい単位」と「内部で再利用したい単位」をどこで切るかは、運用しながら調整していく前提でよいと思います。
アンチパターン③:発火条件があいまい/description が薄い
なぜ問題か(メカニズム)
Skill のオート発火を期待しているのに、なぜか呼ばれない、という場面はよくあります。第 2 部で触れたとおり、Claude は本体ではなく description(と when_to_use)を見て発火を判定しています。ここが薄いと、発火判定そのものが成立しません。
このアンチパターンが生む実害は、両方向に出ます。
-
不発火 —
description: コードレビュー用のように短く抽象的だと、Claude 側がどの場面で発火させればよいか判断しきれず、せっかく作った Skill が呼ばれません - 誤発火 — 逆に範囲を広く書きすぎると、関係ない場面で発火し、他の Skill とぶつかったり、想定外の手順が走ったりします
長すぎる description も、重要なユースケースが後半に回って切り詰められると、肝心の発火トリガーが見えなくなるので避けたいところです。
どう向き合うか
自分が運用してみて効きがよかったのは、description に「何をするか」だけでなく「いつ使うべきか」「どんなキーワードで反応すべきか」まで明示する書き方でした。
---
description: |
PR の差分に対してセキュリティ観点のレビューをします。
認証・入力検証・秘密情報の取り扱い・SQL/コマンド組み立てを重点的に確認し、
指摘は重大度(high/medium/low)付きで返します。
when_to_use: |
「セキュリティレビュー」「脆弱性をチェック」「秘密情報の扱い」などの
キーワードや、PR/差分のレビュー依頼に反応します。
---
@kamome_susume さんの記事でも、Skills は「チームの暗黙知を形式知に変えるツール」と表現されていましたが、発火条件こそその暗黙知の中心にあると感じます。「いつ使うか」という判断は、慣れた人の頭の中にしかないことが多く、それを description に書き出す作業そのものが価値だと思います。
アンチパターン④:副作用の強いコマンドを記述しっぱなしにする
なぜ問題か(メカニズム)
Skills には、!`コマンド` で動的にコマンド出力を埋め込んだり、allowed-tools で許可ツールを広げたりする機能があります。これは強力な反面、書きっぱなしにしておくと事故の原因になります。
ここでのメカニズムは、第 1 部の「Skills は発火したときだけ動く」という性質と、「Claude がオートで発火を判断できる」という性質が組み合わさることにあります。つまり、副作用のある処理をオート発火可能な Skill に書いておくと、Claude が「コードが整ったように見えるから」と判断して、ユーザーの意図しないタイミングで外部に影響を与える操作を走らせてしまう 余地が生まれます。
特に気をつけたいのは次のようなパターンです。
-
git pushやgh pr mergeのような外部に影響を与えるコマンドを Skill 内に直書きしている -
allowed-toolsに Bash を広く許可してしまい、ユーザー承認なしで任意のコマンドを実行できる状態になっている - Claude がオートで発火できる Skill にデプロイ系の処理を含めている
どう向き合うか
公式ドキュメントでも、デプロイなどタイミングを制御したいワークフローには disable-model-invocation: true を設定し、ユーザーが /skill-name で明示的に呼び出すことが推奨されています。これは上記の「整ったように見えるからとデプロイ判断をしてしまう」状況を避けるための仕組みです。
自分も最初は手元のリポジトリで /commit Skill にオート発火を許してしまい、意図しないタイミングでコミットメッセージの草案実行が走ってしまったことがありました。それ以降は、副作用のあるものはすべてマニュアル発火に倒し、Skill の冒頭にも「このスキルは外部に影響を与えます」とコメントを残すようにしています。
副作用のある操作は、disable-model-invocation: true で発火を手動に限定したうえで、allowed-tools を最小限に絞る、という二段構えで設計しておくと安心しやすいです。読み取り系と書き込み系で Skill を分けるのも有効でした。
アンチパターン⑤:スキル間で重複する手順を共通化していない
なぜ問題か(メカニズム)
Skills が増えてくると、「テストを実行する」「Git の差分を確認する」「PR を作る」といった同じ手順が、複数の Skill にコピペで散らばっていきます。第 3 部のインセンティブの話そのもので、「今コピペしたほうが早い」という個人最適が積み重なった結果です。
このアンチパターンの実害は、単一情報源が失われること です。
- ある Skill だけ古い
pnpm testのままで、他はpnpm test --filterに更新されている - セキュリティチェック手順が Skill ごとに少しずつ異なる
- 1 箇所で運用ルールを変えても、他の Skill に伝播していない
手順が分散していると、ルールを変えるたびに「どの Skill を直せばいいか」が分からなくなり、直し漏れが必ず出ます。
どう向き合うか
@inari111 さんの記事で紹介されていた feature-dev のような Skill が魅力的なのは、リサーチ・計画・実装のフェーズが明確に分かれており、それぞれが共通の作法に従っているからだと思います。同じく @misakiito さんの 3 層構造(エントリーポイント/ルール/エージェント)も、共通ルールを 1 箇所に集める仕組みとして機能しています。
自分が試したのは、共通手順を ~/.claude/rules/ 配下に置き、各 Skill からは「このルールに従ってください」と参照する形でした。SKILL.md 自体は薄く保ちつつ、共通化したい知識は別ファイルに集約できるので、変更の影響範囲が見通しやすくなります。
your-app/
├── .claude/
│ ├── skills/
│ │ ├── review/SKILL.md
│ │ ├── release/SKILL.md
│ │ └── write-draft/SKILL.md
│ └── rules/
│ ├── test-command.md # テスト実行手順の単一情報源
│ ├── pr-template.md # PR テンプレート
│ └── security-checklist.md # セキュリティ観点の共通チェック
ただし、共通化を進めすぎると「どこを見ればその挙動の根拠が分かるか」が逆に分かりづらくなります。共通化と局所最適のバランスは、チームの規模と Skill 数に応じて判断したい部分です。
アンチパターン⑥:レビュー・テストの仕組みがない
なぜ問題か(メカニズム)
ふつうのアプリケーションコードであれば、CI でテストが走り、PR レビューでチェックが入るのが当たり前です。一方で、Skills は「Markdown だから」という気軽さもあって、レビューを通さずに直接 push されることが少なくありません。
ここでの実害は、これまで挙げてきたアンチパターン①〜⑤が 検知されないまま増殖すること です。description のちょっとした更新だけのつもりが、発火条件が変わって他の Skill とぶつかる、ということも起こります。レビューの仕組みがないと、肥大化も多責務も曖昧な発火条件も、誰のチェックも通らずに本番に入ってしまいます。Skills の負債が溜まる速度が速いのは、この「気軽さ」と「チェックの不在」の組み合わせが大きいと感じています。
どう向き合うか
@hiropon22 さんの記事では、「発見 → 判定・適用 → 無人運転」という 3 段階の自己改善ループが紹介されていて、その中で verify-diff/skill-review/publicity-review の 3 つの品質ゲートを直列に配置する設計が示されていました。13 日間で 40 件以上の自動修正コミットが生成されたとのことで、ここまで自動化するかは別として、考え方は強く参考になります。
自分のチームで取り入れているのは、もっとシンプルなレベルの話で、次の 3 点を運用ルールに入れた程度です。
- Skills の変更は通常のコードと同じく PR ベースでレビューする
- PR では
descriptionの差分を必ず確認する(発火範囲が変わるため) - 副作用のある Skill は、サンドボックス的なリポジトリで実行確認してからマージする
これだけでも、発火条件の意図せぬ変更や、副作用の強いコマンドの混入はかなり防げました。
リファクタの指針と参考実装の構造例
ここまでのアンチパターンを踏まえて、自分が今 Skills を見直すときに使っている指針を簡単にまとめます。いずれも「段階的開示を壊さない」という一本の線でつながっていると感じています。
-
薄く保つ:SKILL.md 本体は 200 行以下を目標に、詳細は
references/配下へ(段階的開示の維持) - 責務を切る:1 Skill 1 責務を基本にし、統制系と個別処理系を分ける(再利用可能性の確保)
-
発火条件を明示:
descriptionには「何を」「いつ」を両方書き、when_to_useを活用する(発火判定の精度) -
副作用を分離:書き込み系・外部影響系は
disable-model-invocation: true+ 最小allowed-tools(事故の予防) -
共通化する:手順・ルールは
rules/などに切り出し、Skills から参照(単一情報源) - レビューを回す:description 差分の確認と、副作用 Skill の実行確認をルール化(負債の検知)
参考までに、自分が落ち着いた構造例を載せておきます(プロジェクト名は汎用名に置き換えています)。
your-app/
├── .claude/
│ ├── skills/
│ │ ├── review/
│ │ │ ├── SKILL.md # 200 行以内
│ │ │ └── references/
│ │ │ ├── security.md
│ │ │ └── performance.md
│ │ ├── release/
│ │ │ ├── SKILL.md # disable-model-invocation: true
│ │ │ └── scripts/
│ │ │ └── changelog.sh
│ │ └── write-draft/SKILL.md
│ ├── rules/
│ │ ├── test-command.md
│ │ ├── pr-template.md
│ │ └── security-checklist.md
│ └── commands/ # 互換目的の旧コマンドを残す場合のみ
└── CLAUDE.md # 「事実」だけを置く
CLAUDE.md には「事実」を、Skills には「手順」を、rules/ には「共通の作法」を置く、というのが今のところしっくりきている分け方です。これは第 1 部で触れた「いつコンテキストに乗るか」の役割分担を、ディレクトリ構造に落とし込んだもの、と捉えています。
まとめ
Claude Code Skills は、運用してみると本当に開発の進め方を変えてくれるツールだと感じます。一方で、便利だからこそ、いつのまにか「動いてしまっているけれど中はぐちゃぐちゃ」という状態に陥りやすいのも事実です。
この記事で繰り返し戻ってきたのは、「段階的開示(progressive disclosure)」という設計思想 と、「個人の合理が全体の負債になる」というインセンティブのミスマッチ の二つでした。アンチパターンの多くは、前者の前提を壊すことから生まれ、後者の構造によって放置されます。逆に言えば、この二つを意識しておくと、個別の対策がバラバラの知識ではなく一本の線でつながって見えてくると思います。
本記事で取り上げたアンチパターンは、いずれも自分が踏んだ、あるいは社内で見かけた範囲のものです。すべての現場に当てはまるわけではないと思いますが、Skills を社内で増やしていく段階の方には、いくつかでも引っかかるところがあるのではと思います。
もしこの記事の中で「うちでもこのパターンはやってしまっていた」というものがあれば、まずは SKILL.md の行数と description の書き方から見直してみるのがおすすめです。
参考リンク
- 日々の開発で使っている Claude Code Skills(@inari111): https://zenn.dev/inari111/articles/4f9dc787b6c191
- スキルが毎日勝手に改善されていく仕組み(@hiropon22): https://zenn.dev/hiropon22/articles/claude-code-self-improving-loop
- 1 時間で開発を完了する Claude Code Skill(@misakiito): https://zenn.dev/misakiito/articles/e5fd7f54433d3d
- Codex が SKILL.md を 220 行で打ち切っていた話(@haru0416): https://zenn.dev/haru0416/articles/codex-skill-md-220-lines
- Claude Code の skills アイデア大全 20 選(@kamome_susume): https://qiita.com/kamome_susume/items/d8919d94f55d86e9881c
- Claude 公式 Skills ドキュメント: https://code.claude.com/docs/en/skills
- Anthropic: Equipping agents for the real world with Agent Skills: https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
- Anthropic: Effective context engineering for AI agents: https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents