mcpField
P
prompt-engineering

prompt-engineering

github.com/doodledoodエージェントワークフロー78104 回インストール1 日前に更新
リポジトリ

prompt-engineering について

`prompt-engineering`は、モデルの実行結果を改善したいプロンプト作成者向けの、プロンプトの作成・保守スキルです。実行時に与えられた入力を先に確認し、各行の出所、配置、表現を基に必要性を判断して、内容を絞り込みます。

主な機能

  1. 01不足、矛盾、古さ、ノイズのある入力を診断
  2. 02情報の出所から指示の要否を判断
  3. 03手順、参考資料、ポインターに整理
  4. 04重複、無関係な情報、環境で確認可能な事実を削除
  5. 05表現、境界条件、更新の影響を確認

活用シーン

  1. 01モデルの実行結果が悪い原因の診断
  2. 02常時読み込まれるプロンプトやプロジェクト指示の整理
  3. 03入力の不足を解消するプロンプトの更新
  4. 04重複や意図しない制約がないか編集内容を確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/doodledood/manifest-dev --skill prompt-engineering

インストール後、Claude Code で/prompt-engineeringを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
mechanics.md
metaprompting.md
system-prompts.md

詳細

プロンプトは目標を示し、それ以上は干渉しません。それ以外の内容はすべて負荷です。実行のたびに消費され、モデルが本来なら作業に向ける注意を奪うため、各行はコスト以上の価値を生まなければなりません。以下では、実行に何を与えるか、行を入れるかどうか、どこに置くか、どう表現するかという4つの点を決めます。

実行に与えられる情報

実行の結果は、プロンプトと、テンプレートに入力された値、読み込むファイル、取得した情報、ツールの出力、ここまでの会話、引き継ぎ先のエージェントが受け取るものなど、実行に与えられるすべての情報によって決まります。通常、モデルには十分な能力があるため、出力の問題はたいてい入力に原因があります。実行のパフォーマンスが低いときは、表現を変える前に、テンプレートだけでなく、トレースや入力済みのプロンプトなど、実際に与えられた情報を確認し、次の4つの問題がないか探します。

  • 不足 — タスクに必要な情報がなく、実行が推測します。
  • 矛盾 — 2つの情報が食い違い、実行がどちらかを選びます。
  • 誤りまたは古い情報 — 情報が正しくない、あるいは古く、実行がそれを繰り返します。
  • ノイズ — 重要な情報はあるものの、タスクに関係のない内容に埋もれています。

まず入力を修正します。不足している情報、またはその情報にたどり着ける参照先を加え、食い違う情報は一方を選び、誤った情報は修正または削除し、重要な情報を埋もれさせている内容は削ります。通常、これはほかのどの変更よりも結果を改善します。表現の修正や事後の対処、つまりレビュー、セルフチェック、失敗後に追加するルールは、その後に行います。誤った入力を補う修正では、問題そのものが残り、次の実行でも同じ問題が起きます。

タスクに対して十分であることが、完全であるということです。通常、修正では、情報を増やすのではなく、ノイズを削って不足している情報を補います。入力がすでに完全で一貫しており、不要な情報もない場合は、指示を見直します。どのような入力を与えてもモデルにできないことがある場合は、アーキテクチャを変更します。

その行の出どころ

その行が役に立つかどうかを問う前に、これを確認してください。ある行は正しく、関連性があっても、削る価値があることがあります。したがって、有用かどうかだけでは判断できません。決め手になるのは出どころであり、記憶を頼りに答えられます。

  • ユーザーが明示したこと — ユーザーが述べた決定、好み、制約です。そこから導き出されたものではありません。残してください。
  • 実行時には手が届かないところにある事実 — 書かれていない慣習、実際に目にした失敗、実行時に読み込まれる情報の範囲外にある事実です。残し、古くなる可能性のある内容を写すより、出典への参照を優先してください。
  • モデルが取るのを実際に見た既定の振る舞いを打ち消すもの — その既定の振る舞いが、懸念ではなく観察に基づく場合は残してください。
  • 実行時にも読み込まれる資料から導き出したこと — 削ってください。コーパス内で得られる結論は、実行時に自らたどり着けるものです。書き留めても何も得られず、実行のたびに負荷だけが増えます。

最後の分類は、自分で導き出すために労力をかけたぶん、最も残す価値があるように感じられます。そして、仕様を過剰に書き込む原因にもなります。見分ける手がかりは二つあります。実行時に得られるものと同じ情報源から正当化できる行と、上の指示を説明しているだけで、先に述べたテストを通る新たな情報を加えていない文です。

依頼で未決のまま残された選択は、依頼した人に委ねてください。 追加しようとしている内容のなかには、水増しではなく、候補の優先順位や、示されたルールの例外、依頼されていない成果物など、ひとつの決定が含まれていることがあります。それは丁寧さのように見えますが、依頼した人が選んでもいないことを、その人の名のもとに決めてしまい、後で引用されるファイルに残すことになります。その答えによって作業が変わるのはどこかを考え、変わらないところには書かないでください。

