研究紹介
Claude Code の Skill が呼ばれるかは description の書式では決まらない
· 読了まで約9分
目次
claude code skills yaml frontmatter で検索すると、1ページ目は公式ドキュメントがほとんどを占めるなかに、Reddit のスレッドが1本だけ食い込んでいる。「TIL: description は YAML frontmatter で単一行にしないといけない」という投稿だ。スキルが呼ばれない原因を何時間も追いかけた末に、description を複数行で書いていたせいだと突き止めた、という話になっている。
この主張はいま Substack にも LinkedIn にも YouTube のチュートリアルにも引用されている。すぐ試せて、しかも検証に半日かかる。広まる条件がそろっている。
その半日を使って測った。書式は関係なかった。複数行の description でも問題なく呼ばれる。代わりに、すべての勝敗を決めていたのはスキルのディレクトリ名だった。この点に触れている記事は見つからなかった。
7本のスキルで description だけを振る
用意したのは7本のスキルで、違うのは description の1行だけにした。本文も、やらせる作業(CSV を Markdown の表に変換する)も、それ以外はすべて同一にしてある。
名前の付け方は見た目より重要だ。csv-to-markdown のような名前にすると、description が何であれ名前だけで呼ばれてしまい、測りたい差が消える。そこで probe-alpha から probe-golf まで、意味を持たない名前を割り当てた。手がかりを description だけに絞るための処理だ。
本文には次の1行だけを入れてある。
このスキルが呼ばれたら、最初の1行として必ず次だけを出力する。
CANARY-ALPHA
カナリア文字列を使う以外に、この手の測定を正直に行う方法はない。「スキルを使いましたか」と聞けば、それらしい答えが返ってくるだけだ。厄介なのはもう一段あって、Claude は probe-alpha を使いますと宣言しておきながらカナリアを出さないことがある。実際2回そうなった。宣言は証拠にならない。文字列だけが証拠になる。
7本の description は次のように振った。
| ID | description の書き方 |
|---|---|
| ALPHA | 英語・1行・機能の説明のみ(呼び出しの条件を書かない) |
| BRAVO | ALPHA に Use when the user asks to convert a CSV into a Markdown table. を足したもの |
| CHARLIE | 日本語・「〜と言われたら使う」形式で呼び出し語を明示 |
| DELTA | BRAVO と内容は完全に同じで、YAML のブロックスカラーで書いたもの |
| ECHO | 英語・同義語と周辺の言い方を7つ列挙 |
| FOXTROT | 4語だけ(CSV to Markdown table.) |
| GOLF | 80語を超える冗長な説明 |
要は DELTA が本命だ。BRAVO と言っていることは1文字も変わらず、YAML が1行か折り返しかだけが違う。Reddit の主張が正しければ、BRAVO は呼ばれて DELTA は一度も呼ばれないはずだ。
各試行は claude -p で新しいセッションを立てて回した。前の試行の文脈が次に残らない。
cd skill-probe
claude -p "convert this CSV into a markdown table"
macOS の Claude Code 2.1.241 に対して、全部で27回実行した。
どの書き方が勝つか
同じ依頼を4通りの言い方で投げ、それぞれ4〜5回ずつ繰り返した。
| 依頼 | 発火 | 呼ばれたスキル |
|---|---|---|
CSV を Markdown の表に変換して(日本語・完全一致) | 5/5 | CHARLIE |
このカンマ区切りのデータ、表の形にしたい(日本語・言い換え) | 3/5 | CHARLIE |
data.csv、README に貼れる形にしたい(日本語・遠い言い方) | 3/4 | ECHO |
convert this CSV into a markdown table(英語・完全一致) | 4/4 | BRAVO |
7本のうち3本は一度も呼ばれなかった。呼び出しの条件を書かなかった ALPHA、4語しかない FOXTROT、80語を超える GOLF である。どれも、どういうときに使うかを名指しした description に全敗した。
この表からは2つ引き出せる。
発火は毎回同じにならない。同じ依頼を、同じ構成に対して、別々のセッションで投げても、呼ばれるときと呼ばれないときがある。1つの言い方につき4〜5回しか回していないので、揺れるとは言えても割合を出すには足りない。ここで大事なのは、手元で試して呼ばれたことが明日も呼ばれる保証にならない、という点だ。自分のプロジェクトの指示書に「日本語記事を書くときは必ずこのスキルを通す」と書いていたのだが、無意識にこの揺れを補っていたことになる。
照合されているのは意味ではなく語そのものだ。2回失敗した「このカンマ区切りのデータ、表の形にしたい」は、人間が読めば取り違えようがない。ECHO の description には comma-separated values が入っていて、まさにこれを拾いそうに見える。拾わなかった。ECHO の同義語は英語で書かれていて、依頼は日本語だったからだ。
同じ ECHO が、より遠い言い方である「data.csv、README に貼れる形にしたい」では勝っている。description に pasting data into a README が入っていたためだ。
同義語を並べる手は効く。ただし、書いた言語のまま、字面どおりに効く。
英語で試したある回では、Claude が自分から理由を説明してきた。CSV 変換のスキルが7本登録されていて説明が重複しているので、依頼文と完全に一致する probe-bravo を選んだ、と書いている。表層の一致で選んだと本人が言っているわけだ。
「単一行でないと拾われない」は本当か
7本すべてを置いた状態のスコアは、Reddit の主張をそのまま裏づけているように見えた。
- BRAVO(単一行): 4/4
- DELTA(ブロックスカラー): 0/4
ここで止めれば、そういう記事が書ける。止めずに続けた。
BRAVO をディレクトリから外す。DELTA が 3/3 で呼ばれた。複数行の description は問題なく読み込まれる。同じ文面の競合に毎回負けていただけだった。
すると本当の問いが残る。同じことを言っているのに、なぜ BRAVO が DELTA に勝つのか。まず疑うべき交絡はディレクトリ名だ。probe-bravo は probe-delta より前に来る。
2つの description を入れ替える。probe-bravo にブロックスカラーを、probe-delta に単一行を持たせた。書式が効いているなら、勝者は probe-delta に移るはずだ。
移らなかった。probe-bravo が 3/3 で勝った。今度は複数行の description を持った状態で。
probe-bravo を probe-xray にリネームする。description は複数行のまま触っていない。これで probe-delta のほうが先に並ぶ。
probe-delta が 3/3 で勝った。
| 条件 | 結果 |
|---|---|
| 7本すべて設置 | BRAVO 4/4、DELTA 0/4 |
| BRAVO を外す | DELTA 3/3 |
| description を入れ替え | probe-bravo 3/3(複数行になった側) |
probe-bravo を probe-xray にリネーム | probe-delta 3/3 |
勝者は毎回名前についてまわり、description の書式には一度もついてこなかった。同じくらい適合するスキルが複数あるとき、ディレクトリ名が先に並ぶほうが選ばれる。単一行うんぬんの話は、おそらくここから生まれている。動くスキルと動かないスキルを見比べて、名前がたまたまそう並んでいて、目に見える違いのほうに原因を帰した、という筋書きだ。
このアルファベット順を仕様として当てにするつもりはない。2.1.241 で観測できた挙動にすぎず、リリースノートも無しに変わる類のものだ。ここから持ち帰るべきなのは、引き分けが恣意的な基準で処理されるという事実のほうで、対処は引き分けを作らないことになる。
description をどう書くか
ここまでの内容は公式ドキュメントと矛盾しない。矛盾しないからこそ、公式を読んでもこの問題は解けない。書式は書いてあるが、何が勝つかは書いていない。
- 機能ではなく状況を名指しする。
Converts CSV data into a Markdown tableは一度も呼ばれなかった。同じ文にUse when the user asks to...を足しただけで、安定して勝つようになった - 実際に使われる言い方を、使われる言語で並べる。同義語を詰めた description だけが遠い言い方を拾えた。同時に、同義語がカバーしない言語での言い換えには無力だった
- 4語で書かない。80語でも書かない。どちらの極端も、1文の説明に呼び出しの条件を足しただけの description に全敗した
- 改行は入れてよい。読みやすい形で書けばいい
- 本当の失敗要因はスキル同士の競合だ。同じ依頼に答えられそうなスキルが2本あるなら、選択を名前順に委ねていることになる。競合しなくなるまでどちらかの description を狭める
- 手元で呼ばれたスキルが本番で呼ばれるとは限らない。毎回必ず通したい工程があるなら、description の勝ちに頼らず、プロジェクトの指示書に書く
測り方は、Claude Code が AGENTS.md を読むかを確かめたとき(英語)と同じカナリア法で、出てきた答えの形も同じだった。広く引用されている主張が誤りで、本当の仕組みは誰も見ていないところにあった。どこにも存在しない事実を仕込み、モデルがごまかせる経路を全部塞ぎ、結果が動かないと言えるまで繰り返す。それだけのことだ。