Skills関連の記事を書いてくれている方々に、まず感謝を。
特に@nogatakaさんの「Claude Code Skills 完全活用ガイド 2026」には大変お世話になった。6つの設計パターンに分類してもらえたおかげで、自分がやっていることを俯瞰する視点を持てた。あの記事がなければ、この記事は書けていない。
自分はClaude Code Skillsを15本書いて、半月ほど毎日回している。朝に起動し、日中に何度かチェックし、夜に閉じる——その繰り返しだ。
この記事はパターンの分類ではなく、運用の記録として書く。半月で何にハマり、何を直し、今どう動いているか。Skillsの設計判断を、Before/Afterの実例で並べていく。
前提:自分の環境
15本のSkillが入っている。ざっくり分けるとこんな感じ。
- 日次サイクル系(3本):朝のブリーフィング・日中のチェックポイント・夜の終了処理
- 情報取り込み系(3本):メモ保存・音声メモ取り込み・メール返信
- コンテンツ系(2本):記事執筆・リサーチ
- 点検系(3本):監査・サイクル点検・パフォーマンス改善
- その他(4本):インテリジェンス収集・1on1支援・セッション再開・IME修復
MCP接続は、Google Calendar・Gmail・チャットツール・Google Drive・GitHub等。Skillsの中でMCPのデータを使う場面が多い。
ハマり1:Skill同士がファイルで会話している
最初に気づいたのが、Skillが孤立していると運用が回らないということだった。
朝のSkillでその日のタスクを宣言する。日中のSkillでタスクの進捗を確認する。夜のSkillで振り返りを保存する。3本は独立した別々のSkillだが、同じタスクリストを参照している。
最初は各Skillが独自のフォーマットでタスクを扱っていた。朝は「今日やること」リスト、日中は「進捗メモ」、夜は「振り返り」。当然、噛み合わない。朝に宣言したのと微妙に違うタスク名で日中に確認が走る。
Before:
/morning → 「今日やること」を独自フォーマットで出力
/hello → ステータスファイルを読むが、朝の宣言とは別の粒度
/goodnight → 何をやったか記憶ベースで書く
After:
/morning → ステータスファイル(各メンバーのステータス.md)を読んで宣言
/hello → 同じステータスファイルを読み直して差分確認
/goodnight → 同じステータスファイルを最新化
学び:複数のSkillが同じデータを参照するなら、データソースを1つに絞る。
ステータスファイルという共通のフォーマットに統一したことで、3本のSkillが自然に連鎖するようになった。Skill同士は直接通信しないが、ファイルを介して間接的に会話している。
さらにもう一段。日中のSkillに「改善候補の抽出」ステップを入れ、夜のSkillがそれを「設計」に落とし、翌朝のSkillが「実装」する——という3段階の改善サイクルが回るようになった。
/hello(日中) → 改善候補を3カテゴリに抽出
↓ ファイルに保存
/goodnight(夜)→ 改善候補を実装可能な設計に落とす
↓ 「明日の改善設計.md」として保存
/morning(翌朝)→ 設計ファイルを読んで3並列で実装
Skill自身がSkillの設計を改善する。このサイクルが回り始めてから、SKILL.mdの品質が勝手に上がるようになった。
ハマりポイント:ファイルパスの変更
受け渡しファイルのパスを1箇所変えたら、3本のSkillが全部壊れた。「ファイル名くらい変えていいだろう」と思ったのが甘かった。
対策は愚直で、受け渡しファイルのパスを全Skillに直書きしている。DRYの原則には反するが、SKILL.mdの文脈ではDRYよりも読んだだけで全体像がわかることのほうが重要だった。
ハマり2:MCP未接続でSkillが丸ごと止まる
朝のSkillでは、Google Calendar・Gmail・チャットツール等のMCPからデータを取得している。ある朝、チャットツールのMCPだけが接続できなかった。
Skillはチャットツール取得のステップで止まり、その後のカレンダー確認もメール確認も実行されなかった。1つのMCPが落ちただけで、朝のブリーフィング全体が機能しない。
Before:
1. Google Calendar MCPで今日の予定を取得
2. Gmail MCPで未読メールを確認
3. チャットツールAPIで新着メッセージを取得
4. 以上をまとめてブリーフィングを出力
After:
1. Google Calendar MCPで今日の予定を取得
2. Gmail MCPで未読メールを確認
3. チャットツールAPIで新着メッセージを取得
4. 以上をまとめてブリーフィングを出力
MCP未接続の場合は「未接続のため確認できません」と明記し、
取得できる情報だけで報告する。
たった2行の追加。だがこれで、MCPが1つ落ちてもSkillが止まらなくなった。
学び:MCP連携するSkillには、必ずフォールバックの指示を書く。 LLMは「取得できなかったらスキップして続ける」と明示しないと、エラーで止まるか、取得を何度もリトライしようとする。
ハマり3:LLMがいちいち聞いてくる
メモ保存のSkillを作った。「メモして」と言ったら、直前の会話から重要なことを抜き出して保存する——つもりだった。
実際には、毎回「何をメモしますか?」と聞き返してきた。
「メモして」の一言には「何を」が含まれていない。LLMとしては当然の確認だが、ユーザーとしてはストレスだ。文脈を読めばわかるはずだ、と思う。
Before(SKILL.mdの指示):
ユーザーの発言内容をメモファイルに保存する。
After:
**「何をメモしますか?」とは絶対に聞かない。**
直前の会話を遡り、以下の基準で「大事なこと」を抽出する:
- 方針・ルールが決まった内容
- 好み・価値観が明確になった内容
- 新しい事実・情報が確定した内容
**禁止**: 「何をメモしますか?」「どの内容をメモしましょうか?」等、
ユーザーに内容を言わせる質問
学び:LLMに推論させたいなら、「推論しろ」より「聞くな」のほうが効く。 肯定的な指示(「文脈から判断して」)だけだと、LLMは保険をかけて確認してくる。禁止(「聞くな」)まで書いて初めて、推論が安定した。
ハマり4:SKILL.mdが90行を超えて挙動が怪しくなった
朝のSkillに機能を足し続けた結果、SKILL.mdが90行を超えた。すると後半のステップが飛ばされることが増えた。
考えてみれば当然だ。SKILL.mdの内容はコンテキストウィンドウに載る。長すぎれば後半の指示が弱くなる。nogatakaさんも「アンチパターン1: SKILL.mdの肥大化」として指摘していて、まさにそれを踏んだ形だ。
ただ、自分の場合は分割が難しかった。朝のブリーフィングは「カレンダー→メール→チャット→タスク確認→改善実装→レポート出力」まで一気に走る必要がある。途中で別Skillに分けると、前半の取得結果が後半のコンテキストに載らない。
現状の対策:
- 各ステップの説明を1〜2行に圧縮する
- 詳細な手順はステップ番号と箇条書きで構造化する
- 「省略不可」のステップにはその旨を明記する
完全な解決にはなっていない。正直、まだ課題だと思っている。
ハマり5:descriptionを曖昧に書いて自動トリガーが暴発した
これもnogatakaさんが「アンチパターン2: descriptionの曖昧さ」として書いていること。そのまま踏んだ。
メモ保存Skillのdescriptionを最初こう書いていた。
description: メモを保存する
すると、ユーザーが「このメモを読んで」と言っただけでSkillが起動する。「メモ」というキーワードに反応してしまう。保存したいんじゃなくて読みたいだけなのに。
After:
description: つぶやき・メモをObsidianに保存する。
「メモ」「つぶやき」「記録して」等で自動トリガー。
具体的な動詞(保存する)と、トリガーキーワードの例示を入れたことで、誤発火が減った。
学び:descriptionはトリガー精度を決める。動詞と対象を具体的に。 nogatakaさんの「具体的な状況を書く」というアドバイスは正しい。
ハマり6:サブエージェントが同じファイルを読みに行く
監査Skillで3本のサブエージェントを並行起動している。メンバー状態・プロジェクト・自動化の3領域を分担する設計だ。
最初、担当領域の指定が甘かった。「プロジェクトを確認してください」くらいの指示で投げたら、3本とも同じステータスファイルを読みに行った。並列の意味がない。
Before:
### サブエージェント B: プロジェクト監査
プロジェクトの状態を確認する。
After:
### サブエージェント B: プロジェクト・戦略監査
担当領域:
- `projects/` 以下の全プロジェクトフォルダ
- CLAUDE.mdのファイルマップ
- `tasks/lessons.md`(全行)
チェック項目:
- 各プロジェクトの「次のステップ」が3週間以上動いていないもの
- ファイルマップに記載されているが実在しないパス
- lessons.mdのパターンが繰り返された回数
学び:サブエージェントには「担当領域」と「チェック項目」の両方を明示する。 「何を見るか」だけでなく「どこを見るか」まで書かないと、領域が重複する。
ハマり7:Skillが「完璧には動かない」ことを受け入れる
夜の終了Skillに「0:00を過ぎたら自動で発動する」というルールを入れている。
夜中の0:00を過ぎたら、ユーザーが終了を宣言しなくても
セッション終了プロトコルを強制発動する
正直、完璧には動かない。LLMは常に時計を見ているわけではない。0:00を5分過ぎてから気づくこともあれば、会話の流れによっては10分遅れることもある。
でも、これでいい。
ユーザーが止め忘れてもSkillが動く、というセーフティネットとして機能すれば十分だ。crontabのような正確さは期待していない。
学び:SKILL.mdに書く条件分岐は「ベストエフォート」だと割り切る。 LLMは確率的に動く。100%の実行保証がほしければ、外部スケジューラ(launchd、n8n等)を使うべきだ。SkillsとCLAUDE.mdだけでカバーできる範囲を見極めて、そこから外れるものは外部に任せる。
やってみてわかったこと
半月で15本回して見えた設計原則を、3つにまとめる。
1. Skillsは「点」ではなく「線」で設計する
1本のSkillを磨き込むより、複数のSkillが日次サイクルとして連鎖する設計のほうが運用効果が高い。朝→日中→夜のサイクルで同じデータソースを参照し、改善候補を受け渡す。Skill単体の品質より、Skill間の接続の品質が重要だった。
2. 「禁止」は「推奨」より強い
LLMに「こうしてほしい」と書くより、「これはするな」と書くほうが制御が効く。「文脈から推論せよ」より「聞くな」。「簡潔に書け」より「3行を超えるな」。禁止は明確で、LLMが迷わない。
3. フォールバックを書かないSkillは本番で壊れる
MCP未接続、ファイル不在、外部API障害——本番で起きることをSKILL.mdに書いておく。「正常系だけ書いて動かす」フェーズは3日で終わった。異常系の指示を足してからが本当のスタートだった。
おわりに
nogatakaさんの記事に出会えたことで、自分のやっていることに名前がついた。パイプライン型、サブエージェント分離型——ああ、そういう分類ができるのか、と。
名前がつくと、人に説明できるようになる。説明できると、改善点が見える。
自分が書いた「ハマり」の記録が、これからSkillsを触る人の参考になればうれしい。パターン分類は先人たちの記事に譲って、自分は泥臭い運用ログを書き続けようと思う。