# Empirical Prompt Tuning

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

- Skill: `nwiizo/empirical-prompt-tuning` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nwiizo/empirical-prompt-tuning`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nwiizo/empirical-prompt-tuning/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: nwiizo (https://skillmd.com/u/nwiizo)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/nwiizo/empirical-prompt-tuning

---


# Empirical Prompt Tuning

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

**用語**: Task tool / Agent tool で起動する新規 agent を「実行者（= subagent）」と呼ぶ。起動操作を「dispatch」と呼ぶ。以下「実行者」で統一する。

## いつ使うか

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

使わない場面:
- 一回限りの使い捨てプロンプト（評価コストが割に合わない）
- 成功率の改善が目的ではなく、書き手の主観的好みを反映したいだけのとき
- 汎用的な Build→Test→Feedback ループ（`iterative-refinement` の守備範囲）。本 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）
   - **Iter 0 で合わせきれない乖離の扱い**: description が要求する具体性が body 側に欠けていて Iter 0 単独では埋められない場合（frontmatter を持たないプレーンテキスト対象を含む）、乖離を Iter 1 の修正対象として記録のうえ先に進む。対象に frontmatter がない場合は「冒頭 1 文 = description 相当、以降 = body 相当」として扱う

1. **ベースライン準備**: 対象プロンプトを確定し、次の 3 つを用意する。
   - **評価シナリオ** 2 〜 3 種（中央値 1 + edge 1 〜 2）。現実に起こりうるタスクで、対象プロンプトを実際に適用する場面を想定する。
   - **hold-out シナリオ** 1 本。収束判定時の過適合チェック専用で、baseline と同じタイミングで設計・封印する（イテレーション後に作ると改善済みプロンプトに無意識に最適化される）。評価シナリオと hold-out を合わせて最低 3 本を確保。
   - **要件チェックリスト**（精度算出のため）。シナリオごとに「成果物が満たすべき要件」を 3 〜 7 項目で列挙する。`[critical]` タグ付き項目を最低 1 つ含める（0 件だと成功判定が vacuous になる）。事前に固定し、後から動かさない。
2. **バイアス排除読み**: 指示を「白紙」の実行者に読ませる。Task tool で **新規実行者を dispatch** する。自己再読で済ませない（直前に書いた文章を客観視することは構造的に不可能）。並列で複数シナリオを同時実行する場合は単一メッセージ内で複数 Agent 呼び出しを並べる。dispatch 不能環境の扱いは「環境制約」節を参照。
3. **実行**: 後述の **subagent 起動契約** に従ったプロンプトを実行者に渡し、シナリオを実行させる。実行者は実装や出力を生成し、最後に自己申告レポートを返す。
4. **両面評価**: 戻ってきた結果を記録する。
   - **実行者の自己申告**（レポート本文から抽出）: 不明瞭点 / 裁量補完 / 再試行回数（同じ判断をやり直した回数と理由。「同じ判断」はツール呼び出し単位ではなく意思決定ステップ単位）
   - **指示側の計測**（判定ルールは「評価軸」節に一元定義）:
     - `tool_uses` / `duration_ms` を Agent tool レスポンスの usage メタから取得
     - **失敗時は「どの [critical] 項目が落ちたか」を提示フォーマットの "不明瞭点" 節に 1 行添える**（原因追跡のため）
5. **差分適用**: 不明瞭点を潰す最小修正をプロンプトに入れる。1 イテレーション 1 テーマ（関連する複数修正は OK、無関係な修正は次回に回す）。
   - **修正前に「この修正が要件チェックリスト / 判定文言のどの項目を満たすか」を明示する**（軸名から推測した修正は届かないことが多い。後述の「修正の波及パターン」節）。
6. **再評価**: 新しい実行者で再度 2 → 5 を回す（同一実行者は再利用しない: 前回の改善を学習している）。
7. **収束判定**: 詳細条件は「反復の打ち切り基準」節に一元化。

## 評価軸

判定ルールの一元定義箇所。他節はここを参照する。

| 軸 | 取り方 | 意味 |
|---|---|---|
| 成功/失敗 | `[critical]` 項目が **全て ○** のとき ○、1 つでも × または部分的なら × | 最低ライン（二値） |
| 精度 | ○ = 満点、× = 0、部分的 = 0.5 で合算し全項目数で割る（%）。`[critical]` が部分的のときも 0.5 寄与するため「× 85%」のような行は正常 | 部分成功の程度 |
| ステップ数 | `tool_uses`（Read / Grep も含める、除外しない） | 指示の無駄遣いの指標 |
| 所要時間 | `duration_ms` | 認知負荷の代替指標 |
| 再試行回数 | 同じ意思決定ステップをやり直した回数（ツール呼び出し単位ではない） | 指示の曖昧さのシグナル |
| 不明瞭点（自己申告） | 実行者が箇条書きで列挙 | 質的な改善材料 |
| 裁量補完箇所（自己申告） | 指示で決まっていなかった判断 | 暗黙の仕様の炙り出し |

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

**計測の fallback**: `tool_uses` / `duration_ms` は Claude Code の Agent tool レスポンス末尾 `<usage>` メタから取得する。環境により usage メタが返らない場合は subagent 自己申告に格下げ（レポート末尾に「使用ツール数 / 所要秒数」を書かせる）。

### `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. <通常項目>
...

