😽
プロンプトエンジニアリング再入門
はじめに
社内で、具体的な業務ユースケースに即して実践的なプロンプトエンジニアリングをみんなで模索しまくる、みたいな勉強会のような企画を開催してみたところ、プロンプトエンジニアリングなんてもうわかりきったものだと思い込んでいましたが、意外と(やはり?)奥が深く、いろいろな学びが得られました。かいつまんで言うと以下のようなものです。
実践的なプロンプトを書くためのtips
- 一方通行的に、自然な流れで考えさせる。行ったり来たりさせない。
- ステップを分けて、ステップごとにプロンプト自体を分けて一つずつ実行する。
- 決定論的な判断は、JSONやYAML形式で出力させ、計算可能なデータとして考えさせる。
- Few Shotは実はそれほどこだわらなくてもいい。(どちらかと言えばステップ実行とかJSON/YAML思考のほうが効き、Few Shotはユースケースとプロンプトの組み合わせによってはよって効いたり効かなかったりしている)
- Temperatureはつねに0がいいとは限らない。0.3くらいで安定しているケースが多かった。
最近のモデルは非常に精度が高くなってきていて、個人でLLMを触っているときはあまりプロンプトを意識する必要がなくなってきましたが、やはり業務用アプリとなってくると複雑な概念の操作やデータの処理が求められるので、なんだかんだ言ってプロンプトエンジニアリングはいまだ重要です。このようにベストプラクティスを探り続け、勘所をためていくのはまだまだ必要なように思えます。
というわけで、今回の知見をChatGPT o1にインプットして、網羅的に整理してもらったのが以下です。ぜひ参考にしてください。
1. 目的・ゴールの明確化
ポイント
- 「どんな出力を求めているのか?」をはっきり書く。
- 回答のスタイル(短文・長文、客観・創造的)や、回答内容の要件(構造化・要約・分析)などを可能な限り具体的に指定する。
具体例
- 「このテキストを300文字以内で要約してください。専門用語は極力避け、初心者向けに書いてください。」
- 「新商品○○について、若い女性向けの宣伝コピーを提案してください。ポジティブかつ印象に残るフレーズを使ってください。」
注意点
- 目的が曖昧だとモデルの回答にブレが生じやすい。
- 必要に応じて「想定読者」「利用シーン」「背景知識」などを補足して、モデルに正確なゴールを示す。
2. ステップを分けた思考の指示
ポイント
- モデルに一度に多くの要求をしないで、段階的に手順を示す(ステップ・バイ・ステップ)。
- 「まず問題を整理し、次にアイデアを複数出して、最後に絞り込む」など、具体的な進行手順を指示すると、回答が混乱しにくい。
具体例
- 「まずこの問題の論点を3つ挙げて説明してください。次のステップではそれをもとに対策案を考察します。」
- 「以下の手順でやってください:1) 現状を要約 2) 根本原因を特定 3) 対策案を列挙 4) 最も有効と思われる対策を選択」
注意点
- モデルは「ステップ間の文脈」を引き継ぎますが、明確にどのステップの作業をしているのかを指示しないと、「途中で結論を先に書いてしまう」などの混乱が起きがち。
- 手順を箇条書きで書くか、段落を分けて「Step1」「Step2」など明示するとよい。
3. 一方通行での思考を促す
ポイント
- 行ったり来たりをさせると、モデルが迷走しやすくなる傾向がある。
- 「前のステップに立ち返らず、順番通りに進めてください」と指示して、一度終わったステップを再度変更しない方針で進めるのが安定しやすい。
具体例
- 「今のステップでは要約だけを行います。アイデアの抽出や評価は次のステップで行うので、ここでは要約以外は書かないでください。」
- 「先に列挙した情報を修正せず、そのまま使って結論を導いてください。結論の後になって列挙情報を変更しないでください。」
注意点
- 一方通行を貫く場合、修正が必要になるときはあらためて新しいターンを使って「追加要件」を付与する形にする。
- どうしても前のステップを修正したい場合は、そのステップをやり直すような新しいプロンプトを提示するほうが混乱が少ない。
4. プロンプト自体を複数回に分けて実行する(分割実行)
ポイント
- 大きなタスクを1つのプロンプトに詰め込むのではなく、会話形式・マルチターンで分割して行う。
- 各ターンで得られた出力を、次のターンの入力に明示的に取り込むことで、モデルが情報を整理しやすくなり、精度や安定性が向上する。
- “チェーン・オブ・ソート”(Chain of Thought)を人間が制御しながら進めるイメージ。
具体例
-
ターン1(Userメッセージ):
以下の課題文を読んで、重要事項を3点だけ箇条書きにしてください。 ---課題文--- ここに長文や文章が入る -----------
-
ターン1(モデル出力):
1. 〇〇〇 2. 〇〇〇 3. 〇〇〇
-
ターン2(Userメッセージ):
前の出力(重要事項3点)を踏まえて、解決策の案を2つ示してください。
-
ターン2(モデル出力):
解決策1: … 解決策2: …
-
ターン3(Userメッセージ):
解決策1と2のメリット・デメリットを比較し、ベストな案を1つ選んで理由を述べてください。
注意点
- マルチターンで進める場合、前のターンの出力をきちんと引用して、モデルに再掲するようにしましょう(コンテキストが長い場合などに、忘れてしまう可能性がある)。
- 途中で指示を修正する際には、「前のステップの結果を一部訂正してください」など、修正内容を明確に伝えると混乱を減らせます。
5. SystemメッセージとUserメッセージの役割分担
ポイント
- Systemメッセージ: モデルのロール(キャラクター)や大枠の方針、口調・文体、専門性の度合いなどを宣言する。
- Userメッセージ: 具体的な指示や質問を投げる。
具体例
-
Systemメッセージ
あなたは経営コンサルタントとして振る舞います。高度な経営戦略に関する知識を持ち、根拠のあるアドバイスを提供してください。
-
Userメッセージ
中小企業の新規事業計画について、以下の条件でアドバイスをください…
注意点
- Systemメッセージは「会話全体の最上位ルール」なので、話の流れで上書きされにくい。
- 必要に応じてSystemメッセージを更新して、モデルのロールや口調を切り替えることもできる。
6. JSONやYAMLなど構造化出力の指示
ポイント
- 後段でプログラム処理を行いたい場合、JSONやYAMLなどの形式を指定して出力を受け取ると扱いやすい。
- モデルに「この形式のブロック以外は返さないように」と明記すると、余計な文章が混ざりにくい。
具体例
-
JSON出力を要求する
次のスキーマを満たすJSONのみで答えてください: { "summary": string, "ideas": [string, ...] }
-
YAML出力を要求する
以下の構造で出力し、それ以外の文章は書かないでください: summary: "..." ideas: - "..." - "..."
注意点
- それでもモデルが通常の文章を混ぜてしまう場合、再度「構造化のみ」と厳重に指示する必要がある。
- 他にもMarkdownのコードブロックを使うと、構造が守られやすい傾向がある(例:
json ...
)。
7. Few Shotの使い方
ポイント
- 入力例とその理想的な出力例を複数示すことで、曖昧なタスクでもモデルの狙いを“学習”させる。
- 文体や格式、特殊な入力形式などを教える際に有効。
- ただしステップ分割やJSON出力などをキッチリ指定する場合は、必須でないことも多い。
具体例
-
QA形式のFew Shot
例: Q: イギリスの首都はどこですか? A: ロンドンです。 Q: 日本の首都はどこですか? A: 東京です。 次の質問に同じ形式で答えてください: Q: フランスの首都はどこですか?
注意点
- Few Shotサンプルを入れると、その分トークンを消費するので、大規模タスクでは量を最小限に抑える。
- すでにフォーマットが具体的に定義されているなら、Few Shotを使わなくても十分な場合が多い。
8. Temperatureなどパラメータの調整
ポイント
-
Temperature = 0〜1 で創造性や回答の多様性をコントロール。
- 低いほど再現性が高く、正確寄りの回答。
- 高いほど発想が広がり、創造的な表現が増える。
- Top-p, frequency penalty, presence penalty なども合わせて最適化すると、単語の繰り返しを抑えたり、話題を広げたりできる。
具体例
- 創造的なアイデアが欲しいとき: Temperatureを0.7〜1.0に設定。
- 正確な回答(ファクトに基づく)を求めるとき: Temperatureを0.0〜0.3に設定。
注意点
- パラメータ設定はサービス・APIによって異なる(OpenAI API, Azure, 他のLLMなど)。
- 目的が明確なら、複数パターンで試してみて、一番合う設定を選ぶのが早道。
9. 可読性・簡潔性の確保
ポイント
- モデルに渡すプロンプト自体の文章が長いと、どこが重要か見落とされるリスクが高まる。
- 箇条書きや段落構成で、重要指示を埋もれさせない。
- 冗長な背景情報は要約して伝えるか、「重要箇所だけ抜粋」して提示する。
具体例
- 「次の文章を要約します。重要箇所以外は省いてください。分量は200文字以内としてください。」
- 「指示は以下の3点のみなので、他の点には触れないでください。」
注意点
- モデルへの入力(プロンプト)自体に余計な注釈が多いと、誤読や意図と違う出力の原因になりがち。
- まずは必要最低限でプロンプトを作り、問題があれば追加で修正を行う。
10. タスク特化型 vs. 汎用型のバランス
ポイント
-
タスク特化型:特定の目的(翻訳、要約、分析、アイデア出しなど)にフォーカスし、Systemメッセージなどでルールを詳しく定めておく。
- → 安定性・再現性が高い。
-
汎用型:広範囲のリクエストに対応できるよう、ロール設定はざっくりに留めておき、Userメッセージで個別に要件を追加する。
- → 柔軟性があるが、精度が落ちる場合も。
具体例
-
タスク特化例(文章校正ツール)
- Systemメッセージ: 「あなたは優れた校正・編集者です。与えられた文章の文法的ミスやスタイルミスを指摘し、修正案を提案します。」
-
汎用型例(幅広いQA)
- Systemメッセージ: 「あなたは博識なアシスタントです。ユーザーの質問には、できるだけ正確かつ簡潔に答えてください。」
注意点
- 特化型にするほど狙いは絞りやすいが、他の用途では流用しづらい。
- 汎用型にすると回答の幅は広がるが、専門性や精度が下がるリスクもある。
11. 継続的な検証と改善
ポイント
- モデルはアップデートで挙動が変わることがある。
- 定期的にプロンプトを実行し、期待通りの結果が得られるか検証(テストケース)する。
- うまくいかなかったら、指示文やステップ分割、パラメータなどを微調整して再テスト。
具体例
- テストシナリオを複数用意:短い入力・長い入力・曖昧な入力など。
- 実行して結果を評価:チェックリスト(正確さ、フォーマット適合、創造性など)でOK/NGを判断。
- 改善案を考える:ステップ分割をさらに細かくする、分割実行を増やす、Temperatureを調整するなど。
- 再度テストし、比較。
注意点
- ログを保存しておけば、「どういうプロンプトでどんな結果が出たか」を見返しやすい。
- 大幅に指示を変えると、過去のテスト結果と比較が難しくなるので、1回の変更は少しずつが無難。
まとめ
- 目的・ゴールを明確に書き、どんな形式・スタイルで回答してほしいかをしっかり示す。
- ステップを分けた思考や一方通行の流れを指示し、モデルの回答を整理させる。
- プロンプト自体を分割して実行し、前のターンの出力を次のターンの入力に組み込むことで、より高い精度や一貫性が得られる。
- Systemメッセージでモデルのロールやスタイルを定義し、Userメッセージで具体的指示を与える。
- 必要ならJSON/YAMLなどの構造化出力を要求し、プログラムやデータ処理と連携しやすくする。
- Few Shotは形式や文体を教えたいときに使い、トークン消費とのバランスを取りながら最小限にする。
- Temperatureほかパラメータをタスクに応じて調整し、再現性と創造性のバランスを取る。
- 可読性・簡潔性を重視したプロンプトにし、モデルの誤読を防ぐ。
- タスク特化型か汎用型かを事前に検討し、特化型なら安定性が増すが汎用性は下がる。
- 継続的なテストと改善でプロンプトをブラッシュアップし、モデル更新や要件変更に追随する。
これらのポイントを踏まえてプロンプトを設計すれば、安定した高品質の回答を得やすくなります。特に「マルチターンでの分割実行」は、モデルが誤って飛躍した結論を出すのを防ぎ、手順を丁寧に踏ませるうえで強力な手法です。ぜひ試してみてください。
Discussion