完成したプロンプトは、予想よりも短く見えます。それは警告ではなく、そうなるべき結果です。 二つの判断と目標だけなら、短い文書になります。そこで、優先順位の付け方についての節や、用語そのものの定義、誰も求めていない三つ目の証拠源を加えたくなります。しかし、そうして加えようとするものは、すべて上記の分類に当てはまります。短すぎるように感じたら、目標が明記され、判断が含まれていることを確かめたうえで、公開してください。

反実仮想の問い――この行がなければ、モデルはそうするだろうか?――は、モデル自身の振る舞いを予測するよう求めていますが、内部から確実に答えられる問いではありません。すでに認められた出どころを持つ行について、二番目に問いかけてください。この問いで、出どころが認められた行を削ることはできますが、出どころが認められなかった行を残すことはできません。

ある行が役に立っているかどうかで意見が分かれたとき、議論になっているのはモデルの既定の振る舞いです。そこで、その行を取り除いた文書を実行し、結果を比較して決着をつけてください。これは手間をかける価値があるときに使える最終判断の方法であり、すべての行が必ず通過しなければならない手順ではありません。

上へ向かって書く

目標を述べた文から始めてください。上の問いで認められたものだけを、一行ずつ加えてください。

幅広く書いてから削る方法は、より手間がかかり、最終的に長くなります。削る行はすべて、すでに必要だと主張したものですし、下書きに費やした労力そのものが、必要性の証拠のように感じられるからです。

二つの負荷

加えるものはすべて、次の二種類のどちらかの負荷を生みます。

  • コンテキスト負荷 — 常に読み込まれる情報で、使われるかどうかにかかわらず、毎回のターンで負担が発生します。スキルの説明、AGENTS.md のルール、常駐するあらゆる情報が該当します。
  • 認知負荷 — どの文書があり、それぞれにいつ目を通すかなど、人が把握しておく必要のあることです。ゼロにするべき負荷ではありません。人間の判断力を活かすために必要な負荷です。判断が重要なところにかけてください。

参照先を示す一行分の負荷だけで済むなら、その参照先にある情報はコンテキスト負荷を免れます。参照先のない情報は、すべて人が覚えておかなければなりません。

文書内での配置

実行時に必要となる即時性の順に、3つの段階があります。順に実行する手順、必要に応じて参照するリファレンス、そしてポインターをたどった先の別ファイルにある開示リファレンスです。情報を下の段階に移すと冒頭が読みやすくなりますが、移しすぎると実行に必要なものが見えなくなります。どこまで分岐するかで決めます。すべての経路で必要な情報は本文に記載し、一部の経路だけで参照する情報は別ファイルに開示します。

ルールの記述、その適用範囲、例外は、1つの見出しの下にまとめ、どれかを読めばほかも読めるようにします。文書内で分割されたルールは、やがて2つに分かれてしまう1つのルールです。

ポインターとは、文脈外の情報と、それを参照する条件を示す行です。スキルの説明やリファレンスへのリンクがこれに当たります。実行時にそこへ到達するかどうかを決めるのは、リンク先ではなくポインターの文言です。したがって、到達のきっかけとなる語を先頭に置き、異なるケースごとにトリガーを1つ示し、リンク先がすでに説明している内容は省きます。情報にたどり着く必要があるのにポインターが弱い場合は、その情報を本文に移す前に、まず文言を明確にします。

言葉選び

モデルがすでに知っている言葉を選びます。 事前学習で獲得された relentless、tight、adversarial などの語は、複数の語を使う表現よりも少ないトークンで事前学習済みの知識を呼び起こし、行動の方向性を定めます。指示が弱すぎる場合は、言葉を増やすのではなく、より強い語を使います。造語では何も呼び起こせないため、実在する語なら説明なしで伝わることを、定義によって補わなければなりません。

同じ活性化の仕組みは、単語から規律全体にまで及びます。 事前学習済みの概念である adversarial verification、rival explanations、goal-based などは、その実践に関してモデルがすでに持つ知識をすべて呼び起こします。そのため、明確な目標にこうした概念をいくつか添えるだけで、モデルがいずれにせよ再構築するプロセスを何ページ分も代替できます。プロンプト全体も、この形を優先します。目標と拘束力のある裁定を示し、各規律をそれを呼び起こす言葉で名付け、進め方はモデルに委ねます。土台がしっかりするのは、目標と裁定に拘束力があるからであり、すべての手順が書かれているからではありません。プロセスを詳しく書くと、能力の高いモデルを1つの経路に縛ることになりますが、潜在的な規律はあらゆる経路をカバーします。

禁止事項ではなく、目標を示します。 禁止事項は禁じる行動を名指すため、その行動をかえって想起させてしまいます。否定表現は、強く活性化された概念にかかる弱い修飾にすぎません。長いコメントを書かない よりも、コメントは1行で書く のほうが効果的です。肯定的な表現にできない場合に限って禁止事項をガードレールとして残し、肯定的な目標と組み合わせます。

