プロンプトの改善効果を可視化するClaude Codeプラグインを作った
こんにちは、かがわ(@shinpr_p)です。
プロンプトの書き方が結果にどう作用するのかを理解することは難しいものです。「曖昧な指示は避けよう」「出力形式を明示しよう」みたいな定番のプラクティスはありますが、それに倣って修正をしたとしても、それによって何が変わったのかが分かりづらいです。
私自身はツールを作ったりしている都合上、プロンプトを変え何度も同じタスクをやり直しているから書き方の変更によって何が起こるのかを理解できていますが、それでもたまに罠にハマり意図しない挙動をされることがあります。
今回は、そういった試行錯誤を踏まえて作ったツール(Claude Code Plugin)を紹介します。プロンプトの改善効果を「見える化」することで、この書き方がどういう影響を与えるのかを直感的に理解できることを目指しています。
※ 名前の由来はRashomon effect(一つの出来事について複数の人がそれぞれ異なる、あるいは矛盾する証言や解釈をする現象)からとっています
Rashomonの仕組み
やっていることはシンプルです。
- プロンプトを分析 → よくある問題パターンを検出
- 最適化版を生成 → ベストプラクティスに基づいて改善
- 両方を並列実装 → 完全に隔離された環境でオリジナル・最適化プロンプトを実行させる
- 結果を比較 → 結果を比較し、何がどう変わったかをレポートとして提出
- 振り返り → (optional)比較結果へのフィードバックを踏まえて、プロジェクト固有の知見をナレッジベースとして蓄積し、次回以降の最適化に活用
Git Worktreeを使って隔離された環境で両プロンプトを並列実行するので、実行結果が互いに干渉することはありません。
そして、同じ環境でプロンプトだけが差異となること、実際の実行結果を回収することで、プロンプトの影響を具体例を含めて説明できるようになります。
使い方
このツールはClaude Code Pluginとして提供しています。CCを起動してコマンドを叩き、セッション再起動してもらえればすぐに利用できます。
# 1. Start Claude Code
claude
# 2. Install the marketplace
/plugin marketplace add shinpr/rashomon
# 3. Install plugin
/plugin install rashomon@rashomon
# 4. Session Restart
# 5. run
/rashomon [オリジナルのプロンプトをコマンドに渡してください]
実際に使ってみた例
具体例を見てもらった方が早いので、実際の環境で試してみた例を共有します。
オリジナルのプロンプト
geminiServiceにエラーハンドリングを追加して
分かりやすいようにざっくりめな指示にしています。
Rashomonが生成した最適化プロンプト
## Context
GeminiServiceクラス(`src/application/services/geminiService.ts`)のエラーハンドリングを強化する。
### 現在の実装状況
- `executeWithRetry`: リトライ、エクスポネンシャルバックオフ、TokenLimitError/GeminiApiError対応済み
- `generateContent`: executeWithRetryを使用
- `generateFinalResponse`: executeWithRetryを使用
- `generatePromptReview`: try-catchでGeminiApiErrorをスロー
### 既存のエラーパターン(`src/shared/errors/customErrors.ts`)
- BaseError: 抽象基底クラス(code, statusCode, timestamp, context)
- GeminiApiError: Gemini API関連エラー
- TokenLimitError: トークン上限エラー
### プロジェクト原則
- エラー透明性: エラーは必ず表面化させる(サイレント失敗禁止)
- 唯一の例外: ネットワークリトライ(最大3回、指数バックオフ)
## Task
GeminiServiceの現在のエラーハンドリングを分析し、不足している箇所を特定して強化する。
### 分析観点
1. 各publicメソッドで発生しうるエラーの網羅性
2. エラータイプの適切な分類(リトライ可能/不可能、ユーザー起因/システム起因)
3. ログ出力の一貫性
4. エラーメッセージの日本語対応(非技術職ユーザー向け)
## Constraints
- 既存のBaseErrorパターンに従うこと
- 後方互換性は不要(社内システム)- 古い実装は即削除可
- 継ぎ足しコーディング禁止 - 設計を見直してから実装
- 品質チェック(`npm run check:all`)が通ること
## Output Format
1. **現状分析**: 各メソッドのエラーハンドリング状況と不足点
2. **改善提案**: 具体的な変更内容(必要な場合のみ)
3. **実装**: 提案が承認された場合のコード変更
### 判断基準
- 現在のエラーハンドリングが十分な場合は、その旨を報告し不要な変更は行わない
- 改善が必要な場合は、具体的な理由と期待効果を説明する
だいぶ詳細になりました。そして、今回の実行結果を左右したのは判断基準です。
実行結果の比較
| 項目 | オリジナル | 最適化版 |
|---|---|---|
| 所要時間 | 約120秒 | 約45秒 |
| 変更ファイル | 1 | 0 |
| 結果 | try-catch追加 | 「既存で十分」と判断 |
最適化版のプロンプトは、言われた通りに「エラーハンドリングを追加」するのではなく、まず現状を分析し「既に十分なエラーハンドリングがある」と判断し、変更を行いませんでした。
所要時間の差は、最適化版が「現状で十分」と早期に判断し、不要な実装作業をスキップできたためです。判断基準を与えることで無駄な作業が減るという効果が表れています。
このケースにおけるポイントは2つあります。
「追加して」という指示の落とし穴
「追加して」と言われると、LLMは何かを追加しようとします。当たり前ですね。追加することが目的になってしまうので、エラーハンドリングとして達成したいことが作業の目的にはなりません。
要否に関わらず追加をすればゴールなので、結果的に無駄なエラーハンドリングを追加してしまう可能性が生じます。
「変更しない」という選択肢を与える
最適化版のプロンプトにはこう書かれていました。
現在のエラーハンドリングが十分な場合は、その旨を報告し不要な変更は行わない
この一文があるだけで、LLMは「何も変更しないのもアリ」と理解できます。これはBP-008(不確実性を許容する指示)の考え方の応用です。本来は「分からないなら分からないと言っていい」という確信度の話ですが、「判断に自信がないなら無理に行動しなくていい」という余地を与えることで、過剰な変更を防ぐ効果があります。
さいごに
プロンプトの書き方がしっくりくるまでには時間と場数が必要です。
また、「こう書くといい」と言われても、自分のケースに当てはめたときにどう書くといいんだろう?に答えてくれる人が身近に常にいるとも限りません。
プロンプト力をあげたい。AIの想定外の挙動を制御したい。でも具体的にどうやったらいいのかいまいちわからない。そのような悩みをお持ちの方は、ぜひ一度このツールを使ってみてください。
おまけ: 検出する8つの問題パターン
Rashomonは以下のパターンを検出し、最適化します。これらは2024-2025年のプロンプトエンジニアリング研究の中から汎用的に有益なものをピックアップしたものです。
- BP-001: ネガティブ指示(「〜しないで」は守られにくい→「〜だけして」に変換)
- BP-002: 曖昧な指示(スコープ・形式を明確化)
- BP-003: 出力形式の欠落
- BP-004: 非構造化プロンプト(Context/Task/Constraints/Output Formatに整理)
- BP-005: コンテキスト欠落
- BP-006: 複雑なタスクの分割不足
- BP-007: バイアスのある例示
- BP-008: 不確実性許容の欠落
Discussion