プロンプトエンジニアリング テクニックまとめ
プロンプトエンジニアリング
Large Language Model(以降LLM)のプロンプトエンジニアリング、色々テクニックがあるのですが、全然名前と内容が一致しないので一度自分なりにまとめてみることにしました。
そもそも、LLMOps:基盤モデルに基づくアプリケーション開発のワークフローによると、LLMの開発には以下の3つのアプローチがあるとのことです。
LLMOps:基盤モデルに基づくアプリケーション開発のワークフローより引用
本記事ではその中の、In-Context Learningについて(要は、プロンプトを工夫してなんとかしましょうというアプローチ)のみ記載します。そして、更にIn-Context Learningを、この記事の内容で分類した図を以下に示します。
ここで出てくるIn-Context Learningのテクニック、結構名前がカッコいいというか、仰々しいんですよね。「Zero-Shotのゼロってどういうこと?(何もしないの??)」とか「Learningとかついているけど、実際は学習してないじゃん!」など、よくわからなくなってしまうこと多いなと思っていたら、fukabori.fmという音声配信番組の97回目のエピソードでも同じようなことが語られてました。自分だけじゃなくて安心しました。この記事では、音声配信に出てくる内容の中でも、基本的な一部に関して紹介しています。
また、取り上げるプロンプトのテクニックは、誰かがちょっと試してみた的なオレオレプロンプトではなく、ある程度論文などで再現性が確認されているもの・OpenAIの公式情報で紹介されている情報を中心に、具体例や論文、公式情報と一緒にとりあげていきたいと思います。
In-Context Learning
概要
直訳すると「文脈を学習」でしょうか。よくわかりませんね。In-Context Learningは広い概念で、後のK-ShotとかChain of Thought(CoT)を内包するようなものと理解しています。
Learningと書いてありますが、実際にモデルを学習(ファインチューニングなど)をするわけではなくて、プロンプト内にいくつか具体例(タスク例)を挙げることで、モデルの出力をコントロールしていくプロンプトのテクニックです。
具体例
この後出てくるものは、ほぼ全てIn-Context Learningの範疇となります。
論文
Zero/Few/K-Shot
概要
In-Context Learningのために、プロンプトと一緒に提供されるタスク例の数Kに応じてK-Shotと呼ばれるらしいです。
Zero-Shotってどういうこと?と思ったら、タスク例がなく、単純に指示だけだとZero-Shotになるみたいです。Zero-Shotって何かカッコいいけど、実際は単に指示しているだけというね。
Kがちょっとだけ(多分1〜3くらい)だとFew-Shotらしいです。
Open AIの公式ガイドには、Instructionをプロンプトの最初に書いて、文脈(In-Context)は、"""
か###
で区切るのが推奨のようです。
具体例
Zero-Shotのプロンプトは以下です。
fried chickenを日本語に訳してください
Few-Shot(K=3)は、以下のように3つ例を挙げたプロンプトになります。
fried chickenを日本語に訳してください。
日本語訳例:"""
apple > りんご
bear > くま
beer > ビール
"""
論文
Chain of Thought(CoT)
概要
思考の連鎖って、なんかかっこいいですね。
プロンプトのタスク例として、論理的思考の過程を記載すると性能が上がるという話みたいです。説明より具体例をみた方が分かりやすいと思います。
具体例
Chain-of-Thought Prompting Elicits Reasoning
in Large Language Modelsより引用
論文
Self-Consistency
概要
CoTの発展形です。Few-shotのCoTを使うことで、性能がアップするようです。
説明が少しむずかしいのですが、具体例を見たほうがピンとくるかもしれません。詳細は論文を参照ください。
具体例
Q:林には15本の木があります。林業従事者は今日、林に木を植える予定です。その後、21本の木があります。林業従事者は今日、何本の木を植えましたか?
A:15本の木から始めます。後で21本の木があります。差は、彼らが植えた木の数でなければなりません。したがって、彼らは21-15 = 6本の木を植えなければなりません。回答は6です。
Q:駐車場に車が3台あり、さらに2台の車が到着した場合、駐車場には何台の車がありますか?
A:駐車場には既に3台の車があります。2台の車が到着しました。これで、車が3+2 = 5台あります。回答は5です。
Q:リアは32個のチョコレートを持っており、彼女の姉妹は42個のチョコレートを持っています。彼らが35個食べた場合、彼らが残したピースの数は何ですか?
A:リアは32個のチョコレートを持っており、リアの姉妹は42個のチョコレートを持っていたことを意味します。つまり、もともとは32 + 42 = 74個のチョコレートがありました。35個食べられました。したがって、合計で残るのは74-35 = 39個のチョコレートです。回答は39です。...
(略)
...
Q:私が6歳のとき、妹は私の半分の年齢でした。今、私は70歳です。私の妹は何歳ですか?
A:
論文
Zero-Shot CoT
概要
プロンプトの最後に「Let’s think step by step.(ステップごとに考えよう)」とつけるだけで、性能が上がるというものです。
それだけ??と思ってしまうのですが、ここでのポイントは、CoTという高度なIn-Context Learningを、タスク例を挙げること無くZero-Shotで実現してしまうという点ですね。
そう捉えると、この「Let’s think step by step.」の発見の凄さが少し分かるのではないでしょうか??
具体例
ほんとに、最後に「Let’s think step by step.」つけてるだけです。
Large Language Models are Zero-Shot Reasonersより引用
論文
外部(実世界)から取得した情報を活用する方法
システムが現実にアクセスする手段を提供することをLLMの分野だと「Grounding」といいます。そのGroundingを活用した手法を紹介します。
ここからは、まだまとめきれてないので、簡単に紹介します。
Retrieval-Augmented Generation(RAG)
情報をベクトル化(Embedding)して、プロンプトで検索して、距離が近い文章をプロンプトと一緒に投げる手法です。In-Context LearningのIn-Contextを外部からひっぱってくることですね。
実際にやってみた例が以下となります。
参考情報
ReAct
外部のサービスから必要な情報をLLMが取得する方法です。
参考情報
Recursively Criticizes and Improves(RCI)
LLMの出力をLLM自身で確認して修正する方法です。いわゆるエージェントと環境の相互作用で生まれる情報を活用しているわけで、これもGroundingの一種ではないかと自分は思っています(あんまりそういう文脈で語られていない気がするので、ちょっと自信ないです。
Code Interpreterがエラーを自分で修正してくのも、このRCIを使っているのかと思います。
参考情報
プロンプトインジェクション
プロンプトを使った攻撃(ハック)に関してです。以下にまとめました。
まとめ
プロンプトのテクニック、色々あるので、網羅的にまとめようと思ったのですが、In-Context Learning周りの代表的なものだけで限界でした。またここに追記するか、別記事で別観点でまとめてみたいと思います。
もっと知りたい方は、参考リンクあたりをみていただけたら幸いです。あと、間違いに気づかれた方はそっと優しく教えていただけると嬉しいです。
参考リンク
ガイド
プロンプト集
プロンプトで検索
デジタル庁のプロンプト集
Google Gemini用のプロンプト集
システムプロンプト集(個人まとめ)
論文
ツール
関連記事
変更履歴
- 2024/07/01 プロンプト集追記
- 2023/07/27 Self-Consistency、Groundingに関して追記
- 2023/07/18 全体感を追記
Discussion
興味深い記事をありがとうございます
個人的に大量のLLM系の論文を表形式にまとめています
この表に載っていないおすすめの論文があれば教えてください