すべての手順は、実行時に確認できる条件で終えます。 理解できたら完了 という条件では、まだ先の手順が見えていて、完了することに注意が向くため、早く止めてしまいがちです。まず境界を明確にします。手順を分割して効果があるのは、実際に文脈が切り替わる場合だけです。本文に後続の手順への言及があれば、後続の手順は引き続き見えているからです。表現によって、その手順が求める作業量も変わります。呼び出し元を列挙する ではなく、すべての呼び出し元を漏れなく列挙する とすれば、網羅的な確認を促せます。

判断が必要な場面には、絶対的な指示ではなくルールを与えます。 決めつける前に必ず確認する は過剰に適用されます。一方、不足している事実によって行動が変わる場合は確認し、そうでなければ前提を明示して進める なら実際に適用できます。MUST と NEVER は、真に不変のルールに限って使います。

過度な緊張感を避けます。 緊急性を強調する表現、大文字だけの命令、過剰な称賛は、行動を測定可能なほど変化させます。プレッシャー下では手を抜く方向に、お世辞を受けたときは同意する方向に働きます。反復的な作業では、失敗を当然のものとして扱います。この方法がうまくいかなければ、別の方法を試してください。 冒頭の書き方が、それ以降すべての文体を定めます。

削減

  • 1つの意味は1か所に。 同じルールが2つのファイルにあると、内容が変化していくテキストが2つでき、そのうち読まれるのは1つだけです。意図的に 単語 を繰り返すのは正反対のやり方で、問題ありません。
  • 環境は信頼できる情報源です。 package.json、設定ファイル、または --help がすでに答えていることをプロンプトで言い直すのは、古くなるキャッシュです。ファイルに書かれていないことだけを記録してください。暗黙の慣例、その理由、落とし穴などです。
  • 正確さだけでなく、関連性も行ごとに確認してください。 ある行が正しくても、ドキュメントの役割に関係しなくなっていることがあります。確認を怠ると、誰も取り除こうとしない層がプロンプトに積み重なります。
  • 文ごとに、何もしない指示を探してください。 モデルがすでに従う指示は、何も言わないのに読み込みコストだけを発生させます。言葉を削るのではなく、文全体を削除してください。

境界

ある行が必要でも、プロンプトが実際に実行される環境では問題を起こすことがあります。想定される条件に照らして、1つずつ確認してください。

  • 能力を平易な言葉で示し、モデル自身に利用可能な手段を見つけさせるべきところで、ハーネスに依存するプリミティブ、つまり特定のツール、スケジューラー、CLI を指定していないか。
  • 原則が対象とするケースを、限定句がひそかに除外していないか(モード X で、別のレビュアーによって)。
  • 原則を示すべきところで、固定された手順やハードコードされた数値など、特定の仕組みを唯一の方法として示していないか。数値はデフォルト値にとどめてください。

更新

望ましくない結果を受けて変更する場合は、まず 実行時に与えられている情報 を確認し、入力で説明されていないことだけをプロンプトの行に反映してください。何かを変更する前に、その行が埋めるギャップを特定します。最善の変更はたいてい、行を追加するのではなく置き換えるものです。また、新しく明示したルールによって、以前の曖昧な留保が不要になることもよくあります。変更量は増えても減ってもかまいません。目標は方向ではなく、バランスです。

更新後のプロンプトは、現在の役割に合わせて今日書かれたように読める必要があります。以前の行に何が書かれていたか、いつ、なぜ変更したか、誰が依頼したかは、コミットメッセージか意思決定記録に、プロンプトファイルの外で記録してください。プロンプトに残すと、実行のたびに読み込みコストがかかり、指示として従われる可能性もあります。ルールが成立する理由は残してもかまいません。判定内容を残し、判定したという注記は残さないでください。

編集後は、変更した行だけでなく、新しく参加した人の視点でファイル全体を読み直してください。各ルールは1度だけ述べられているか、新しい行と矛盾したり重複したりするものはないか、冒頭は引き続きプロンプトの役割を説明しているかを確認します。履歴の注記や、新しいルールによって不要になった留保は、どこにあっても削除してください。それらを削除してもルールは変わらないため、依頼者に判断を委ねる必要はありません。

観察された1つの失敗に対して、過剰に防御しないようにしてください。1つの事例なら修正で十分です。セクションを設けるのは過剰な修正です。

参考資料

  • references/mechanics.md — 形式について。スキルのフロントマター、命名、レイアウト、エージェントの分離と能力宣言、振る舞いではなくデータが不足しているナレッジスキル。
  • references/system-prompts.md — デプロイループで使われるシステムプロンプトと、そのための既成ブロック。検証パス、ツール呼び出し予算、曖昧さへの対処、出力仕様、高リスク時のセルフチェックなど。この成果物に限ります。
  • references/metaprompting.md — ログに記録されたトレースを使って、失敗するプロンプトを診断する方法。

コメント