Claude CodeのSkillsを確実に発動させる方法を色々試してみた
結論から言うと、CLAUDE.mdに書け
100%。
いや、マジで。色々試した結果、CLAUDE.md に直接書くのが一番確実という身も蓋もない結論になりました。「Skills」っていう仕組みがあるのに、それを発動させるために別の場所に設定書くって何なんだって話なんですけど、現状これが最も信頼できる方法です。
そもそもなんでこんなこと調べ始めたかというと、チームでClaude Code使い始めて、「TDDワークフロー強制するSkill作ったよ!」って意気揚々とSlackに投げたんですね。で、誰も発動しない。「動かないんだけど」「こっちも」「えっ何それ」。最初は使い方の問題だと思ってたんですけど、どうも違う。Skill自体が呼ばれてない。
Skills、そもそも何者か
Claude Codeには「Skills」という機構があって、.claude/skills/ 以下に定義ファイルを置くと、関連するタスクで自動的に発動する...はずなんです。公式のドキュメント読むと "autonomously decides when to use them based on your request" って書いてある。
.claude/
├── skills/
│ └── tdd-workflow/
│ └── skill.md
└── agents/
├── test-writer.md
└── implementer.md
こういう構成で、ユーザーが「テスト書いて」って言ったらtdd-workflowが起動して、サブエージェントが順番に動く。理想的には。
現実は違った。
最初にぶつかった壁:権限
{
"permissions": {
"allow": ["Skill"],
...
}
}
.claude/settings.json にこれ書かないと、そもそもSkillツールがブロックされます。知らなかった。デフォルトでブロックって、なんでそんな設計にしたんだろう(まあ、セキュリティ的には正しいのかも)。
確認は jq でできます:
jq '.permissions.allow' .claude/settings.json
"Skill" が入ってなかったら追加。これで「呼べる」ようにはなる。でも「呼ばれる」とは限らない。ここ大事。
発動率、体感25%くらい
権限通した後も、体感で4回に1回くらいしかSkillが発動しない。「TDDでお願い」って言っても普通に実装始めちゃう。Skillの存在自体を無視してる感じ。
Scottさんの検証によると、シンプルなhookだと20%、複数Skillを同時に使うタスクだと0%になることもあるらしい。0%て。
で、なんで発動しないのか。正直、完全にはわかってない。仮説としては:
- プロンプト解析の段階でSkillとの関連度が閾値を超えない
- 他のツールで解決可能と判断されてしまう
- Skill定義のキーワードマッチングが甘い
2番目が怪しいと思ってるんですよね。Claude Code、普通に賢いので「Skillなくてもできるじゃん」って判断しちゃう。親切設計が裏目に出てる。
Forced Eval Hook:84%まで上がる
Scottさんが紹介してた方法がこれ。UserPromptSubmit hookで強制的に評価させる。
まず .claude/hooks/skill-forced-eval-hook.sh を作成:
#!/bin/bash
# stdinを消費(hookの仕様)
cat > /dev/null
cat << 'EOF'
INSTRUCTION: MANDATORY SKILL ACTIVATION SEQUENCE
Step 1 - EVALUATE:
For each skill in <available_skills>, state: [skill-name] - YES/NO - [reason]
Step 2 - ACTIVATE:
IF any skills are YES → Use Skill(skill-name) tool for EACH relevant skill NOW
IF no skills are YES → State "No skills needed" and proceed
Step 3 - IMPLEMENT:
Only after Step 2 is complete, proceed with implementation.
CRITICAL: You MUST call Skill() tool in Step 2. Do NOT skip to implementation.
The evaluation is WORTHLESS unless you actually ACTIVATE the skills.
EOF
実行権限を付与:
chmod +x .claude/hooks/skill-forced-eval-hook.sh
.claude/settings.json に登録:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/skill-forced-eval-hook.sh",
"timeout": 5
}
]
}
]
}
}
やってることは単純で、毎回のプロンプト送信前に「Skill使うか判断しろ、YESなら呼べ」って指示を差し込む。WORTHLESSとかCRITICALとか強い言葉使ってるのは、それくらいしないと無視されるから。
これで84%。悪くない。でも100%じゃない。
なぜ100%にならないのか、もう少し考えてみた
16%の失敗、気になるじゃないですか。Scottさんの記事では深追いしてなかったので、手元で何パターンか試してみた。
仮説1:hookのタイミングが遅い
→ PreToolUse に変えても変わらず。却下。
仮説2:プロンプトが長いと指示が埋もれる
→ 短いプロンプトでも失敗するケースあり。完全な原因ではない。
仮説3:モデルの気分(確率的なブレ)
→ これが一番ありそう。同じプロンプトでも通ったり通らなかったりする。
結局、確率的なブレを0にはできない、という当たり前の結論に落ち着いた。84%は「かなり頑張った」数字なんだと思います。Anthropicの中の人に聞いてみたいところだけど、たぶん「仕様です」って言われそう。
で、CLAUDE.md
ここまで来て思ったんですよね。hookで84%、じゃあ残り16%どうするの?って。
試しにCLAUDE.mdに直接書いてみた:
## 開発ワークフロー
このプロジェクトではTDD駆動で開発します。
1. テストを先に書く(Red)
2. 最小限の実装(Green)
3. リファクタ(Refactor)
**必ずこの順序を守ること。実装から始めない。**
発動率、、
100%
いや、Skillじゃないじゃんこれ、って思うかもしれない。その通り。CLAUDE.mdに書いたルールは厳密には「Skill」ではなくて「プロジェクト指示」なんです。でも、やりたいこと(特定のワークフローを強制する)は達成できる。
(ってこれ書いてて思い出したんだけど、最初にCLAUDE.md試さなかったの、「せっかくSkillsって仕組みがあるんだから」っていう謎のこだわりだったんですよね。本末転倒だった。)
Skillsの本来の価値
じゃあSkillsいらないのか、というとそうでもなくて。
Skillsの強みは共有できることなんです。.claude/skills/ に置いたものは、そのプロジェクトをcloneした人全員が使える。チームで「このワークフロー使おう」ってなったとき、各自のCLAUDE.mdに書くより、Skills化して共有する方がメンテしやすい。
Alexさんの記事で紹介されてるTDDワークフロー、かなり作り込まれてて参考になります。フェーズごとにサブエージェント分けて、コンテキスト汚染防いでる。
Phase: RED → test-writer agent(テスト失敗確認まで)
Phase: GREEN → implementer agent(テスト通過まで)
Phase: REFACTOR → refactorer agent(テスト維持しながら改善)
こういう複雑なワークフローはSkillsで定義する価値ある。ただ、発動させる部分は別途工夫が必要、というのが現状。
まとめというか、現時点での結論
試した方法と発動率:
- 権限設定のみ:25%くらい(体感)
- Forced Eval Hook:84%(Scottさん検証)
- CLAUDE.md直書き:100%
確実に発動させたいなら、CLAUDE.mdに書く。複雑なワークフローで、かつチーム共有したいなら、Skills + Forced Eval Hookの組み合わせ。
正直、Skillsがもう少し賢く発動してくれれば...と思わなくもない。今のところ「自律判断」は当てにならないので、明示的に発動させる仕組みを自分で作るしかないです。知らんけど。
補足
Scottさんの検証では200回以上テストしてるらしい。真面目。手元では10回程度しか試してないので、84%という数字は参考値として見てください。
Discussion