## タスク
1. 対象プロンプトに従ってシナリオを実行し、成果物を生成する。
2. 終了時に下記レポート構造で返答する。

## レポート構造
- 成果物: <生成物 or 実行結果サマリ>
- 要件達成: 各項目について ○ / × / 部分的（理由付き）
- 不明瞭点: 対象プロンプトで詰まった箇所、解釈に迷った文言（箇条書き）
- 裁量補完: 指示で決まっておらず自分の判断で埋めた箇所（箇条書き）
- 再試行: 同じ意思決定ステップをやり直した回数とその理由
```

呼び出し側メモ（実行者には渡さない）: `[critical]` 最低 1 件の制約チェック、レポートからの自己申告抽出、`tool_uses` / `duration_ms` の usage メタ取得はすべて呼び出し側の責務。

## 環境制約

新規実行者を dispatch できない環境（既に subagent として動作している、Task tool が無効化されている等）では、**この実行インスタンスからは** 本 skill を実行しない。
- 代替案 1: 親セッションのユーザーに別 Claude Code セッションを起動して依頼してもらう
- 代替案 2: 評価を諦め、ユーザーに「empirical evaluation skipped: dispatch unavailable」と明示報告する
- **NG**: 自己再読で代替する（バイアスが入るので評価結果を信じてはいけない）

**部分失敗**: 並列 dispatch で一部の実行者が timeout / error で終わった場合、完了分だけで評価しない（シナリオ欠損は比較の前提を崩す）。該当シナリオを新しい実行者で再 dispatch する。

**継承される文脈**: 新規 subagent であっても親セッションの CLAUDE.md やグローバルルールは継承される。「コンテキスト完全ゼロ」ではなく「対象プロンプトについての記憶だけがゼロ」と理解すること。完全な隔離が必要なら別セッションからの起動（代替案 1）を選ぶ。

## 構造審査モード

empirical 評価ではなく、プロンプトの **記述の整合性・明瞭性だけ** をチェックしたい場合のモード。dispatch 可能・不可能にかかわらず選択できる。実行者への依頼プロンプトに「今回は構造審査モード: 実行ではなくテキスト整合性チェック」と明記する。構造審査は empirical の代替ではなく補助（連続クリア判定には使えない）。

## 反復の打ち切り基準

- **収束（停止）**: 連続 2 回（重要度の高いプロンプトは連続 3 回に引き上げる）で次を **全て** 満たす:
  - 新規不明瞭点: 0 件
  - 精度の前回比改善: +3 ポイント以下（5% → 8% のような飽和）
  - ステップ数の前回比変動: ±10% 以内
  - duration の前回比変動: ±15% 以内
  - **過適合チェック**: 収束判定時、ベースライン準備で封印した hold-out シナリオを投入して評価。精度が直近平均から 15 ポイント以上落ちたら過適合。baseline シナリオ設計に戻って edge を足す。
- **発散（設計を疑う）**: 3 回連続で新規不明瞭点が 0 件にならない → プロンプトの設計方針自体が間違っている可能性。修正パッチで直すのをやめ、構造を書き直す
- **リソース打ち切り**: 重要度と改善コストが釣り合わなくなったら止める（80 点で出す判断）

## 提示フォーマット

実行モードに応じて 3 種類のフォーマットを使い分ける。

### モード 1: empirical（通常）

各イテレーションで次の形で記録・ユーザーに提示する:

```
## Iteration N

### 変更点（前回差分）
- <修正内容 1 行>

### 実行結果（シナリオ別）
| シナリオ | 成功/失敗 | 精度 | steps | duration | retries |
|---|---|---|---|---|---|
| A | ○ | 90% | 4 | 20s | 0 |
| B | × | 60% | 9 | 41s | 2 |

### 不明瞭点（今回新出）
- <シナリオ B>: [critical] 項目 N が × — <落ちた理由 1 行>   ※ 失敗時は必ず添える
- <シナリオ B>: <その他の指摘 1 行>
- <シナリオ A>: （新出なし）

