---
name: empirical-prompt-tuning
description: agent 向けテキスト指示（skill / slash command / task プロンプト / CLAUDE.md 節 / コード生成プロンプト）を、バイアスを排した実行者に動かしてもらい、両面（実行者の自己申告 + 指示側メトリクス）で評価して反復改善する手法。改善が頭打ちになるまで回す。プロンプトや skill を新規作成・大幅改訂した直後、またはエージェントの挙動が期待通りにならない原因を指示側の曖昧さに求めたいときに使う。
---

# Empirical Prompt Tuning

プロンプトの品質は書いた本人には分からない。書き手が「明瞭だ」と思うものほど、別エージェントが読むと詰まる。**バイアスを排した実行者に実際に動かしてもらい、両面で評価して反復する** のが本 skill の核。改善が頭打ちになるまで止めない。

## いつ使うか

- skill / slash command / タスクプロンプトを新規作成・大幅改訂した直後
- エージェントが期待通り動かず、原因を指示側の曖昧さに求めたいとき
- 重要度の高い指示（頻繁に使う skill、自動化の中核プロンプト）を堅牢化したいとき

使わない場面:
- 一回限りの使い捨てプロンプト（評価コストが割に合わない）
- 成功率の改善が目的ではなく、書き手の主観的好みを反映したいだけのとき

## ワークフロー

0. **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）

1. **ベースライン準備**: 対象プロンプトを確定し、次の 2 つを用意する。
   - **評価シナリオ** 2 〜 3 種（中央値 1 + edge 1 〜 2）。現実に起こりうるタスクで、対象プロンプトを実際に適用する場面を想定する。
   - **要件チェックリスト**（精度算出のため）。シナリオごとに「成果物が満たすべき要件」を 3 〜 7 項目で列挙する。精度 % = 満たした項目数 / 全項目数。事前に固定すること（後から動かさない）。
2. **バイアス排除読み**: 指示を「白紙」の実行者に読ませる。Task tool で **新規 subagent を dispatch** する。自己再読で済ませない（直前に書いた文章を客観視することは構造的に不可能）。並列で複数シナリオを同時実行する場合は単一メッセージ内で複数 Agent 呼び出しを並べる。dispatch 不能環境の扱いは「環境制約」節を参照。
3. **実行**: 後述の **subagent 起動契約** に従ったプロンプトを subagent に渡し、シナリオを実行させる。実行者は実装や出力を生成し、最後に自己申告レポートを返す。
4. **両面評価**: 戻ってきた結果から次を記録する。
   - **実行者の自己申告**（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] の付け外しをしない。
5. **差分適用**: 不明瞭点を潰す最小修正をプロンプトに入れる。1 イテレーション 1 テーマ（関連する複数修正は OK、無関係な修正は次回に回す）。
   - **修正前に「この修正が要件チェックリスト / 判定文言のどの項目を満たすか」を明示する**（軸名から推測した修正は届かないことが多い。後述「修正の波及パターン」節）。
   - **まず失敗パターン台帳を参照する**。構造化された振り返りの `General Fix Rule` が既存エントリと一致するなら、最初に問うべきは「既存の修正はなぜ再発を防げなかったのか」。新しい台帳エントリを追加する前に、修正の位置をプロンプト冒頭寄りに移す、あるいは文言を書き直す必要があるかもしれない。
6. **再評価**: 新しい subagent で再度 2 → 5 を回す（同一 agent は再利用しない: 前回の改善を学習している）。並列度はイテレーションを進めても改善が頭打ちにならない場合に増やす。
7. **収束判定**: 目安「連続 2 イテレーションで新規の不明瞭点ゼロ かつ メトリクス改善が閾値以下（後述）」で停止。重要度が高いプロンプトは 3 連続にする。

## 評価軸

| 軸 | 取り方 | 意味 |
|---|---|---|
| 成功/失敗 | 実行者が意図した成果物を出したか（二値） | 最低ライン |
| 精度 | 成果物が要件を何 % 満たしたか | 部分成功の程度 |
| ステップ数 | 実行者が使ったツール呼び出し / 判断ステップ数 | 指示の無駄遣いの指標 |
| 所要時間 | 実行者の duration_ms | 認知負荷の代替指標 |
| 再試行回数 | 同じ判断を何度やり直したか | 指示の曖昧さのシグナル |
| 不明瞭点（自己申告） | 実行者が箇条書きで列挙 | 質的な改善材料 |
| 裁量補完箇所（自己申告） | 指示で決まっていなかった判断 | 暗黙の仕様の炙り出し |

**重み付け**: 質的（不明瞭点・裁量補完）を主、量的（時間・ステップ数）を補助とする。時間短縮だけ追いかけるとプロンプトが痩せすぎる。

### `tool_uses` の質的解釈

精度だけ見ると skill の問題が隠れる。`tool_uses` を **シナリオ間の相対値** として使うと構造的欠陥が見える:

- シナリオ間で他シナリオ比 **3-5 倍以上** なら、その skill は **decision-tree index 寄りで自己完結性が低い** サイン。実行者が references descent を強いられている
- 典型例: 全シナリオ `tool_uses` が 1-3 なのに 1 シナリオだけ 15+ → そのシナリオ用の recipe が skill 内に無く、references/ を横断探索している
- 対処: iter 2 で「最小完成例 inline」や「いつ references を読むかの指針」を SKILL.md 冒頭に追加すると `tool_uses` は大幅低下する

