Chain-of-Thought プロンプティングとは、最終的な答えを出す前に、問題の途中の手順を書き出すよう言語モデルに頼む方法です。文章題、論理パズル、スケジュールのように何ステップもかかる問題では、すぐに答えるよりも手順を見せながら解くほうが正答が増える傾向があり、確認できる手順も手元に残ります。いちばん短い形は、プロンプトに1文加えるだけです。「ステップごとに考えてみましょう(Let's think step by step)」。
手順を書くと効く理由
モデルは返答を1トークンずつ生成し、すでに書いたものはすべて次のトークンのための入力になります。プロンプトがすぐに答えを求めると、モデルは途中の結果がまだどこにも書かれていない段階で答えを出さなければなりません。先に「月曜日のコーヒーの売上は16,800円」と書けば、その数はもうコンテキストの中にあり、次のステップは頭の中で抱えておく代わりに、それを土台にできます。
これが直感的な説明です。根拠は2022年の2本の論文から来ました。Wei らの「Chain-of-Thought Prompting Elicits Reasoning in Large Language Models」は、推論を書き出した実例によって、大規模モデルの算数、常識、記号推論のタスクの成績が上がることを示しました。また、その効果が規模に依存することも見つけました。小さいモデルは改善せず、流暢な推論を書いたうえで間違った答えにたどり着くことがよくありました。続いて Kojima らの「Large Language Models are Zero-Shot Reasoners」が、例なしの1文「Let's think step by step」でも、一般に実例ほどではないものの、結果が大きく改善することを示しました。
直接の答えと Chain-of-Thought
どちらのタブも同じ質問をしています。1つ目は金額だけを求め、2つ目は計算の過程を求めたうえで、答えを決まった最後の行に置かせています。
25,800円
直接の返答は典型的なミスを示しています。25,800円は月曜日のコーヒー16,800円に火曜日のマフィン9,000円を足したもので、火曜日はコーヒーが10杯少なかったことを忘れています。ステップごとの返答では火曜日のコーヒーの杯数に専用の行があるので、そのステップを黙って飛ばすことができません。現在のモデルなら直接の版でも正解するかもしれませんが、問題が長くなり、ステップ同士の依存が強くなるほど差は広がります。
書き出したステップにはもう1つ利点があります。答えが間違っていたとき、どのステップで崩れたかが見えるので、その箇所でプロンプトや入力を直せます。
Few-shot Chain-of-Thought
Wei らの元の手法は、答えが推論を示している実例をプロンプトに入れ、モデルに新しい質問に同じやり方で答えさせるものです。下の例は論文の最初の図を翻案したもので、そのあとの質問は新しく作ったものです。質問を変えて自分の問題を試してみてください。
図書館には最初に120冊ありました。45冊を貸し出して棚には75冊が残りました。18冊が返却されて93冊になりました。30冊の寄贈で123冊になりました。答えは 123 です。
Few-shot CoT では推論の形を制御できます。どれくらいの長さにするか、何を書き出すか、答えをどう述べるか。例の中の「答えは 11 です。」は決まった締めくくりで、返答はそれをまねています。Zero-shot CoT は書くのが早いぶん、そうした選択をモデルにまかせます。例のセットの作り方は Few-shot プロンプティングを、指示だけの版は Zero-shot プロンプティングを参照してください。
答えは専用の行に置かせる
返答に推論が含まれると、答えは段落のどこかに埋もれてしまい、プログラムが読まなければならないときに困ります。カフェのプロンプトが「Answer: X円」でしているように、答えを最後の行に決まった形で書かせ、その行をコードで読み取ってください。
import re
matches = re.findall(r"^Answer:\s*(.+)$", reply, re.MULTILINE)
answer = matches[-1] if matches else None
最後の一致を取ることが重要です。モデルが途中で自分を訂正する前に、推論そのものの中に「Answer:」で始まる行が含まれることがあるからです。ユーザーに答えだけを見せたいなら、推論を1組のタグの中に、答えを別のタグの中に書かせ、2つ目だけを表示してください。複数の項目が必要なときに JSON を頼む方法は構造化出力で扱っています。
推論モデル
現在のモデルの中には、答える前に考えるように作られているものがあります。見える返答の前に内部で推論を生成し、それはたいてい隠されているか要約されています。こうしたモデルでは「ステップごとに考えて」の重要性はずっと小さくなります。頼んでも頼まなくてもステップが実行されるからです。加えても、たいてい見える返答が長くなるだけです。
推論モデルでも役立つのは、推論のまわりにあるすべてのことです。問題の完全な記述、正しい答えが満たすべき制約、最終的な答えの形式。各ステップを台本にするより、良い答えとはどういうものかを説明してください。手順の決まったレシピは、モデルが自分で見つけたはずのもっと良い道筋からそらしてしまうことがあります。
Chain-of-Thought を使わないほうがいいとき
Chain-of-Thought はトークンと時間を消費し、元が取れるのはタスクに互いに依存するステップがあるときだけです。調べもの、翻訳、書き直し、単純な分類では、返答が長くなるだけです。また、モデルは筋が通って見える推論を書いたうえで間違った答えにたどり着くこともあるので、そこに至るステップだけでなく、最終的な結果をそれ自体で確認してください。
1本の推論の連鎖が間違いうる難しい問題には、これを発展させた手法が2つあります。Self-Consistency プロンプティングは複数の連鎖をサンプリングし、その多くがたどり着いた答えを採用します。Tree of Thought プロンプティングは、1つに決める前に、途中までの推論の筋を複数探索して比較します。
よくある質問
Chain-of-Thought プロンプティングとは何ですか?
Chain-of-Thought(CoT、思考の連鎖)プロンプティングとは、最終的な答えの前に問題の途中の手順を書き出すよう言語モデルに頼むことです。推論を含む実例を見せる方法と、「ステップごとに考えてみましょう」のような指示を加える方法があります。複数ステップの問題では正答が増える傾向があり、各ステップを確認することもできます。
「Let's think step by step」は今でも効きますか?
通常のチャットモデルでは、何ステップもかかる問題、特にプロンプトが即答を迫るような場合には今でも効きます。返答の前に考える推論モデルは、すでにこれを内部で行っているので、このフレーズの効果は返答が長くなる以外にあまりありません。そうしたモデルには、代わりに問題と答えの形式をはっきり伝えてください。
Chain-of-Thought が効くのはどんなとき、効かないのはどんなときですか?
互いに依存する複数の手順が必要なタスクで効きます。文章題、計算、論理パズル、制約つきのスケジュール調整、コードの動きの追跡などです。調べもの、翻訳、書き直し、単純な分類ではあまり効果がなく、返答が長く遅くなるだけです。
Zero-shot CoT と Few-shot CoT の違いは何ですか?
Few-shot CoT は2022年に Wei らが紹介したもので、推論つきの実例をプロンプトに入れ、モデルがその推論のスタイルをまねます。Zero-shot CoT は2022年の Kojima らによるもので、例を使わず、「ステップごとに考えてみましょう」のような指示を加えるだけです。Zero-shot は書くのが早く、Few-shot はステップの見た目をより細かく制御できます。
書き出された推論は、モデルが実際に答えを出した過程ですか?
必ずしもそうではありません。ステップはモデルが生成するテキストであり、筋が通って見えるのに最終的な答えが間違っていることも、誤りを含んでいるのに答えがたまたま正しいこともあります。推論は証明ではなく確認すべきものとして扱い、最終的な答えはそれ自体で検証してください。