Empirical Prompt Tuning
プロンプトの品質は書いた本人には分からない。書き手が「明瞭だ」と思うものほど、別エージェントが読むと詰まる。バイアスを排した実行者に実際に動かしてもらい、両面で評価して反復する のが本 skill の核。改善が頭打ちになるまで止めない。
いつ使うか
- skill / slash command / タスクプロンプトを新規作成・大幅改訂した直後
- エージェントが期待通り動かず、原因を指示側の曖昧さに求めたいとき
- 重要度の高い指示(頻繁に使う skill、自動化の中核プロンプト)を堅牢化したいとき
使わない場面:
- 一回限りの使い捨てプロンプト(評価コストが割に合わない)
- 成功率の改善が目的ではなく、書き手の主観的好みを反映したいだけのとき
ワークフロー
-
Iteration 0 — description と body の整合チェック(静的、dispatch 不要)
- frontmatter
descriptionが謳う trigger / 用途を読む - body がカバーする範囲を読む
- 乖離があれば iter 1 に進む前に description か body を合わせる
- 例: description「navigation / form filling / data extraction」と書いてあるが body は
npx playwright testの CLI ref のみ、のような乖離を検出 - これを飛ばすと、subagent は description に合わせて body を「再解釈」し、実質 skill が要件を満たしていないのに精度が出る(false positive)
- frontmatter
-
ベースライン準備: 対象プロンプトを確定し、次の 2 つを用意する。
- 評価シナリオ 2 〜 3 種(中央値 1 + edge 1 〜 2)。現実に起こりうるタスクで、対象プロンプトを実際に適用する場面を想定する。
- 要件チェックリスト(精度算出のため)。シナリオごとに「成果物が満たすべき要件」を 3 〜 7 項目で列挙する。精度 % = 満たした項目数 / 全項目数。事前に固定すること(後から動かさない)。
-
バイアス排除読み: 指示を「白紙」の実行者に読ませる。Task tool で 新規 subagent を dispatch する。自己再読で済ませない(直前に書いた文章を客観視することは構造的に不可能)。並列で複数シナリオを同時実行する場合は単一メッセージ内で複数 Agent 呼び出しを並べる。dispatch 不能環境の扱いは「環境制約」節を参照。
-
実行: 後述の subagent 起動契約 に従ったプロンプトを subagent に渡し、シナリオを実行させる。実行者は実装や出力を生成し、最後に自己申告レポートを返す。
-
両面評価: 戻ってきた結果から次を記録する。
- 実行者の自己申告(subagent のレポート本文から抽出): 不明瞭点 / 裁量補完 / テンプレ適用で詰まった箇所
- Trace 解釈: 各不明瞭点に、発生したフェーズタグ(Understanding / Planning / Execution / Formatting — 「subagent 起動契約」で定義)を付ける。フェーズ局所的な修正の方が、全体的に「指示が不明瞭だった」と片付ける修正より効く。Understanding フェーズの 1 つの曖昧さが、Execution フェーズの連鎖的な失敗として表面化することが多い。
- 構造化された振り返り: 各不明瞭点は
Issue / Cause / General Fix Ruleの 3 点で返させる。General Fix Ruleは「失敗パターン台帳」に供給されるクラスレベルの抽象化。これが無いと修正はその場限りのパッチに留まり、同じ誤りを後で再発見することになる。 - 指示側の計測(判定規則は本節で一元定義、他箇所は本節を参照する):
- 成功/失敗:
[critical]タグの付いた要件が 全て ○ のときのみ成功(○)。うち 1 つでも × または部分的なら失敗(×)。ラベルは ○ / × の 2 値のみ。 - 精度(要件チェックリストの達成率 %。○ = 満点、× = 0、部分的 = 0.5 で合算、全項目数で割る)
- ステップ数(Task tool の戻り値に付く usage メタの
tool_usesをそのまま使う。Read / Grep も含める、除外しない) - 所要時間(Task tool の usage メタの
duration_ms) - 再試行回数(subagent が同じ判断をやり直した回数。subagent の自己申告レポートから抽出、指示側では測れない)
- 失敗時は「どの [critical] 項目が落ちたか」を提示フォーマットの "不明瞭点" 節に 1 行添える(原因追跡のため)
- 成功/失敗:
- 要件チェックリストには
[critical]タグ付き項目を 最低 1 つ 含めること(0 件だと成功判定が vacuous になる)。事後に [critical] の付け外しをしない。
-
差分適用: 不明瞭点を潰す最小修正をプロンプトに入れる。1 イテレーション 1 テーマ(関連する複数修正は OK、無関係な修正は次回に回す)。
- 「差分」は加算とは限らない。削除・書き直しも同格の修正手段(後述「簡潔性を保つ」節)。否定形パッチ(「旧来の X は使わない」)を足す前に、望む終状態を 1 つの肯定形に書き直せないか先に試す。
- 修正前に「この修正が要件チェックリスト / 判定文言のどの項目を満たすか」を明示する(軸名から推測した修正は届かないことが多い。後述「修正の波及パターン」節)。削除のときも同じ — 「消してもどの [critical] 項目も落ちない」根拠を 1 行で示してから消す。
- まず失敗パターン台帳を参照する。構造化された振り返りの
General Fix Ruleが既存エントリと一致するなら、最初に問うべきは「既存の修正はなぜ再発を防げなかったのか」。新しい台帳エントリを追加する前に、修正の位置をプロンプト冒頭寄りに移す、あるいは文言を書き直す必要があるかもしれない。
-
再評価: 新しい subagent で再度 2 → 5 を回す(同一 agent は再利用しない: 前回の改善を学習している)。並列度はイテレーションを進めても改善が頭打ちにならない場合に増やす。
-
収束判定: 目安「連続 2 イテレーションで新規の不明瞭点ゼロ かつ メトリクス改善が閾値以下(後述)」で停止。重要度が高いプロンプトは 3 連続にする。
簡潔性を保つ(減算的チューニング)
チューニングは放っておくと加算に偏る(差分適用も台帳も「足す」方向しか持たない)。プロンプトは反復のたびに膨張し、読み手の認知負荷が上がる。チューニング後のプロンプトは「いま望む終状態」だけを最も簡潔に書いた状態を目指す — 前バージョンの痕跡・修正経緯・否定形パッチを残さない。削除・書き直しは加算と同格の差分であり、各イテレーションで次を削除候補として疑う:
- 自明: 対象が扱うコード / ツールを読めば分かること(API シグネチャ、自明なディレクトリ構成の説明 等)
- 冗長: 同じ規則が複数箇所にある、例が規則の言い換えにすぎない
- 陳腐化: 過去の版の経緯、もう存在しない選択肢の禁止
- 否定形パッチの蓄積: 「A は使わない / B も使わない」が増えていたら、望む終状態を 1 つの肯定形に書き直せないか試す(否定形は新旧両方を読ませる)
削りすぎ防止(最重要): 削除も差分なので必ず再評価にかける。簡潔さは精度を犠牲にして得るものではなく、精度を保ったまま到達する状態。削除前に「消してもどの [critical] 項目も落ちない」根拠を 1 行示し、再評価で精度(特に [critical])が落ちたら、その記述は load-bearing だった=削除が誤り。元に戻す。「短くする」を目的化して精度を割るのは本末転倒。
評価軸
| 軸 | 取り方 | 意味 | | ------------------------ | --------------------------------------------- | ---------------------- | | 成功/失敗 | 実行者が意図した成果物を出したか(二値) | 最低ライン | | 精度 | 成果物が要件を何 % 満たしたか | 部分成功の程度 | | ステップ数 | 実行者が使ったツール呼び出し / 判断ステップ数 | 指示の無駄遣いの指標 | | 所要時間 | 実行者の duration_ms | 認知負荷の代替指標 | | 再試行回数 | 同じ判断を何度やり直したか | 指示の曖昧さのシグナル | | 不明瞭点(自己申告) | 実行者が箇条書きで列挙 | 質的な改善材料 | | 裁量補完箇所(自己申告) | 指示で決まっていなかった判断 | 暗黙の仕様の炙り出し |
重み付け: 質的(不明瞭点・裁量補完)を主、量的(時間・ステップ数)を補助とする。時間短縮だけ追いかけるとプロンプトが痩せすぎる。
tool_uses の質的解釈
精度だけ見ると skill の欠陥が隠れる。tool_uses を シナリオ間の相対値 で見て、1 シナリオだけ他比 3-5 倍以上なら、その skill は自己完結性が低く references 横断を強いているサイン(例: 全シナリオ 1-3 なのに 1 つだけ 15+)。対処は iter 2 で「最小完成例 inline」や references を読む指針を冒頭に足すこと。精度 100% でも偏りがあれば打ち切らない。
修正の波及パターン
修正→効果は非線形。特に 軸名と判定文言は別物 で、軸名から推測した修正は判定文言のどれにも届かないことがある。逆に 1 つの構造的情報(コマンド + 設定 + 期待出力の組合せ等)が複数軸の判定文言を同時に満たすこともある。だから step 5 の通り差分適用前に判定文言レベルで紐付けを言語化させる。評価軸を新設するときも各点の判定基準を閾値文言レベルまで具体化する(何があれば満点か subagent が判定できる粒度)。
subagent 起動契約
実行者に渡すプロンプトは次の構造を取る。これが「両面評価」の入力契約。
あなたは <対象プロンプト名> を白紙で読む実行者です。
## 対象プロンプト
<対象プロンプトの本文を全文貼る or Read で読ませるパスを指定>
## シナリオ
<シナリオの状況設定 1 段落>
## 要件チェックリスト(成果物が満たすべき項目)
1. [critical] <最低ラインに含む項目>
2. <通常項目>
3. <通常項目>
...
(判定規則は「ワークフロー 4. 両面評価 / 指示側の計測」節に一元定義。[critical] は最低 1 つ必須。)
## タスク
1. 対象プロンプトに従ってシナリオを実行し、成果物を生成する。
2. 終了時に下記レポート構造で返答する。
## レポート構造
- 成果物: <生成物 or 実行結果サマリ>
- 要件達成: 各項目について ○ / × / 部分的(理由付き)
- **Trace**(各フェーズについて OK / stuck / skipped タグを付け、OK でないときは 1 行理由を添える):
- Understanding(指示を読み、メンタルモデルを組み立てる)
- Planning(アプローチ・順序を決める)
- Execution(実際に作業する)
- Formatting(成果物を期待される形に整える)
- *折り畳み形式可*: 4 フェーズすべてが OK のときは `Trace: all OK` の 1 行で十分。stuck / skipped があるフェーズが 1 つでもあるときのみ phase-by-phase で出す。(happy-path のボイラープレートを避けるため。trace 構造は何かが実際に詰まったときにしかコストに見合わない)
- **不明瞭点(構造化)**: 各項目について 3 行:
- Issue: <観測された現象>
- Cause: <指示レベルで診断した原因>
- General Fix Rule: <その場限りの修正ではなく、このクラスの誤りを防ぐクラスレベルのルール>
- 裁量補完: 指示で決まっておらず自分の判断で埋めた箇所(箇条書き)
- 再試行: 同じ判断をやり直した回数とその理由
呼び出し側はレポートから自己申告部分を抽出し、tool_uses / duration_ms を Agent tool の usage メタから取得して評価軸表を埋める。
環境制約
新規 subagent を dispatch できない環境(既に subagent として動作している、Task tool が無効化されている等)では、本 skill は 適用しない。
- 代替案 1: 親セッションのユーザーに別 Claude Code セッションを起動して依頼してもらう
- 代替案 2: 評価を諦め、ユーザーに「empirical evaluation skipped: dispatch unavailable」と明示報告する
- NG: 自己再読で代替する(バイアスが入るので評価結果を信じてはいけない)
構造審査モード: empirical 評価ではなく、skill / プロンプトの 記述の整合性・明瞭性だけ をチェックしたい場合は、構造審査モードとして明示的に切り分ける。subagent への依頼プロンプトに「今回は構造審査モード: 実行ではなくテキスト整合性チェック」と明記する。これにより subagent は環境制約節の skip 動作に引っかからず、静的レビューを返せる。構造審査は empirical の代替ではなく補助(連続クリア判定には使えない)。
反復の打ち切り基準
- 収束(停止): 連続 2 回で次を 全て 満たす:
- 新規不明瞭点: 0 件
- 精度の前回比改善: +3 ポイント以下(5% → 8% のような飽和)
- ステップ数の前回比変動: ±10% 以内
- duration の前回比変動: ±15% 以内
- 過適合チェック: 収束判定時に、これまで使っていない hold-out シナリオ 1 本を追加して評価。精度が直近平均から 15 ポイント以上落ちたら過適合。baseline シナリオ設計に戻って edge を足す。
- 発散(設計を疑う): 3 回以上イテレーションしても新規不明瞭点が減らない → プロンプトの設計方針自体が間違っている可能性。修正パッチで直すのをやめ、構造を書き直す
- リソース打ち切り: 重要度と改善コストが釣り合わなくなったら止める(80 点で出す判断)
失敗パターン台帳
イテレーション横断で、失敗モードを累積的に記録するリストを維持する。これが無いと、各イテレーションで同じクラスの誤りを何度も再発見することになり、同じ General Fix Rule が表層の文言を変えて繰り返し表面化しているのに気付かないまま精度改善が停滞する。
エントリ形式:
- **Pattern 名**: 短く記述的なハンドル(「X が曖昧」ではなく「skip 条項が無いときの過剰なテンプレ適用」のような形)
- Example: <あるイテレーションの代表的な Issue 文言>
- General Fix Rule: <当該イテレーションの構造化振り返りから得たクラスレベルのルール>
- Seen in: iter N, iter M, ...
ルール:
- ワークフロー 5 で修正を生成する前に、台帳をスキャンする。現在の
General Fix Ruleが既存エントリと一致するなら、Seen inを更新し、新エントリを追加する前に「既存の修正はなぜ再発を防げなかったか」(文言の曖昧さ?プロンプト内の位置が遅すぎ?例が欠けている?)を調査する。 - 的を絞った修正にもかかわらず 3 回以上再発するパターンは構造的シグナル — パッチを続けるのではなく、上記「発散」基準にエスカレートする。
- 台帳は対象プロンプト単位で持つ。empirical-prompt-tuning 全体のグローバル台帳ではない。
- 台帳はチューニング作業中の作業メモであり、対象プロンプト本体には書き込まない(本体は終状態だけを保つ)。作業ログ / 別ファイルに置く。
バリアント探索(任意、停滞打破用)
収束基準に届かないまま頭打ちなら局所最適を疑い、同じシナリオに 2 バリアントを並列 dispatch する:
- Conservative: 現在のプロンプト + 次善の小さな修正
- Exploratory: 構造変更を 1 つ(節の並べ替え / 密な段落の分割 / 冗長節の削除 / 欠けている動作例の追加)
採用は 客観軸のみ で決める — 精度が高い方、同率なら不明瞭点の少ない方、さらに同率なら tool_uses の少ない方。subagent に「A vs B」を直接評価させない(位置・self-preference バイアスでノイジー)。dispatch が 2 倍になるので停滞時のみ使う。
提示フォーマット
各イテレーションで次の形で記録・ユーザーに提示する:
## Iteration N
### 変更点(前回差分)
- <修正内容 1 行>
- Pattern applied: <台帳上の Pattern 名、または「(new)」>
### 実行結果(シナリオ別)
| シナリオ | 成功/失敗 | 精度 | steps | duration | retries | Weak phase |
|---|---|---|---|---|---|---|
| A | ○ | 90% | 4 | 20s | 0 | — |
| B | × | 60% | 9 | 41s | 2 | Execution |
### 構造化された振り返り(今回新出)
- <シナリオ B>: [critical] 項目 N が × — <落ちた理由 1 行>
- Issue: <観測された現象>
- Cause: <指示レベルでの原因>
- General Fix Rule: <クラスレベルの抽象化>
- <シナリオ A>: (新出なし)
### 裁量補完(今回新出)
- <シナリオ B>: <補完内容>
### 台帳更新
- Added: <Pattern 名>(シナリオ B 由来)
- Re-seen: <Pattern 名>(元々 iter K) — 既存の修正が再発を防げなかった理由: <理由>
### 次の修正案
- <最小修正 1 行>
(収束判定: 連続 X 回クリア / 停止条件まであと Y 回)
Red flags(合理化に注意)
| 出てくる合理化 | 実態 | | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | 「自分で読み直せば同じ効果がある」 | 直前に書いた文章を "客観視" はできない。必ず新規 subagent を dispatch する。 | | 「1 シナリオで充分 / 適当でいい」 | 1 本は過適合。楽すぎ・難しすぎはシグナルが出ない。中央値 1 + edge 1〜2。 | | 「不明瞭点ゼロが 1 回出たから終わり」 | 偶然なこともある。連続 2 回で確定判定。 | | 「複数の不明瞭点を一気に潰そう」 | 何が効いたか分からなくなる。1 イテレーション 1 テーマ。 | | 「関連する微修正も純粋に 1 件ずつ別 iter に分けよう」 | 逆方向の罠。"1 テーマ" は意味単位。関連する 2-3 件の微修正は 1 iter にまとめて良い。分けすぎると iter 数が爆発する。 | | 「メトリクスが良いから質的フィードバックは無視」 | 時間短縮は痩せすぎのサインにもなる。質的を主に。 | | 「書き直した方が早い」 | 3 回以上不明瞭点が減らないなら正解。それ以前の段階では逃げ。 | | 「同じ subagent を使い回そう」 | 前回の改善を学習している。毎回新規に dispatch する。 | | 「前の版を否定する一文を足せば直る」 | 否定形パッチの蓄積はプロンプトを膨張させ、新旧両方を読ませる。望む終状態を肯定形で書き直す(「簡潔性を保つ」節)。 | | 「念のため残しておく」 | 自明・冗長・陳腐化した記述は削除候補。消して精度が落ちなければそれが正解、落ちたら load-bearing なので戻す。 | | 「不明瞭点が潰れたのでシナリオを簡単にしよう」 | 修正に合わせてシナリオを緩めるのは本末転倒。シナリオは固定する。 |
関連
superpowers:writing-skills— skill 作成時の TDD アプローチ。本 skill の「subagent で baseline → 修正 → 再実行」と本質的に同じsuperpowers:dispatching-parallel-agents— 複数シナリオを並列で走らせるときの作法