精度 100% でも `tool_uses` の偏りがあれば iter 2 発動の根拠になる。「精度のみで判断して打ち切り」は構造的欠陥を見逃しがち。

### 修正の波及パターン (保守 / 上振れ / ゼロ振れ)

修正→効果は線形ではない。事前見積もりは次の 3 パターンが起こりうる:

- **保守的に振れる** (見積もり > 実測): 1 修正で複数軸狙ったが 1 軸しか動かなかった。「複数軸狙いは外しがち」
- **上振れ** (見積もり < 実測): 1 つの構造的な情報 (例: コマンド + 設定 + 期待出力の組合せ) が複数軸の判定文言を同時に満たした。「情報の組合せが構造的に多軸に効く」
- **ゼロ振れ** (見積もり > 0、実測 = 0): 軸名から推測した修正が、判定文言のどれにも届かなかった。「軸名と判定文言は別物」

これを安定させるには **差分適用前に subagent に「この修正が判定文言のどれを満たすか」を言語化させる**。閾値文言レベルで紐付けないと見積もり精度が出ない。評価軸を新設するときも、各点の判定基準を閾値文言レベルまで具体化しておくこと（「全部明示」「動く最小構成全文」のように、何があれば 2 点になるか 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 回クリア）に届かないとき、局所最適を疑って 2 バリアント回す:

- **Conservative バリアント**: 現在のプロンプト + 次善の小さな修正
- **Exploratory バリアント**: 現在のプロンプトに構造変更を 1 つ入れる — 節の並べ替え、密な段落の分割、冗長節の削除、あるいは欠けている scaffolding（動作例など）の追加

同じシナリオに新規 subagent を並列 dispatch する（単一メッセージで複数 Agent 呼び出し）。精度が高い方を採用；同率なら不明瞭点の少ない方；さらに同率なら `tool_uses` の少ない方。

ペアワイズ比較の注意:
- subagent に「A vs B」を直接評価させ **ない**。LLM の位置バイアスと self-preference バイアスにより、小サンプルでは判定がノイジーになる。
- 客観的な軸（精度、ステップ数、不明瞭点数、フェーズ弱点数）のみで比較する。これらは再現可能だが「どちらのプロンプトが良く感じたか」は再現不能。
- 質的比較が本当に必要なら、counterbalance する: 両順序 (A,B) と (B,A) を走らせ、両方が一致したときのみ判定を採用する。

コスト: バリアント探索はイテレーションあたりの 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 シナリオは過適合する。最低 2、できれば 3。 |
| 「不明瞭点ゼロが 1 回出たから終わり」 | 偶然なこともある。連続 2 回で確定判定。 |
| 「複数の不明瞭点を一気に潰そう」 | 何が効いたか分からなくなる。1 イテレーション 1 テーマ。 |
| 「関連する微修正も純粋に 1 件ずつ別 iter に分けよう」 | 逆方向の罠。"1 テーマ" は意味単位。関連する 2-3 件の微修正は 1 iter にまとめて良い。分けすぎると iter 数が爆発する。 |
| 「メトリクスが良いから質的フィードバックは無視」 | 時間短縮は痩せすぎのサインにもなる。質的を主に。 |
| 「書き直した方が早い」 | 3 回以上不明瞭点が減らないなら正解。それ以前の段階では逃げ。 |
| 「同じ subagent を使い回そう」 | 前回の改善を学習している。毎回新規に dispatch する。 |

## よくある失敗

- **シナリオが楽すぎる / 難しすぎる**: どちらもシグナルが出ない。現実の使用場面の中央値を 1 つ、edge を 1 つ
- **メトリクスだけ見る**: 時間短縮しか追わないと、重要な説明が削られて脆くなる
- **イテレーションごとに変更多すぎ**: 「あのときの修正のどれが効いたか」が追えなくなる。1 修正 1 イテレーション
- **シナリオを修正に合わせてチューニング**: 不明瞭点が潰れたように見せるため、シナリオ側を簡単にする → 本末転倒

## 関連

- `superpowers:writing-skills` — skill 作成時の TDD アプローチ。本 skill の「subagent で baseline → 修正 → 再実行」と本質的に同じ
- `retrospective-codify` — タスク後の学び固定化。本 skill はプロンプト開発中、retrospective-codify はタスク終了後、と使い分ける
- `superpowers:dispatching-parallel-agents` — 複数シナリオを並列で走らせるときの作法
- `waxa-eval` — `waxa` CLI の運用マニュアル。 eval / iterate ループを YAML scenario と永続 ledger で外部プロセスに自動化する。 本 skill (empirical-prompt-tuning) は **方法論と session 内 Task-tool subagent フロー**、 `waxa-eval` は **CLI 操作と YAML authoring** を担当する補完関係。 empirical は Iter 0 の静的整合チェック、 `[critical]` タグ付きチェックリスト、 `tool_uses` ベースの skill 診断 (CLI プロセスからは届かない領域) を担う。 waxa-eval は永続性 / CI 再現性 / 外部 adoption gate が要るときに使う。

## 出典

本 skill は [mizchi/skills](https://github.com/mizchi/skills/tree/main/empirical-prompt-tuning) (`empirical-prompt-tuning` ディレクトリ) の SKILL-ja.md (commit `0b197be`) を pev-harness に取り込んだもの。 上流の変更を取り込むときは raw URL を直接更新するのではなく、 本 skill の Related 節と pev-harness の他 skill (pev-pipeline / pev-spec-template 等) との cross-reference を保ったまま reconcile する。
