スキルを書いていて一番困るのは、同じプロンプトなのに出力が毎回違う、という事象です。私は 4 サイトの記事生成と品質チェックをスキル化して運用していますが、初期のスキルは「お願いの仕方」を書いただけで、出てくる成果物の構造もトーンも実行のたびに揺れていました。この揺れを設計で潰す方法を、スペック文書を読みやすい HTML に変換するスキルの設計例と、自分の article_gate.py 周りの運用をもとに整理します。
題材にするのは「仕様書を分析・再構成・要約して、図やバッジ付きの HTML レポートにする」という種類のスキルです。単なる Markdown から HTML への機械変換ではなく、内容の理解を伴う変換という点が肝で、ここをどう設計に落とすかが出力安定の分かれ目になります。
「いつ使うか・使わないか」を本文の先頭に置く
最初にやるべきは、スキルが行うタスクの大前提を冒頭で固定することです。「変換」とだけ書くと、性能の低いモデルほど Markdown タグを HTML タグに置き換えるだけの処理と解釈しますし、高性能なモデルでも文脈次第で単純変換に寄ります。だから「これは分析・再構成・要約を伴う変換である」と最初に宣言します。
## When to Use This Skill
- Convert a specification, requirements, or design doc into a
readable HTML report (analyze, restructure, summarize)
- Make a Markdown spec easier for humans to read
- Add summaries, diagrams, and charts that aid comprehension
Do **not** treat this as a literal Markdown-to-HTML conversion
unless the user explicitly asks for a faithful conversion.
この「Do not」の一文が効きます。私の記事生成スキルでも、冒頭に「公式ドキュメントの要約を作る作業ではない」と否定形で明示してから、テンプレート要約への寄りが目に見えて減りました。やってほしいことの定義と同じ重みで、やってほしくない解釈を否定形で書く のが、出力を意図に寄せる第一歩です。
判断基準をテーブルで与える
スキルに自由度を残すと、「どう判断すべきか」が毎回ぶれます。これを潰すには、判断の分岐をスキル内に明示します。HTML 変換スキルの例では「いつ何の図を出すか」を表で与えていました。
ステップバイステップのプロセス → フローチャート
システム間の API 呼び出し → シーケンス図
エンティティと関係 → ER 図
ステータスのライフサイクル → ステート図
この対応表を渡しておくだけで、的確なダイアグラムが自動で選ばれるようになります。私の品質チェックスキルでも同じ発想で、「このシグナルが N 個未満なら違反、N 個以上なら通過」という閾値判断をスキルに埋め込み、article_gate.py 側と二重化しています。判断を文章でふんわり書くのではなく、入力の特徴 → 取るべき出力 の対応として列挙すると、モデルの判断が安定します。
references テンプレートで品質を固定する
プロンプトだけでは、生成される成果物のスタイルが毎回ブレます。ここで効くのが references/ にテンプレートを置く設計です。スキル本体は判断と手順を持ち、固定したい具体物はテンプレートファイルに逃がします。
skill-name/
├── SKILL.md # 判断・手順(200行以内)
└── references/
├── template.html # ベースHTML(CSS変数を含む)
└── components.md # 各UIパーツの使い方ガイド
テンプレート側には、固定したい見た目を CSS 変数として定義しておきます。
:root {
--color-primary : #00a273 ;
--color-primary-dark : #008a62 ;
--color-surface : #f5f8f7 ;
--font-sans : 'Hiragino Kaku Gothic ProN' , sans-serif ;
--radius : 12 px ;
}
この「テンプレート + コンポーネントガイド」の組み合わせがミソで、CSS を丸ごとコピーしつつ、コンテンツだけをソース文書から生成する、という安定した出力が得られます。本体に全部を書こうとすると SKILL.md が肥大し、しかも後半が読まれないリスクが出ます。詳細を references/ に逃がす設計は、SKILL.md の後半が読まれていなかった話 — 200行に収める設計 で扱った progressive disclosure と完全に同じ方向です。
私が記事生成スキルで _documents/AUTHOR_VOICE_STYLE_GUIDE.md や PERSONALIZATION_MAX_GUIDE.md を別ファイルに分け、本体からは参照だけにしているのも、まさにこのテンプレート固定の発想です。文体や禁止パターンの「具体物」を本体に書くと毎回ブレますが、別ファイルに固定して参照させると再現性が上がります。
トレーサビリティを規則として埋め込む
AI が文書を要約すると、元の意味がずれるリスクが常にあります。これを設計で防ぐには、トレーサビリティの規則を SKILL.md に明文化します。HTML 変換スキルでは次のような規則を組み込んでいました。
推測した内容には Inferred や Assumption のラベルを付ける
仕様上のキーワード(MUST / SHOULD / SHALL)はそのまま保持する
API パス、フィールド名、エラーコード、列挙値は原文のまま引き写す
曖昧な箇所は勝手に解釈せず「Open Questions」セクションに分離する
この 4 つを規則化しておくと、「要約されているが、原文のどこに対応するか追えない」という事故を防げます。私の品質ゲートでも考え方は同じで、機械チェックの正規表現を article_gate.py に固定し、検出条件を曖昧にしないようにしています。例えば常体混入を弾く規則は、こう書いています。
JOTAI_REGEX = [
r " (?:^ | [ ^ \w]) である [ 。. ] " ,
r " (?:^ | [ ^ \w]) だった [ 。. ] " ,
r " [ ぁ-んァ-ヶ一-龥 ] だ [ 。. ] " ,
]
# いずれか1件でも一致したら違反として push を止める
人間の判断に委ねると揺れる箇所を、規則として固定する。スキルでもスクリプトでも、安定の本質はここにあると考えています。
本番運用で踏んだ落とし穴
実運用でつまずいた点を挙げておきます。本番運用に投入する前に、ここで挙げる落とし穴をどう回避するかを決めておくと、不具合時の対処も楽になります。
「変換」という語を否定形で縛らないと、単純なタグ置換に落ちる 。冒頭の Do not が無いと、性能の高いモデルでも文脈次第で機械変換に寄ります
テンプレートの CSS を本体に書くと SKILL.md が肥大する 。本体が 200 行を超えると、横断利用時に後半が読まれないリスクが出ます
判断基準を文章で書くと再現しない 。入力の特徴と出力の対応を列挙する形にすると安定します
要約規則が無いと原文の用語がずれる 。MUST / SHOULD やフィールド名の保持を規則化しておくのが安全です
テンプレートの取り違えは references/ の一本化で回避する 。固定物を 1 ファイルにまとめて参照させると、本番運用でのばらつきを回避でき、問題が起きたときの原因の切り分けと対処も追いやすくなります
まず1つのスキルで試す
もし手元に出力がブレるスキルがあるなら、私はまず references/ にテンプレートを切り出すことを推奨します。具体的には次の手順で進めると安全です。
references/template.html に固定したい見た目(CSS 変数や雛形)を切り出す
SKILL.md 本体からはそのテンプレートを参照する形に直す
判断基準を「入力の特徴 → 出力」の対応として列挙し直す
本体に散らばっていた具体物を 1 ファイルに集めるだけで、出力の安定度が変わります。この場合は、本体を 200 行以内に保ちやすくなる副次効果もあります。
スキルは、プロンプトとテンプレートだけでツールを作れるのが強みです。2014年からアプリを個人開発で作り続けてきた感覚として、私自身、複数サイトを一人で回す中で、この「判断は本体・具体物はテンプレート」という分け方に何度も助けられました。スクリプトでオーケストレーションそのものを固定する話はDynamic Workflow を自作する — phase / agent / pipeline で再現可能な調査パイプラインを書く で扱っているので、スキルとワークフローの使い分けの参考にしていただければ幸いです。