「Skillsを作ったのに、Claudeが同じミスを繰り返す」「スキルが複雑になるにつれてコンテキストが膨れ上がる」——Skillsを実運用で使い続けると、こうした問題が必ず出てきます。
その理由はシンプルです。Skillsは設計図ではなく、使いながら育てるものだから。最初から完璧なスキルを作ろうとすると、実際には使わないルールで埋め尽くされた重いファイルができあがります。
この記事では、Skillsの基本的な作り方(Skills入門・Skills設計ガイド)を前提に、量産フェーズで失敗から学びながらSkillsを改善し続けるサイクルを体系的に解説します。NG/OKパターンの記録方法・役割分離・LLMが自己修正しやすい出力設計まで、実際に回し続けるための設計思想を紹介します。
なぜSkillsは一発完成を目指さない方がいいのか
多くの開発者がSkillsで最初にやりがちなのは、「考えられるすべてのルールを最初から網羅しよう」とすることです。しかし実際には、重要なルールのほとんどはClaudeが実際に間違えてから初めて分かるものです。
最初から書き込みすぎると起きる問題
- コンテキスト圧迫:使わないルールがコンテキストを食い、肝心の作業への集中度が下がる
- メンテナンス不能化:ルールが増えすぎると「どのルールが効いているか」が分からなくなる
- 適用過多:汎用的すぎるルールが、逆に正しい出力を阻害することがある
- 学習効果がない:なぜそのルールが必要か分からないまま追加しても、次のスキル設計に活かせない
Skills改善の3段階モデル
| フェーズ | 状態 | 目標 | やること |
|---|---|---|---|
| Phase 1:基盤 | 最初の数実行 | 動くことを確認 | コアフロー・命名規則・出力形式だけを定義 |
| Phase 2:知識抽出 | NG/OKが蓄積 | ミスの再発防止 | 繰り返す失敗パターンをNG/OKとして明示化。ドメイン固有ルールを独立スキルへ切り出し |
| Phase 3:委譲アーキテクチャ | コンテキスト限界 | 品質と速度の両立 | 役割分離・サブエージェント委譲・参照ファイルへの知識逃がし |
この3段階を1〜2週間のスパンで回していくと、量産フェーズで安定して機能するSkillsが育ちます。
NG/OKパターンの記録と埋め込み
Skillsを育てる上で最も効果的な改善は、Claudeが繰り返す失敗を「暗黙ルール」から「明文化されたパターン」に変換することです。
失敗パターンの記録方法
Claudeが同じ種類のミスを2回以上犯したら、そのミスをNG/OKパターンとしてSKILL.mdに追加します。記録の基準は以下の通りです。
- 同じ間違いが2回以上発生したもの(1回は偶発の可能性がある)
- エラーメッセージや出力で明確に「これが間違い」と判定できるもの
- 正しい書き方を具体的に示せるもの(NG→OK の対応が明確)
- 将来も同じパターンで失敗しそうなもの(ドメイン固有の知識が必要な箇所)
SKILL.mdへのNG/OK埋め込み形式
---
name: api-test-generator
description: Generates API integration test files. Use when creating tests for REST API endpoints. Handles authentication, request/response validation, and error scenarios.
allowed-tools: Read, Glob, Grep, Bash, Write
---
## NG/OK パターン(繰り返すミスの防止)
### 文字列比較
NG: `expr: response.body.status == "active"`
OK: `expr: response.body.status == 'active'`
理由: ダブルクォートはYAMLのキー構文と競合する。文字列値はシングルクォートで囲む。
### null チェック
NG: `expr: response.body.id != null`
OK: `expr: response.body.id != ""`
理由: null比較は型エラーになる。空文字列比較を使う。
### 認証ヘッダーの位置
NG: bind セクションの後に Authorization ヘッダーを記述
OK: bind セクションの前に Authorization ヘッダーを記述
理由: bind変数はヘッダー解決より後に処理されるため、変数が展開されない。
### エラーアサーション
NG: 複数条件を1つの test ブロックに詰め込む
`test: response.status == 400 && response.body.error != "" && response.body.code == "INVALID_INPUT"`
OK: 条件を個別の verify ステップに分割
```
- test: response.status == 400
- test: response.body.error != ""
- test: response.body.code == "INVALID_INPUT"
```
理由: 複合条件はどの条件で失敗したか判別が難しく、自己修正が困難になる。
## コアフロー
...(以下省略)
ドメイン固有知識を独立スキルに切り出す
特定のフォーマット・DSL・ライブラリ固有のルールが多くなってきたら、独立したスキルとして切り出します。これにより:
- メインスキルのフローが見やすくなる
- 独立スキル単体でのテスト・改善が可能になる
- 他のスキルからも再利用できる
# .claude/skills/runn-syntax/SKILL.md --- name: runn-syntax description: runn YAML syntax reference and validation. Use when generating or fixing runn test files. Checks for common syntax errors specific to runn's expression language. user-invocable: false allowed-tools: Read --- ## runn expr-lang チートシート ### 関数 - 文字列前方一致: `hasPrefix(str, "prefix")` ← NOT startsWith() - 文字列後方一致: `hasSuffix(str, "suffix")` ← NOT endsWith() - 文字列含有: `contains(str, "substr")` ### 変数参照 - レスポンスボディ: `response.body.fieldName` - ヘッダー: `response.headers["Content-Type"]` - bind変数: `vars.myVar` ### ステップ参照(前ステップの結果を使う) - 前ステップID: `steps.stepName.response.body.id` ...(詳細仕様)
役割分離:スキルとサブエージェントの責務を分ける
Skillsが複雑化してきたとき、最も効果的な改善は「考える作業」と「実行する作業」を分離することです。1つのスキルにすべてを詰め込もうとすると、コンテキストが膨れ上がり、Claudeの精度が低下します。
役割分離の3層構造
| 層 | 担当スキル/エージェント | 権限 | 役割 |
|---|---|---|---|
| 調査層 | 情報収集スキル | Read・Glob・Grep のみ | コードベース解析・仕様理解・テストケース設計 |
| 承認層 | 人間(ユーザー) | なし | 生成範囲の確認・優先度の判断 |
| 実行層 | 生成サブエージェント | Write・Edit・Bash | ファイル生成・実行・エラー自己修正 |
この分離により、実行層に書き込み権限を集中させ、調査層を読み取り専用に制限できます。万が一の暴走もWrite権限がないスキルでは大きな被害にならりません。
役割分離の実装例(APIテスト量産)
--- name: design-api-tests description: Analyzes API endpoint code and designs test cases (does NOT generate files). Use when planning what to test for a given API. Reviews source code, extracts validation logic, and outputs a test plan for user approval. agent: Explore context: fork allowed-tools: Read, Glob, Grep --- ## タスク 以下の手順でテスト設計を行う(ファイルは一切生成しない)。 ### Step 1: 情報収集 `$ARGUMENTS` で指定されたAPIエンドポイントに関連するコードを読む: - ルーターファイル(URL定義) - コントローラー(バリデーション・ビジネスロジック) - テスト対象モデル(フィールド定義・制約) - 既存テスト(命名パターン・カバレッジの確認) ### Step 2: テストケース洗い出し(ホワイトボックス視点) コードから以下の観点でテストケースを抽出: - 正常系(必須フィールドあり・オプションフィールドあり/なし) - バリデーションエラー(各フィールドの境界値・型違い・必須欠如) - 認証・認可(未認証・権限なし・他ユーザーのリソース) - エッジケース(空配列・最大文字数・特殊文字) ### Step 3: 承認を求める Markdownテーブルで生成予定のテストケース一覧を提示し、ユーザーの確認を求める。 確認が取れたら /generate-api-tests を呼び出す。
---
name: generate-api-tests
description: Generates runn API test YAML files from a pre-approved test plan. Use only after /design-api-tests has been approved by the user. Takes the test plan as input and produces test files.
user-invocable: false
allowed-tools: Read, Write, Bash
---
## タスク
引数として渡されたテスト計画に基づきAPIテストを生成する。
### 生成単位
**APIエンドポイント1つ = 1回の生成**。複数エンドポイントは個別に処理する。
理由: 一度に多くのコンテキストを持つと精度が下がり、エラー修正が難しくなる。
### 生成フロー
1. テスト計画を読み込む
2. /runn-syntax を参照してYAML記法を確認
3. テストファイルを生成
4. `runn run tests/api/target-endpoint.yaml --verbose` で実行
5. 失敗した場合:エラーメッセージを解析し、1件ずつ修正して再実行(最大3回)
6. 3回失敗した場合:エラー内容と試みた修正をサマリーとして報告
### 品質チェックリスト(生成後、ユーザーへ渡す前に必ず確認)
- [ ] すべてのテストケースが実行可能か(`runn run` が通るか)
- [ ] ファイル名が命名規則に従っているか(`test-{endpoint}-{scenario}.yaml`)
- [ ] アサーションが個別ステップに分割されているか(複合条件になっていないか)
- [ ] 認証ヘッダーが bind セクションより前に記述されているか
user-invocable: false に設定するのが安全です。必ず調査層→承認→実行層の順を守らせることができます。詳細はSkills設計ガイドを参照してください。LLMが自己修正しやすい出力設計
Skillsの改善において見落とされがちなのが、出力(生成物)の設計です。同じテストを書くにも、Claudeが失敗したときに「どこで何が間違いか」をすぐに判断できる形式にするか否かで、自己修正ループの効率が大きく変わります。
粒度設計:大きな条件を細かく分割する
最も重要な原則は「1ステップ1条件」です。複数の条件を1つに詰め込むと、エラー時にどの条件が失敗したか判別しにくくなります。
| 設計 | コード例 | 失敗時の可読性 |
|---|---|---|
| NG:複合条件 | status == 400 && error != "" && code == "INVALID" |
どの条件が失敗したか不明。エラーツリーが深くなる |
| OK:個別ステップ | 各条件を別行に分割 | ステップ名で失敗箇所が即座に判明。Claudeが自律デバッグ可能 |
# NG: 複合条件(どの条件で失敗したか分かりにくい)
- test: response.status == 400 && response.body.error != "" && response.body.code == "INVALID_INPUT"
# OK: 個別ステップに分割(ステップ名で失敗箇所が即座に判明)
- test:
title: ステータスコードが400であること
expr: response.status == 400
- test:
title: エラーメッセージが空でないこと
expr: response.body.error != ""
- test:
title: エラーコードがINVALID_INPUTであること
expr: response.body.code == "INVALID_INPUT"
エラー出力の自己修正フロー設計
サブエージェントに「生成 → 実行 → エラー修正」のループを組み込む場合、エラー修正の上限と報告形式を明示することが重要です。
--- name: generate-and-fix description: Generates code/test files and automatically fixes errors until tests pass. Use when you need a complete generate-test-fix cycle with automatic error correction. allowed-tools: Write, Edit, Bash --- ## 自己修正ループ 生成後、以下の手順で自動修正を試みる: 1. 生成したファイルを実行・検証 2. エラーが出た場合: a. エラーメッセージを1行ずつ解析 b. 該当箇所を特定(エラー出力に含まれるファイル名・行番号を参照) c. 最小限の変更で修正(関係ない箇所は触らない) d. 再実行 3. 修正を最大 **3回** 試みる 4. 3回で解決しない場合: - 試みた修正の一覧 - 最後のエラーメッセージ全文 - 想定される根本原因(1〜3候補) をサマリーとしてユーザーに報告し、処理を停止する ## 修正してはいけないもの - テストの期待値(仕様側の問題の可能性がある) - 認証情報・設定ファイル(スコープ外) - 3つ以上のファイルにまたがる変更が必要な場合(設計上の問題)
ファイル分割単位の最適化
「どれくらいの粒度でサブエージェントに委譲するか」は、コンテキスト管理の観点で重要な設計決定です。
| 分割単位 | 適する場面 | 問題が出やすい場面 |
|---|---|---|
| モジュール全体 | 小規模プロジェクト・関連性が高いファイル群 | 大規模プロジェクト。コンテキストが200K超になり精度低下 |
| ファイル単位 | 中規模。1ファイル1責務が明確な設計 | ファイル間の依存が強い場合。前後の文脈が切れる |
| エンドポイント/関数単位 | APIテスト量産・コード生成の量産 | ほとんどの量産シナリオに適合する。推奨 |
| テストケース単位 | 非常に複雑な単一テスト | オーバーヘッドが大きすぎる |
一般的なガイドラインとして、1サブエージェントが扱うコンテキストは50K tokens以内に収めると精度が安定します。Subagentsの詳細も参照してください。
参照ファイルへの知識逃がし:SKILL.md 500行の壁
Claude Code の公式ドキュメントでは SKILL.md は500行以内を推奨しています。これを超えるとコンテキスト効率が低下し、Claudeがすべての指示を正確に処理できなくなります。
情報の種類別に保管場所を分ける
| 情報の種類 | 保管場所 | 理由 |
|---|---|---|
| プロセスフロー・手順 | SKILL.md 本文 | Claudeが実行する「手順書」。常に参照する |
| NG/OKパターン(〜10項目) | SKILL.md 先頭 | 実行前に確認させるため先頭に置く |
| NG/OKパターン(11項目〜) | 参照ファイル(reference.md等) | SKILL.mdの肥大化を防ぐ |
| 出力テンプレート | 参照ファイル(template.yaml等) | 変更頻度が高く、スキルフローと分離すると管理しやすい |
| 品質チェックリスト | SKILL.md 末尾 または 参照ファイル | スキル末尾に置いて自己レビューを強制 |
| DSL仕様・APIリファレンス | 専用スキル または 参照ファイル | 他のスキルとも共有できる |
| 処理スクリプト | scripts/ ディレクトリ | バイナリや処理はスクリプトへ。SKILL.mdは指示書 |
ディレクトリ構成の推奨パターン
.claude/
└── skills/
├── api-test-generator/
│ ├── SKILL.md # プロセスフロー(500行以内)
│ ├── ng-ok-patterns.md # NG/OKパターン詳細(10項目超の場合)
│ ├── test-template.yaml # 出力テンプレート
│ ├── checklist.md # 品質チェックリスト
│ └── scripts/
│ └── validate-yaml.sh # 実行スクリプト
├── runn-syntax/
│ └── SKILL.md # DSL専門スキル(他スキルから参照)
└── design-api-tests/
└── SKILL.md # 役割分離:調査専門スキル
参照ファイルを呼び出す記法
SKILL.md から参照ファイルを読ませるには、SKILL.md内にファイルパスを明示して Read ツールで読むよう指示するのが確実です。パスはリポジトリルートからの相対パスで指定します。
## SKILL.md 内での参照例 ### テンプレートの使用 出力形式は `.claude/skills/スキル名/test-template.yaml` を参照すること。 テンプレートのフォーマットから外れないよう注意する。 ### NG/OKパターンの参照 詳細なNG/OKパターンは `.claude/skills/スキル名/ng-ok-patterns.md` を参照すること。 特にSection 3(アサーション記法)は毎回確認すること。 ### DSL仕様の確認 記法に迷った場合は /runn-syntax を呼び出して確認すること。
品質チェックリストの埋め込み
「自律的に品質を担保するスキル」を作る上で、チェックリストの埋め込みは効果的な手法です。Claudeは明示的にチェックリストが提示されると、それを実行して結果を報告しようとします。
チェックリストの設計原則
- 具体的で測定可能:「コードが綺麗か」ではなく「lint が0 warningで通過するか」
- 自律確認可能:ツールで実行できる確認項目(Bashコマンドで検証できるもの)
- 人間に返すもの:自律確認できないものは「ユーザーへの確認依頼」として分類
- 15項目以内:多すぎると読み飛ばされる
## 完了前チェックリスト(Claudeが自律実行)
### 形式チェック(ツールで確認)
- [ ] `runn syntax tests/api/*.yaml` が全ファイルでパスするか
- [ ] ファイル名が `test-{endpoint}-{scenario}.yaml` 形式か
- [ ] すべてのテストに `title` フィールドがあるか
### 内容チェック(コードを読んで確認)
- [ ] テストケース設計で承認されたすべてのケースが含まれているか
- [ ] 正常系・バリデーションエラー・認証エラーの3系統が揃っているか
- [ ] アサーションが個別ステップに分割されているか(複合条件 && が残っていないか)
### ユーザーへの確認依頼
- [ ] 仕様不明な項目がある場合は、生成前にリストアップしてユーザーに確認
- [ ] テスト実行に必要な環境変数(API_KEY等)が不明な場合は確認
チェックリストの実行を強制するプロンプト文言
単にチェックリストを置くだけでは読み飛ばされることがあります。以下の文言で実行を強制します。
## ⚠ 重要:完了前チェックリスト **ユーザーへ結果を渡す前に、必ず以下のチェックリストをすべて実行すること。** **チェック結果を「✅ 通過 / ❌ 失敗: 理由」の形式で報告すること。** - [ ] lint チェック: `npm run lint` でエラーがないか - [ ] 型チェック: `npm run type-check` でエラーがないか - [ ] テスト実行: `npm test` でfailureがないか
Skillsの改善サイクルを回す実践
1セッションの振り返り:何を記録するか
量産セッションが終わったら、以下の観点で振り返りを行い、次のSkillsに活かします。
| 観点 | 記録すること | 反映先 |
|---|---|---|
| NG/OKパターン | 同じ種類のミスが2回以上あったか | SKILL.md の先頭セクション |
| コンテキスト消費 | 200K tokenに近づいたか・精度が下がった箇所 | サブエージェント委譲・参照ファイルへの移動 |
| 手動介入した箇所 | Claudeの自律処理では解決できなかった問題 | SKILL.mdへのルール追加 または 役割分離 |
| 品質チェックリスト | 見落とされたチェック項目があったか | チェックリストの追加・強制文言の強化 |
| 処理時間 | 各フェーズで予想より長くかかった箇所 | 分割単位の見直し・サブエージェント並列化 |
/retro コマンドで振り返りを自動化する
CLAUDE.md に振り返り用のコマンドを定義しておくと、セッション終了時の改善アクションを体系化できます。
# /retro コマンド セッション終了時に以下の振り返りを行い、改善PRを作成する: ## 振り返りの観点 1. **NG/OKパターン**: 今回のセッションでClaudeが繰り返したミスをリストアップ 2. **コンテキスト効率**: 200K tokenに近づいた場面と原因 3. **手動介入箇所**: ユーザーが手動で修正した箇所とその理由 4. **未使用ルール**: SKILL.mdに書いたが今回一度も適用されなかったルール ## アクション - NG/OKパターン → 対象SKILL.mdの先頭セクションに追加 - コンテキスト肥大化 → 参照ファイルへの切り出し or サブエージェント委譲の検討 - 手動介入箇所 → SKILL.mdへのルール追加 or 役割分離の検討 - 未使用ルール → SKILL.mdから削除(シンプルに保つ) 振り返り結果をMarkdownで出力し、該当するSKILL.mdへの変更をPRとして作成する。
Skillsのライフサイクル管理
定期的な棚卸しも重要です。Skills設計ガイドでも解説していますが、以下のサインが見えたら見直しのタイミングです。
- SKILL.mdが500行を超えた → 参照ファイルへの切り出し or スキル分割
- 同じ内容のNG/OKが10項目超 → 独立スキルへの昇格を検討
- 3回以上手動修正が必要になる → コア設計の見直し(スキルの粒度が大きすぎる可能性)
- 毎回最初の数ターンで混乱が起きる → descriptionの改善 or 前提情報の明示
- 1ヶ月以上使われていないスキル → アーカイブ or 削除
量産フェーズへの移行:安定したら並列化する
Phase 3まで来てSkillsが安定したら、並列化による量産が可能になります。ワークフローガイドも参照してください。
並列委譲のパターン
Claude Code の /batch コマンドや複数サブエージェントへの並列委譲を使うと、同じスキルを複数エンドポイント・複数ファイルに対して並列実行できます。
# CLAUDE.md または プロンプト
以下の各エンドポイントに対して /generate-api-tests を並列で実行する:
- POST /api/users(ユーザー作成)
- PUT /api/users/{id}(ユーザー更新)
- DELETE /api/users/{id}(ユーザー削除)
- GET /api/users/{id}/permissions(権限取得)
各エンドポイントの処理は独立しているため、context: fork を使って並列実行すること。
量産品質の維持:バッチ後チェック
量産後は個別ファイルの確認に加えて、バッチ全体の統計的なチェックを行うと問題の早期発見につながります。
#!/bin/bash
# 生成したテストファイルの統計チェック
TESTS_DIR="tests/api"
echo "=== 生成ファイル統計 ==="
echo "総ファイル数: $(find $TESTS_DIR -name "*.yaml" | wc -l)"
TOTAL=$(find $TESTS_DIR -name "*.yaml" -exec wc -l {} + | tail -1 | awk '{print $1}')
COUNT=$(find $TESTS_DIR -name "*.yaml" | wc -l)
echo "平均行数: $(( TOTAL / COUNT ))"
echo ""
echo "=== 複合条件チェック(NG パターン検出)==="
grep -rn "&&\|test:.*==" $TESTS_DIR --include="*.yaml" | head -10
echo ""
echo "=== 認証ヘッダー位置チェック ==="
# bindの後にAuthorizationがある場合を検出
python3 scripts/check-auth-order.py $TESTS_DIR
よくある失敗パターンと対処法
スキルが徐々に劣化する
症状:最初は動いていたスキルが、時間が経つにつれてミスが増える。
原因:プロジェクトのコードが変化したのに SKILL.md が更新されていない。NG/OKパターンが増えすぎてコンテキストを圧迫している。
対処:月1回の棚卸しを習慣化。NG/OKパターンが10項目を超えたら参照ファイルに移す。未使用ルールを定期的に削除する。
サブエージェントがメインスキルの知識を引き継がない
症状:メインスキルでは正しく動くが、サブエージェントに委譲すると同じNG/OKパターンを無視する。
原因:context: fork で分離されたサブエージェントは、メイン会話のコンテキストを引き継ぎません。
対処:サブエージェントに使わせたいスキルは、サブエージェント定義の skills フィールドに明示的に列挙する。または SKILL.md 内で参照ファイルへの読み込みを指示する。
自己修正ループが収束しない
症状:生成 → エラー → 修正 → 同じエラー、のループに入る。
原因:エラーの根本原因がスキルの知識範囲外にある(環境設定・依存関係・スペック変更など)。または修正上限が設定されていない。
対処:自己修正は最大3回と明示的に上限を設ける。3回で解決しない場合は「試みた修正内容とエラー全文をユーザーに報告して停止」を SKILL.md に記述する。
よくある質問
まとめ
Claude Code Skills の改善サイクルを機能させる要点をまとめます。
| 要素 | ポイント |
|---|---|
| 最初から完璧を目指さない | Phase 1は最小構成で動くことを確認。重要なルールは量産の中で発見する |
| NG/OKパターンの蓄積 | 同じミスが2回以上出たら即座にSKILL.mdへ記録。暗黙知を明文化する |
| 役割分離 | 調査・承認・実行を分ける。書き込み権限は実行層のみ。user-invocable: false を活用 |
| LLMが自己修正しやすい出力設計 | 1ステップ1条件。自己修正ループは最大3回。根本原因不明なら報告して停止 |
| 参照ファイルへの知識逃がし | SKILL.mdは500行以内。テンプレート・詳細ルール・チェックリストは別ファイルへ |
| 定期的な棚卸し | 未使用ルールは削除。500行超えたら分割。/retro で振り返りを自動化 |
Skills の改善は一度完成させたら終わりではなく、プロジェクトとともに育て続けるものです。この記事で紹介した改善サイクルを回すことで、量産フェーズでも安定して機能するスキルが育ちます。Skills入門・Skills設計ガイドと合わせて参照してください。