### 裁量補完（今回新出）
- <シナリオ B>: <補完内容>

### 次の修正案
- <最小修正 1 行>

（収束判定: 連続 X 回クリア / 停止条件まであと Y 回）
```

### モード 2: 構造審査（dispatch 不能時の補助）

empirical 表の `精度` / `steps` / `duration` / `retries` 列は実測不能なので **`N/A`** と明記するか、予測値を入れる場合は値の後ろに `(pred)` を付ける。`成功/失敗` は `予測 ○` / `予測 ×` として通常の ○ / × と区別する。表の上に「※ 構造審査モードによる予測。empirical 実測ではない」の 1 行を添える。収束判定カウントには算入しない。

- **「不明瞭点（今回新出）」見出し**: モード 1 をそのまま流用してよいが、各項目に `(予測)` を付けて実測由来でないことを示す
- **hold-out シナリオ**: 構造審査では使わない（収束判定が算入外のため過適合チェックが無意味）。hold-out は封印したまま、empirical 可能な環境に戻ったとき初めて投入する
- **繰り返し回数**: 同じ対象に対し構造審査だけで回すのは 1 回まで。同じ審査者で 2 回目を回しても情報増分がほぼ無く、別審査者に変えても実測との整合が取れない。2 回以上回したくなったら dispatch 可能な環境で empirical に戻す

### モード 3: 適用外（使わない場面該当）

イテレーション表は出力しない。次の簡易フォーマットで済ませる:

```
## 適用外判定

### 対象
<対象プロンプト 1 行>

### 該当した「使わない場面」基準
- <基準 1>
- <基準 2（あれば）>

### 代替提案
- <代替 1、なければ「代替なし」と明記>

### ユーザー向け応答
> <そのまま送れる 2-4 行の文面。丁寧・簡潔。「使わない場面」該当理由と代替提案を含める>
```

- dispatch 不能かつ「使わない場面」該当時は **適用外モードを優先** する（dispatch 不能の併記は不要。主因は「使わない場面」であり、dispatch 可否は判断に影響しない）
- dispatch 可能だが「使わない場面」該当時も、このモード 3 を使う（empirical には進まない）

## Red flags（合理化に注意）

| 出てくる合理化 | 実態 |
|---|---|
| 「自分で読み直せば同じ効果がある」 | 直前に書いた文章を "客観視" はできない。必ず新規実行者を dispatch する。 |
| 「1 シナリオで充分」 | 1 シナリオは過適合する。最低 2、できれば 3 + hold-out 1。 |
| 「不明瞭点ゼロが 1 回出たから終わり」 | 偶然なこともある。連続 2 回（重要度高は 3 回）で確定判定。 |
| 「複数の不明瞭点を一気に潰そう」 | 何が効いたか分からなくなる。1 イテレーション 1 テーマ。 |
| 「関連する微修正も純粋に 1 件ずつ別 iter に分けよう」 | 逆方向の罠。"1 テーマ" は意味単位。関連する 2-3 件の微修正は 1 iter にまとめて良い。分けすぎると iter 数が爆発する。 |
| 「メトリクスが良いから質的フィードバックは無視」 | 時間短縮は痩せすぎのサインにもなる。質的を主に。 |
| 「書き直した方が早い」 | 3 回連続で新規不明瞭点が 0 にならないなら正解。それ以前の段階では逃げ（打ち切り基準「発散」節を参照）。 |
| 「同じ実行者を使い回そう」 | 前回の改善を学習している。毎回新規に dispatch する。 |
| 「失敗が続くシナリオは [critical] を外して成功にしよう」 | 基準の事後改変は成功判定を無意味にする。[critical] は baseline で固定、以降触らない。 |
| 「今回のシナリオに合わせてシナリオ側を調整しよう」 | 過適合の誘発。シナリオは固定、動かすのはプロンプト側だけ。 |

## よくある失敗

- **シナリオが楽すぎる / 難しすぎる**: どちらもシグナルが出ない。現実の使用場面の中央値を 1 つ、edge を 1 つ
- **メトリクスだけ見る**: 時間短縮しか追わないと、重要な説明が削られて脆くなる
- **無関係な修正を同一イテレーションに混在させる**: 「あのときの修正のどれが効いたか」が追えなくなる（関連する 2-3 件の微修正を 1 iter にまとめるのは OK。Red flags の「1 テーマ」条件を参照）
- **シナリオ設計者がプロンプト作成者と同一であることを忘れる**: subagent を dispatch してもシナリオ側のバイアスは残る。重要な skill は過去の失敗事例からシナリオを逆算する、または別セッションで生成させる

