FIXERで、プロンプトエンジニアをしている高桑です。
前回では、プロンプトエンジニアはどんな職種なのか、どんなスキルセットを求められるのかを話しました。
※前回の記事「プロンプトエンジニアってどんな職種?内定第1号者としての答え」
今回の記事では、プロンプトの設計方法についてお話します。
論文で提案されているようなプロンプトは、特定の構文やフレーズが多い一方で、この記事では「プロンプトの全体構成を設計するヒント」をお話します。
難問は分割する
複雑なタスクや、論理的な思考を要するタスクの処理においては、途中の処理を明文化すると、意図した生成結果を得られやすいです。
△の例)
商品Aの売上を上げる施策を考えてください。
⚪️の例)
#step-by-stepで実行
Step1. 売上の現状を把握する
Step2. 売上の理想状態を把握する
Step3. 1と2の差分を推定して、それを{課題}として定義する
Step4. 3で推定した{課題}に対して、効果的な施策を3つ提案する。
Step5. ...
※タスクをStepごとに分解した上で、それぞれのStepを明文化する手法として「Chain of Thoughts(CoT)」が有名ですが、まさにこれと同じ理屈になります。
自明ではない要素は定義する
読み手によって、解釈が異なる要素は定義をします。
特に、主観的な表現が含まれている場合には注意が必要です。
△の例)
このpdfファイルから、重要な部分を抽出してください。
⚪️の例)
このpdfファイルから、契約する上でリスクとなり得る重要な情報を、抽出してください。
前提とするルールがあるなら宣言する
LLMは、確率的推論で生成する原理です。
なので、思考のモデルをこちらから設計して指示すると、意図した出力を期待できます。
△の例)
資格試験Aの、コスパのいい勉強方法を教えてください。
⚪️の例)
パレートの法則に基づいて、つまり「全体の20%の工数で80%のパフォーマンスを引き出す」コアの要素に注意した、資格試験Aの効果的な勉強方法を教えてください。
※LLMに対して役割を指示するプロンプト(ロールプロンプト)が有名ですが、これも「出力するLLMの立場を前提として定義する」という点で同じ理屈です。
※この「ルール宣言」は、LLMが生成するまでの思考プロセスを明確にすることにもなります。本来、LLMの思考はブラックボックスな側面が大きいため、「なぜLLMはその出力をしてきたのか?」「その出力背景もセットで、深く知りたい」という場合には、「ルール宣言」のように初めから思考のプロセスを定義してしまうのも推奨です。
場合分けや例外を見逃さない
LLMは、確率的推論で出力します。
明確な指示があれば、高確率でその通りに出力してくれる一方で、
プロンプトの指示で一意的に判断できないものは、ランダムチックな生成をしているように見えます。
なので、それを許容できない場合には、「場合分け」や「例外処理」でハンドリングを行う必要があります。
△の例)
ファイル.pdfから「仮説」を抽出してください。
⚪️の例)
ファイル.pdfから「仮説」を抽出してください。
もし空白であれば、ファイル.pdfの他の情報から、あなたなりの「仮説」を推定して出力してください。
#出力形式
・仮説
・あなたが推定した仮説かどうか(yes or No)
途中プロンプト内で引用する要素は名前をつける
複雑なタスクを処理するときは、処理のステップが複数に分かれる場合があります。
つまり、プロンプトで生成した1つ目のアウトプットを、次のプロンプトのインプットとして渡す必要があります。
このときに、1つ目で出力したアウトプットに対して、プロンプト内の固有な表現で命名するとLLMは理解しやすいです。
△の例)
Userが、どんな役割で組織全体の生産性に貢献したいのか、将来どのような役割へ成長したいのかを、フローチャート形式で1問質問してください。
Userからの回答に基づいて、Userの悩みを解決してください。
⚪️の例)
#ゴール
Userに対して、下記の2つの問いを解明すること
A: Userは、どんな役割で、組織全体の生産性に貢献したいのか?
B: Userは、将来どのような役割へ成長したいのか?
#step-by-stepで出力
Step0. {ゴール}に基づいて、{KPI}を設計する出力する。
Step1. {KPI}をクリアするために、ファイルA.pdfを参照しながら、フローチャート形式で1問質問する。
Step2. Userが入力した「Step1の質問への回答」に基づいて、現時点で{KPI}をクリアできるか判断し、下記のi)〜iii)のいずれかを出力する。
...
※「△の例」だと、AとBに即した内容ではなく、一般的な悩みに文脈がすり替わってしまうリスクがあります。
繰り返す場合は抽象化する
プロンプト内で繰り返す場合には、上記の「要素の命名」が一つありますが、出力を繰り返す場合にはどのようなやり方があるでしょうか?
ここでご紹介するのは、中身の具体性をあえて無くして、抽象的な枠組みだけを支持して、繰り返し使わせる手法です。
△の例)
Userへの質問を考えて、その質問と回答の選択肢をセットで出力してください。
⚪️の例)
Userへの質問を考えて、その質問を{回答の選択肢}とセットで出力してください。
#回答の選択肢:
o: (最も考えられる候補をあなたが設計する)
p: (oの次に考えられる候補)
k: (kの次に考えられる候補)
l: (文脈と全く関係のない尖った選択肢)
※出力形式(今回だと1文字入力式で、4択である)を枠組みとして固定した上で、ただし内容は柔軟に変化をもたらせたい場合に有効です。