スキルの舵の取り方法
このページの目的
正直、いまいちスキルの調整がわかっていないので何が必要なのかを公式ドキュメントに沿って理解する
調整するうえで前準備
実施した結果をもとにスキルの調整内容を抜粋する方法
- 効果があった手順をスキルにする
- 例えば、Aの作業をした後にBの手順を参照し、Cのような結果になるようDを作成してください。という結果がうまくいったのであれば、その内容をそのままスキルとして手順化する
- エージェントとの対話の中でうまくいった修正方針を追記する
- エージェントの出力結果に対して、修正・補足・訂正等の行った内容をスキルに埋め込む
- 以下のような例の文言をSKILLの資料としてreference等に記載する
- Aをする場合は、コーディング規約に沿って修正してください
- Bを確認する場合は、MCPを使用しサーバ内にある資料を参照してください
- 以下のような例の文言をSKILLの資料としてreference等に記載する
- エージェントの出力結果に対して、修正・補足・訂正等の行った内容をスキルに埋め込む
- 入力と出力結果の相対内容
- 入力データに対する出力結果の形式例
- 作業特有の慣例・事実
- エージェントが知りえない情報をreferenceやMCPなどを使用して補完できるようにする
既存のプロジェクト成果物からスキルの調整内容を抜粋する方法
0から1を作り出すことが難しいように、何も知らないエージェントが突然作れ・修正しろと言われても、何が何だかわからない状態となってしまう
そのような状態を避けるようにするため、既存の資料をエージェントに渡すことでどういった内容なのか、どのようなことをしていいのかなどのバックボーンを読み取り、より自由により幅広く動くことができるようになります
- 例
- 社内文書などのドキュメント
- API仕様・スキーマ・設定ファイルなど
- 過去事例
実践を通して調整するにあたって
実際にスキルを走らせ実行結果をもとに調整するにあたって必要なことがあります。
それは、実行して成功した内容だけをもとに調整するのではなく、失敗した内容から何が問題だったのか、何が足りなかったのかなどを確認して調整する必要があります。
実行と修正を行うだけで品質が向上し、効果が得られます。
また、調整するために確認する内容は最終的な出力内容だけではなく、エージェントが実行する途中結果や実行トレースも参照すべきです。
- 非生産性の部分について
- 指示があいまいで分かっていない部分がある:『Aの内容を結果としてまとめてください』だとエージェント自身が一から考えてしまい、『フォーマットに沿わない』・『求めていない観点でもの考察・推論がある』といった望まない結果になってしまう
- エージェントが指示に適さない行動をする:分析・考察・推論をより深くしてほしいのに、明確な指示がないため、早めに切り上げ結果として出力されてしまう
- スキルを使用時に指定するオプションのデフォルト値が指定されていない:スキルにはどのような値が必要かなどを記載することができるが
- description:value=<default:1>のようにデフォルト値を指定していない場合スキルがどのような値を必要としているかがわからなくなり、余計なトークンを使用してしまう
賢くトークンを利用しよう
SKILL.mdに記載された内容はスキルが起動されるタイミングで内容すべてが読み込まれます。
そのため複雑な内容であったり、スキルとしてのインターフェース以外の要素を組み込むとトークンを余計に消費してしまうため注意が必要である。
どうでもいい一般的な情報は、除外しよう
どういうことなのか
エージェントは、一般的な情報であれば知識として知っています。
なので、Aはアルファベットの一番目である。ギリシャ文字のアルファを由来とする・・・といったように不要な内容を記載するとトークンを余分に使用してしまう。
下記は、Claudeに生成してもらって比較例である。
このように余計な情報を記載してしまうと余分にトークンが消費されてしまう。
このトークン使用料は、天使の取り分のようにセッションが変わるごとに消費されてしまうため注意が必要である。
| パターンA | パターンB |
|---|---|
![]() |
![]() |
結論:知らないものだけ書くのが正解
そのためスキルに、必要なものはLLMが知りえないプロジェクトの固有の情報・プロジェクト内での特殊ケース・使用すべきツールやAPIなどスキルのみである。
もし、スキルを使用しても内容がスキルを使用しない状態と同じであれば、何も追加情報を渡せていないこととなるので注意が必要
スキルごとに一貫して処理できるようにしよう!
たとえば、オブジェクト指向のようにAという処理に特化したメソッド(DBを参照し出力する)、Bという処理に特化したメソッド(データを渡してDBを更新する)といったようにスキル自体も一貫性のある形にすることによって、出力内容の一貫性を保つことできます。
また、範囲を広く持ちすぎると複雑になりすぎて、思い通りに動作しなかったり、範囲が逆に狭すぎると単一の動作しかできないようになってしまうので注意が必要である
適度な道順を示す
A -> Dを求める場合、A->B->C->Dという経路になる。
しかし、A->B,B->C,C->Dへの経路のようにたどらなければいけないのにA->Dを導き出してと言われても難しいといえる。
この際に、過去事例や実装方法について明確にしつつ、A->B,B->Cへの導き方(具体例や実装例)といったように書く道順を示しつつ、関連した情報をスキルの関連ファイルに記載することによって非生産性な経路(A->Z)といったユーザが望まない結果になる可能性を低くすることができます。
大規模スキルの細分的情報開示
SKILL.mdは、スキル自体の要約であり500行以下かつ読み込みに必要なトークンが5000以下になるようしなければならない。
そのため、重要な情報であっても情報すべてを必ずSKILL.mdに書かなければならないというわけではない。
対象スキルのフォルダ配下にreferencesフォルダを用意し、SKILL.md内でどういうパターンは、references/hogehoge.mdを参照することといったように記載することで、必要に応じて読み込みつつSKILL.md自体の読み込みコストを抑えることができます
キャリブレーション制御
作業の難易度による難易度の制御
余裕を持たせた設計も有効打
例えば、求める出力結果が厳格でない場合、遊びを持たせることができます。
その遊びは、AIにとっての状況対応力の幅につながるため具体的な指示をしなくとも探りを入れつつ、自動駆動することができます。
### コードレビューについて
以下の観点を踏まえ問題がなければ、OKとしてください
1. 脆弱性のあるような書き方をしていないこと
2. 共通化できるものを処理に加えていないこと
3. エラーメッセージに内部情報が出力されていないこと
ただし、先ほど述べたように厳格な出力結果を求めるパターンや特定の指示が必須といったパターンの場合具体的に指示を与える必要があります。
ファイルのバージョンアップについて
以下を使用してバージョンアップ処理をしてください。
それ以外を使用してのバージョンアップはしないでください
```bash
python scripts/versionUp.py
```*
ツールの選択肢はなるべく控えめに
エージェントが処理を実行するうえで記載すべきものと控えるべきである。
Aを実施するにあたっては、B、C、Dを使用して行うことができます
↑何を使えばいいのかが明確でない(アンチパターン)
↓代替案を提示する程度
Aを実施するにあたってはBを使用することができます。
ただし、特定のパターンではDを選択すべきです。
答えではなく答えの導き方を教えることも重要
例えば、Aの時はBをするといったように汎用的ではないものを記載したとしても、AからBの対処法しかわからずCが出たときは対処できない状態になりかねない。
なので、下記のようにAをBに変更するための手順・手続き方法を記載するのが大切
(アンチパターン)
### 問題が発生した場合の対処法
Aデータに関する処理が発生した場合は、Bの処理を実装すれば解決します。
### 問題が発生した場合の対処法
1. `references/hogehoge.md`を参照し、対応するデータの対応例を取得する
2. 本リポジトリ内に存在する類似例を探し、実装を行う
3. もしなければ、新規で実装を行い`references/hogehoge.cls`ファイルに追加する
4. ・・・
効果的な指示の方法
スキルを記載するためには有効な手法もあるが、スキルに記載するには取捨選択が必須である
落とし穴を教える方法
人間もAIもあらかじめ想定・見えている落とし穴について教えてもらった方が、対処がしやすいものです。
例えば、コードを書き換えている際にエラーが発生した場合は、「そのエラーに対する適切な対処法」といったAIエージェントが間違えることを想定した修正方法を記載する方法である。
エージェントが一度間違えたことを落とし穴として追加することでよりミスを減らすことができる反復的かつ直接的な対処法になるので覚えときましょう!
references/内にそれら用の特化したファイルを用意し、問題が発生したタイミングで呼び出すといったことも有効かつ簡潔に記載することができる手順である。
ただし、読み込みに関するトリガーをエージェントが理解できない等の可能性が発生するので注意が必要である。
- 外部APIを参照する場合は、外部APIから200が返ってくることを確認してください。もし200が返ってこない場合は、サーバが正常動作しているか生きているかを確認するために`/health`を使用してください
- DB上で使用されている`user_id`は、システム上`Uid`として使用されています。
- 外部APIへのレスポンスでは`user_id`は、暗号化する必要があるため`MD5`をかけるロジックが必須となっています。
- DB内のデータを参照する場合、USERS.DELETEDがNULLである場合は削除されていないことを指すので注意が必要である
出力フォーマットの提示
例えば、どのような形式で出力してほしいのかを記されなければ都度違うフォーマットになってしまう。
それを修正・指摘するのはトークンの無駄遣いにつながり、非生産的である。
フォーマットの形式を文章として記載することもよいが、形式が定まっているのであれば具体的なフォーマットを文章ではなくテンプレートとして記載することがよいこともある。
理由としては、エージェントがパターンマッチングなどでより理解できるからである。
また、フォーマットはSKILL.mdもしくは、assets/にフォーマット自体をインライン形式で記載することができる。
## 調査結果の出力フォーマットについて
必要に応じて分析結果を以下のフォーマットで出力してください
```markdown
# [分析結果のタイトル]
## 結論
[列挙型で見つかったKeyを表示]
## Keyの一覧
- 見つかったKey1と履歴
- 見つかったKey2と履歴
## Keyに対応する対処法
- Key1への最も有効な対処法
- Key2への最も有効な対処法
(対処法がないのであれば、「対処法なし」と表示する)
`` `
ステップごとのチェックフロー
明確なチェックリストは前後関係における依存や懸賞手順がある場合にエージェントが自身の進捗状況を追跡でき、コンパクションが起こった際に手順を省略することができます。
## 形式的処理のワークフロー
進捗:
- [ ] Step 1: inputタグの調査を行う(run `scripts/実行するファイル`)
- [ ] Step 2: タグのマッピングファイルを作成する(edit `mapping.json`)
- [ ] Step 3: 既存のデータに紐づく検証を実施(run `scripts/実行するファイル`)
- [ ] Step 4: inputタグに入力可能な形式を洗い出す(run `scripts/実行するファイル`)
- [ ] Step 5: 結果を出力する(run `scripts/実行するファイル`)
検証時のループについて
一度実行した作業をエージェント自身に評価・検証させるように指示をする(検証ツール等必須)と、問題があれば修正し、検証に合格するまで繰り返します。
また、調査フェーズ時に参照したファイルは最終的な結果に対する検証用のツールとしても機能します。
## 編集中のワークフロー
1. 編集作業を実施してください
2. 検証作業: `python scripts/validation.py output/`
3. もし検証結果が失敗になったら:
- エラーメッセージをレビューしてください
- 問題を修正してください
- 検証作業を再度実施してください
4. 検証に合格した場合のみ次の作業に進んでください
計画・検証・実行
エージェント自身がスキルのタスク内で必要な計画を行い、その計画が問題ないことを検証したうえで実行する等の方法も有効である
例えば下記のように記載した場合、1にて渡した答えとなる読み込んだ内容と、3で抽出した実装済みの内容を4で比較しています。
もし、何かないのであればその結果をもとにエージェント自身が修正する布石になります。
## ドキュメントに沿って実装を行う
1. `hogehoge`MCPを使用し、ユーザが提示したドキュメントページを参照する
2. 参照したページからinputタグに関連した情報を抽出し、`form_values.json`として出力する
(フィールド名、タイプ、必須等の情報を一覧で表示する)
3. 既存の実装ファイルから`filed_values.json`ファイルにフィールド名等の紐づけたマッピング情報として出力
4. 検証: `script/hoge.py`を使用して`form_values.json`と`filed_values.json`を比較し、フィールド名が存在すること、タイプがあっていること記載漏れがないことを確認する
5. もし、検証に失敗した場合、再度マッピングファイルを作成し`filed_values.json`に書き出して検証を行ってください
再利用すべきスクリプトは存在するのか
スキルを再開発する際は、エージェントの実行トレースを参照することも重要です。
例えば、毎回同じようなロジックを作成して形式の分析や出力の検証をエージェントが独自に行っているのであれば、そのスクリプト自体をバンドル化すべきであるというサインになります。
*scripts/配下に置くもののこと
スキル記述の最適化
スキルの説明を充実させることで、実施したいことをプロンプトだけでなくスキルを呼び出せる形にする。
スキルは、呼び出されないと効果を発揮することができません。
なので、descriptionにどのようなパターンで呼び出されるのかを明確に書くことが重要になります。
ただし、拾えるスコープがでかすぎるとそれはそれで不要な場合でも呼ばれてしまうようになってしまうので注意が必要です。
*補足:スキルは /hogehogeのように呼び出すほかdescriptionに記載した内容から関連していそうな場合にも呼び出されます。
スキルの発動条件について
AIエージェントは、段階的情報開示によってコンテキストを管理します。
起動時には利用可能なスキル名と説明のみ読み込み、関連するものがないかの可能性を判断できるようにロードします。
プロンプトとして入力した内容がdescriptionに記載した内容と一致した場合スキル全体と、SKILL.mdを読み込み処理を実施します。
ただし、単純な処理では説明と一致していても基本的なツールで処理できる場合は、スキルが起動しない場合もあります。(起動される場合:専門的な知識が必要、なじみのない処理、特殊なワークフロー・フォーマットが必要)
効果的な説明を書くには?
適切な説明文を書きたいけどどこに注意すればわからない
- どういうタイミングで使用するのかを記載する
- 例えば、「このスキルは、○○する」ではなく「このスキルは、○○するときに使用する」のようにエージェント指示として記載する。そうすることで、エージェントがいつ行動すべきなのかが明確になるので行動しやすくなります
- ゴールを記載する
- 例えば、どういうパターンの時に使用するのか、何を達成させたいときに呼びたいかなどユーザが何をしたいかに焦点を当てるの良いです
- やや強引な説明を記載する
- 例えば、ユーザが詳細に記載しなくともエージェントがこれっぽいなと思えるぐらいに列挙する
- 簡潔にまとめよう
- 1024文字以内にスキルの範疇を網羅できるような短文を記載する。ただし、複数のスキルに類似するような文言は避けるようにしましょう
トピック:トリガーを評価しよう
どのようなパターンでスキルが呼び出されるのかを確認してみよう!
以下のような形式で、プロンプトを記載することでスキルが呼び出されるかどうかの確認をすることができます
(公式ドキュメント上20個ぐらい(true:10,false:10)が目安)
[
{"query":"想定するプロンプト","should_trigger":真偽値(呼び出されてほしいプロンプトの場合は'true'、そうでない場合は'false')},
{"query":"","should_tjrigger":false},
]
トリガーに求めるもの
- 表現
- 直接的な書き方や簡単なもの、誤字脱字や省略系など多種多様な書き方がよい
- 明示性
- スキルの領域を直接指定する:明確に目標・目的があるものやこうしたいんだけどどうすればいいなどバリュエーション豊かに記載する
- 詳細
- 簡潔な指示と文脈が豊富な支持を組み合わせる。例えば、これを分析してほしいという文言の後にcsvのファイルや背景情報がある
- 複雑性
- 段階と判断基準をより複雑に、対象となるスキルが複雑な文言に含まれていたとしてもくみ取れるかを確認する
トリガーが誤動作しないことの確認クエリ
例えば、分析ではなく編集・処理をしてほしいのに、CSVという文言が含まれているだけで実行されるとユーザからしたら、不要な動作をされUXが悪くなります。
そういったことをテストする
- 類似しているが違うもの
- CSVファイルをEXCEL形式で編集して
- データがCSVであるからその情報をもとにDB操作して
リアリティーを追求しよう
一般的な利用としては、ファイルパスを含んでいたり、個人的な背景や処理に関する詳細な内容、言葉遣いなどリアリティーのある文章もクエリに追加したほうが良いでしょう
- ファイルパス(~/hogehoge.csv)
- 個人的な背景
- 詳細情報(CSVでは、列名やデータ形式)
- 言葉遣いや略語、誤字脱字
動作確認について
実行方法はいたって簡単です。
スキルが読み込まれている状態で、エージェント経由でスキルが呼び出されたかを確認するだけです。
一般的なエージェントクライアントは、実行ログなどを参照することができるのでどのスキルが実行されたかを確認できます。
なので、should_triggerで記載した通りの動作をしているかを確認してください。
複数回同じ文言で呼び出してみよう
一度の呼び出しではサンプリング数が少なく、評価基準であるトリガー率がわかりませんなので、最低3回程度呼び出すような形をとりましょう
#!/bin/bash
QUERIES_FILE="${1:?Usage: $0 <記載したクエリ.json>}"
SKILL_NAME="実行したいスキル名"
RUNS=3 #ループ数
check_triggered() {
local query="$1"
claude -p "$query" --output-format json 2>/dev/null \
| jq -e --arg skill "$SKILL_NAME" \
'any(.messages[].content[]; .type == "tool_use" and .name == "Skill" and .input.skill == $skill)' \
> /dev/null 2>&1
}
count=$(jq length "$QUERIES_FILE")
for i in $(seq 0 $((count - 1))); do
query=$(jq -r ".[$i].query" "$QUERIES_FILE")
should_trigger=$(jq -r ".[$i].should_trigger" "$QUERIES_FILE")
triggers=0
for run in $(seq 1 $RUNS); do
check_triggered "$query" && triggers=$((triggers + 1))
done
jq -n \
--arg query "$query" \
--argjson should_trigger "$should_trigger" \
--argjson triggers "$triggers" \
--argjson runs "$RUNS" \
'{query: $query, should_trigger: $should_trigger, triggers: $triggers, runs: $runs, trigger_rate: ($triggers / $runs)}'
done | jq -s '.'
訓練データと検証データの分割による過学習の回避
すべての検証データをもとに説明文の最適化を行うと、偏りによる過学習が起こります。
例えば特定の文言には、確実に呼び出すことができるが、新しいフレーズで呼びだしたいのに呼び出せないといった問題が発生する
そのため、下記を目安に作成するのが大切です。
- トレーニング用データセット:6割
- 検証用データセット:4割
*ただし、呼びだすためのクエリとそうでないクエリを同等含めるようにしなければならない
最適化するためのループ
今までの内容をもとにdescriptionを最適化するループを作りましょう!
方法
- プロンプトとして以下の内容をインプットする
# 目的
SKILL.md の `description` を最適化し、発火精度を高める。
対象スキル: <SKILL.md のパス>
評価データ: トレーニング用 <パス> / 検証用 <パス>
各クエリに should-trigger / should-not-trigger のラベルが付与されている。
# 評価方法
- 各イテレーションで train / validation の両方を評価する。
- 発火判定は、最適化の文脈を持たないクリーンな状態で行う(eval script、または
description のみを渡したサブエージェント)。推測による自己評価で代用しない。
- 結果を必ず下表に記録する。
| iter | description(全文) | train合格率 | val合格率 | trainの失敗クエリ(種別付き) |
# 手順(1イテレーション)
1. 現在の description を train / validation の両方で評価し、上表に記録する。
2. **train の失敗のみ**を2種類に分けて列挙する。
- a: should-trigger なのに発火しなかったクエリ
- b: should-not-trigger なのに発火したクエリ
※ validation の結果は、この分析にも次の修正にも一切使わない(記録のみ)。
3. train の失敗だけを根拠に description を修正する。一般化を最優先する。
- a が多い → 範囲が狭い。対象範囲を広げる、またはスキルが役立つ状況・文脈を追記する。
- b が多い → 範囲が広い。何をしないかを明示する、または隣接スキル/隣接機能との
境界を明確にする。
- 失敗クエリの固有語をそのまま追記しない(過学習)。**代わりに**、そのクエリ群が
代表する上位カテゴリ・概念を特定し、それを記述する。
- 2〜3回修正しても改善しない場合は、小さな手直しをやめ、文構造・切り口ごと
書き直した別案を試す。
- 1024文字以内を厳守する(最適化中は膨張しやすいため毎回確認する)。
# 反復と停止条件
1〜3 を繰り返す。上限5イテレーション。以下のいずれかで停止する。
- train が全件合格した
- 2イテレーション連続で train 合格率が改善しない
- 5イテレーションに達した
5回で改善しない場合、原因は description ではなくクエリ側(易しすぎる/難しすぎる/
ラベル誤り)の可能性が高い。その旨を指摘して報告する。
# 最終選択
- 全イテレーションのうち **validation 合格率が最も高いもの** を採用する。
- 最後のイテレーションが最良とは限らない。train に過学習した後半より、前半の方が
validation が高い場合は前半を採用する。
- 同率の場合は description が短い方を採用する。
# 適用と最終確認
1. 選んだ description を SKILL.md の frontmatter に反映する。
2. 1024文字以内であることを再確認する。
3. 最適化に一度も使っていない新規クエリを5〜10件(should-trigger と
should-not-trigger を混在)作成し、それで最終評価する。この結果を汎化性能の
報告値とする。
# 出力
- イテレーション記録の表(上記形式)
- 採用した description(全文・文字数・採用理由)
- 各修正で「どの失敗カテゴリに、どの一般化で対応したか」
- 新規クエリでの最終合格率
参考資料
公式ドキュメント


