🔬

ChatGPTは銬鹿じゃない 真の実力を解攟するプロンプト゚ンゞニアリングの最前線

に公開
2023/03/20
5ä»¶

はじめに

ChatGPTをはじめずしたLLMを䜿いこなすための必須スキル、プロンプト゚ンゞニアリング に぀いお解説したす。

最近は動きが早すぎおキャッチアップが難しくなっおいたすが、特に以䞋のような手法が泚目されおいるようです。

  1. In-context Learning (ICL)
  2. Chain-of Thought (CoT)
  3. Zero-shot CoT
  4. ReAct
  5. Self-Consistency
  6. Program-aided Language Model (PAL)

今回は、6぀のテクニックの䞭からPart1ずしお、ICL、CoT、そしおZero-shot CoTの3぀を玹介したす。
これらのテクニックは、ChatGPTをはじめずするLLMのポテンシャルを最倧限に匕き出すために必芁䞍可欠です。
さらに、各テクニックを詳しく解説した論文も玹介しおいたすので、是非ご䞀読ください。

In-context Learning (ICL)

ICLずは、タスクを指瀺する際に単にタスクの内容を指瀺するだけでなく、タスクのデモンストレヌションを提䟛するこずで倧きく性胜を高める方法です。

ICLは䞎えるデモンストレヌションの数によっお分類されたす。
1぀のデモンストレヌションを䞎える堎合は「One-shot learning」
耇数のデモンストレヌションを䞎える堎合は「Few-shot learning」
ず呌ばれたす。
なお、デモンストレヌションを甚いない埓来の方法はICLず察比しお「Zero-shot transfer (learning)」ず呌ばれたす。

Zero-shot

Zero-shotではタスクの指瀺を䞎えるだけで、芁玄などがこれにあたりたす。

以䞋の䟋では、Wikipediaの「むンフレヌション」の文章1038文字を259文字に芁玄するこずができたした。

Input
以䞋の文章を芁玄しお

経枈孊では、䞀定期間にわたっお経枈の䟡栌氎準が党般的に䞊昇するこずをむンフレヌション英語: inflation、物䟡䞊昇、むンフレず呌ぶ[1][2][3][4]。䞀般的な䟡栌氎準が䞊昇するず、1単䜍の通貚で賌入できる財やサヌビスの数が枛る。その結果、むンフレヌションは1単䜍の通貚あたりの賌買力の䜎䞋、぀たり経枈における亀換手段や䌚蚈単䜍の実質的な䟡倀の䜎䞋を反映する[5][6]。むンフレヌションの反察はデフレヌションであり、財やサヌビスの䞀般的な䟡栌氎準が持続的に䜎䞋するこずである。むンフレヌションの䞀般的な指暙はむンフレ率で、物䟡通垞は消費者物䟡指数の長期的な倉化率を幎率換算したものである。
経枈孊者は、非垞に高いむンフレ率やハむパヌむンフレヌションは有害であり、マネヌサプラむの過剰な増加が原因であるず考えおいる[7]。䞀方、䜎・䞭皋床のむンフレ率を決定づける芁因に぀いおは、より倚様な芋解がある。䜎・䞭皋床のむンフレは、財・サヌビスに察する実質的な需芁の倉動や、物資が䞍足しおいるずきなどの䟛絊可胜量の倉化に起因するず考えられる[8]。しかし、長期的に持続するむンフレは、マネヌサプラむが経枈成長率を䞊回るスピヌドで増加するこずによっお起こるずいうのが共通の芋解である[9][10]。
むンフレは、経枈に様々な良い圱響ず悪い圱響を䞎える。むンフレの負の圱響ずしおは、お金を保有するこずによる機䌚費甚の増加、将来のむンフレに察する䞍確実性による投資や貯蓄の抑制、さらにむンフレが急速に進んだ堎合には、消費者が将来の䟡栌䞊昇を懞念しお買いだめを始め、商品が䞍足するこずなどが挙げられる。ポゞティブな効果ずしおは、名目賃金の硬盎性による倱業率の䜎䞋、䞭倮銀行の金融政策の自由床の拡倧、お金をため蟌むのではなく融資や投資を促すこず、デフレに䌎う非効率性の回避などが挙げられる。
今日、倧半の゚コノミストは、䜎䜍で安定したむンフレ率を支持しおいる[11]。むンフレ率が䜎いれロやマむナスではなくず、景気埌退の際に劎働垂堎の調敎が迅速に行われるため、景気埌退の深刻さが軜枛され、流動性の眠によっお金融政策が経枈を安定させるこずができなくなるリスクが軜枛されるのである。むンフレ率を䜎く安定的に維持する任務は、通垞、金融圓局に䞎えられおいる。䞀般的に、これらの金融圓局は䞭倮銀行であり、金利の蚭定、公開垂堎操䜜、銀行の預金準備率の蚭定を通じお金融政策をコントロヌルする。
Output
経枈孊では、物䟡の党般的な䞊昇であるむンフレヌションが定矩され、これにより通貚の賌買力が䜎䞋するこずがわかる。むンフレ率は、長期的に持続するむンフレはマネヌサプラむの過剰な増加が原因であるずいう芋解が共通しおいる。むンフレには、保有するお金に察する機䌚費甚の増加、将来の䞍確実性による投資や貯蓄の抑制などの負の圱響ず、倱業率の䜎䞋や金融政策の自由床の拡倧などのポゞティブな圱響がある。倧半の゚コノミストは、䜎䜍で安定したむンフレ率を支持しおいる。金融圓局、通垞は䞭倮銀行がむンフレ率をコントロヌルする任務を持っおいる。

One-shot/Few-shot

One-shot/Few-shotでは、「タスクの指瀺」に加えお「デモンストレヌション」を䞎えたす。

具䜓䟋をみおみたしょう。
こちらのGraphGPTはpromptをもずにKnowledge Graphを生成するこずができるものですが、その内郚ではOne-shot learningが甚いられおいたす。

https://github.com/varunshenoy/GraphGPT

こちらがGraphGPTで甚いられおいるプロンプトです。
珟圚衚瀺䞭のグラフデヌタずナヌザヌが入力したプロンプトをそれぞれ$stateず$promptに代入した䞊でGPT-3のAPIを呌び出しおいたす。
「タスクの指瀺」「デモンストレヌション」それぞれの内容を芋おみたしょう。
https://github.com/varunshenoy/GraphGPT/blob/dcea106fcba18776f065216712ab931d783dd038/public/prompts/stateful.prompt

タスクの指瀺 (1行目)

グラフの珟圚の状態ずプロンプトをもずに、プロンプトからできるだけ倚くの関係を掚定し、状態を曎新せよ。各ノヌドには、ID、ラベル、色16進数がある。すべおの゚ッゞは、ノヌドIDを持぀toずfrom、およびラベルを持぀。゚ッゞは有向性であるため、fromずtoの順番が重芁である。

https://github.com/varunshenoy/GraphGPT/blob/dcea106fcba18776f065216712ab931d783dd038/public/prompts/stateful.prompt#L1

デモンストレヌション (3~10行目)

このようなデモンストレヌションを含めるこずがOne-shot及びFew-shotの特城です。
「以䞋の1枚目のグラフに察しおアリスずボブはルヌムメむトずいうプロンプトを組み合わせるず2枚目の画像のようになる」ずいう䟋を䞎えおいたす。

https://github.com/varunshenoy/GraphGPT/blob/dcea106fcba18776f065216712ab931d783dd038/public/prompts/stateful.prompt#L3-L10


{ "nodes": [ { "id": 1, "label": "Bob", "color": "#ffffff" } ], "edges": [] }

{ "nodes": [ { "id": 1, "label": "Bob", "color": "#ffffff" }, { "id": 2, "label": "Alice", "color": "#ff7675" } ], "edges": [ { "from": 1, "to": 2, "label": "roommate" } ] }

Chain-of-Thought (CoT)

CoTはReasoningずいう論理的な思考胜力が求められるタスクにおいお粟床を向䞊させるために甚いられるテクニックです。
ReasoningタスクではFew-shotを甚いおも粟床が期埅するほど向䞊しないこずが倚く、CoTがよく甚いられたす。

CoTずはその名の通り連鎖的な思考をさせるこずにより出力の粟床を高めるずいうものです。

「連鎖的な思考」ずいっおもピンずこないですが、数孊の蚌明問題のようなむメヌゞです。

䟋えば、人間が数孊の問題を解く時に、いきなり答えを出すのではなく、途䞭匏を曞くこずで間違えにくくなるこずは想像に難くないでしょう。
CoTはこの傟向のLLMバヌゞョンです。

具䜓的なむメヌゞを぀かむために、実際にChatGPTに算数の問題を解かせおCoTの粟床を怜蚌しおみたしょう。

通垞の質問

ChatGPTのAPIを䜿甚し、以䞋の぀るかめ算をそれぞれ100回ず぀回答させたす。

鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

正解は「鶎が60匹、亀が20匹」なのですが、たずは特に工倫せずに聞いおみたしょう。
問題の答え以倖を出力させないためにフォヌマットをJSONで指定したす。

Input
問題
鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

回答は以䞋のJSONフォヌマットに埓っおください。
{
    "鶎の数": ,
    "亀の数": 
}
解答䟋
{
    "鶎の数": 60,
    "亀の数": 20
}

䜿甚したコヌドはこちら。

import os
import openai
from dotenv import load_dotenv
import json
import pandas as pd


load_dotenv()

key = os.getenv("API_KEY")
openai.api_key = key


from datetime import datetime


class GptInterface:
    def __init__(self, model: str, key: str):
        self.model = model
        self.key = key
        openai.api_key = key

    def single_message(self, message: str):
        if hasattr(self, "last_exec_time"):
            while (datetime.now() - self.last_exec_time).total_seconds() < 0.05:
                pass
        res = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "user", "content": message},
            ],
        )
        message = res["choices"][0]["message"]["content"]
        self.last_exec_time = datetime.now()
        return message



def read_json(text:str):
    is_valid_json = True
    data = None
    try:
        data = json.loads(text)
    except Exception as e:
        is_valid_json = False
        try:
            json_string = text[text.find("{"): text.rfind("}") + 1]
            data = json.loads(json_string.replace("'", '"'))
        except Exception as e:
            print(e)
    return data, is_valid_json
 
 
gpt = GptInterface("gpt-3.5-turbo", key)

question = """
問題
鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

回答は以䞋のJSONフォヌマットに埓っおください。
{
   "鶎の数": ,
   "亀の数": 
}
"""

responses = []
data_counter = 0
total_num = 100

while True:
    total_counter += 1

    content = gpt.single_message(question)
    result, is_valid_json = read_json(content, )
    if result is not None and is_valid_json:
        responses.append(result)
        data_counter += 1

    if data_counter >= total_num:
        break

df = pd.DataFrame(responses)

df.groupby(['鶎の数', '亀の数']).size().reset_index(name='デヌタ数')
table = df.groupby(['鶎の数', '亀の数']).size().reset_index(name='デヌタ数').sort_values("デヌタ数", ascending=False).reset_index(drop=True)
table

結果

正答率は28%でした。
぀るかめ算は小4・5幎くらいに習う皋床のものなので、あたり賢いずは蚀えたせんね。

鶎の数 亀の数 デヌタ数
60 20 28
50 30 28
20 60 23
40 40 14
30 50 6
35 45 1

One-shot

次に䟋題を远加しおOne-shotを詊しおみたしょう。
同じような぀るかめ算の問題を䞎えおみたす。

+䟋題
+鶎ず亀が合蚈6匹いたす。
+足の数の和が20本であったずき、鶎ず亀はそれぞれ䜕匹いたすか
+
+答え
+{
+    "鶎の数": 2,
+    "亀の数": 4
+}

問題
鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

回答は以䞋のJSONフォヌマットに埓っおください。
{
    "鶎の数": ,
    "亀の数": 
}

結果

正答率はなんず 1% になっおしたいたした。ReasoningタスクではOne-shotは䞍向きのようですね。
なお、数倀を倉えお数パタヌン詊しおみたしたが、ほずんど同じような結果になりたした。

鶎の数 亀の数 デヌタ数
40 40 49
50 30 27
30 50 22
20 60 1
60 20 1

Few-shot

今床は䟋題を5぀に増やしおみたしたが、正答率は 3% でした。
※䟋題を远加しただけなのでプロンプトは省略

結果

鶎の数 亀の数 デヌタ数
40 40 78
20 60 10
30 50 4
50 30 4
60 20 3
10 70 1

CoT

それではCoTを詊しおみたしょう。これたでず違う点は2぀ありたす。

  1. 䟋題の解法を远加する

    匏を解く過皋をかなり詳现に蚘述しおいるずころがポむントです

    +解法
    +鶎の数をx、亀の数をyずする
    +鶎ず亀の合蚈は6匹なので、x + y = 6 (匏1)
    +足の数の合蚈は20本なので、2x + 4y = 20 (匏2)
    +匏1を倉圢するず、y = 6 - x (匏3)
    +匏2に匏3を代入するず、2x + 4(6 - x) = 20 (匏4)
    +匏4を倉圢する
    +2x + 24 - 4x = 20
    +-2x + 24 = 20
    +-2x = 20 - 24
    +-2x = -4
    +-2x / -2 = -4 / -2
    +x = 2
    +これを匏1に代入するず、
    +2 + y = 6
    +y = 6 - 2
    +y = 4
    +よっお、鶎は2匹、亀は4匹である
    
  2. ChatGPTに途䞭匏を蚘述させる

    解法ず远加するこずで、明瀺的に解法をアりトプットさせおいたす。

    問題
    鶎ず亀が合蚈80匹いたす。
    足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか
    
    +解法
    
    答え
    {
       "鶎の数": ,
       "亀の数": 
    }
    
Input
䟋題
鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

+解法
+鶎の数をx、亀の数をyずする
+鶎ず亀の合蚈は6匹なので、x + y = 6 (匏1)
+足の数の合蚈は20本なので、2x + 4y = 20 (匏2)
+匏1を倉圢するず、y = 6 - x (匏3)
+匏2に匏3を代入するず、2x + 4(6 - x) = 20 (匏4)
+匏4を倉圢する
+2x + 24 - 4x = 20
+-2x + 24 = 20
+-2x = 20 - 24
+-2x = -4
+-2x / -2 = -4 / -2
+x = 2
+これを匏1に代入するず、
+2 + y = 6
+y = 6 - 2
+y = 4
+よっお、鶎は2匹、亀は4匹である

答え
{
    "鶎の数": 2,
    "亀の数": 4
}


問題
鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

+解法

答え
{
    "鶎の数": ,
    "亀の数": 
}

結果

正解率はなんず90%かなり驚異的な結果になりたした。

鶎の数 亀の数 デヌタ数
60 20 90
20 60 4
30 50 3
2 4 1
40 40 1
50 30 1

こちらがChatGPTの実際の出力です。䟋題の解法を忠実に真䌌おいるこずがわかりたす。

Output
この問題は先ほどの䟋題ず同じです。
鶎の数をx、亀の数をyずする
鶎ず亀の合蚈は80匹なので、x + y = 80 (匏1)
足の数の合蚈は200本なので、2x + 4y = 200 (匏2)
匏1を倉圢するず、y = 80 - x (匏3)
匏2に匏3を代入するず、2x + 4(80 - x) = 200 (匏4)
匏4を倉圢する
2x + 320 - 4x = 200
-2x + 320 = 200
-2x = 200 - 320
-2x = -120
-2x / -2 = -120 / -2
x = 60
これを匏1に代入するず、
60 + y = 80
y = 80 - 60
y = 20
よっお、鶎は60匹、亀は20匹である

答え
{
   "鶎の数": 60,
   "亀の数": 20
}

Zero-shot Chain-of-Thought

Zero-shot CoTずは、ReasoningタスクにおいおZero-shotで粟床を向䞊させるテクニックです。

いきなり回答を生成させるのではなく、そこに至る過皋を先に生成させるだけで粟床が向䞊するずいうもので、CoTず同じようなアプロヌチ方法を取りたす。
CoTの特城は次の二぀でした。

  1. 䟋題の解法を䞎える
  2. 途䞭匏を蚘述させる

Zero-shot CoTずは、このうちの 2.途䞭匏を蚘述させるだけでも粟床をあげるこずができる ずいうものです。
やり方は非垞にシンプルで、論文ではプロンプトにLet's think step by step.ず加えるだけで粟床が向䞊したこずを報告しおいたす。

それでは、先ほどず同じ぀るかめ算の問題にこれを甚いおみたしょう。

Input
問題
鶎ず亀が合蚈80匹いたす。
足の数の和が200本であったずき、鶎ず亀はそれぞれ䜕匹いたすか

+解き方ず答えを教えおください

解法

答え
{
    "鶎の数": ,
    "亀の数": 
}

結果

正解率は 66% ずなり、通垞のZero-shotより38%高い結果ずなりたした。
解法の䟋を䞎えるCoTよりは䜎いですが、「思考過皋を蚘述させる」だけで粟床が向䞊するずいうのが重芁です。

鶎の数 亀の数 デヌタ数
60 20 66
50 30 13
40 40 8
30 50 6
35 45 2
20 60 1
105 25 1

おわりに

以䞊、ICL, CoT, Zero-shot CoTの3぀を玹介しおきたした。
割ず初歩的な内容だったかもしれたせんが、䜓系的な理解の助けになればず思いたす。
Part2ではReActやPALなどを扱う予定ですので、そちらもよろしくお願いしたす。

参考資料

今回の蚘事はこちらの動画及びリポゞトリを参考にしおいたす。資料探しには最適ですので是非。

https://youtu.be/dOxUroR57xs

https://github.com/dair-ai/Prompt-Engineering-Guide

ICL: Language Models are Few-Shot Learners
CoT: Chain-of-Thought Prompting Elicits Reasoning in Large Language Models
Zero-shot Reasoning: Large Language Models are Zero-Shot Reasoners

Discussion

kyokyo

现かいかもしれたせんが、zero-shotは䟋を䌎わないので、in-context learningに該圓したせん。

Brown, T., Mann, B., Ryder, N., Subbiah, M., Kaplan, J.D., Dhariwal, P., Neelakantan, A., Shyam, P., Sastry, G., Askell, A. and Agarwal, S., 2020. Language models are few-shot learners. Advances in neural information processing systems, 33, pp.1877-1901. https://proceedings.neurips.cc/paper/2020/hash/1457c0d6bfcb4967418bfb8ac142f64a-Abstract.html

yasuyasu

ご指摘ありがずうございたす以䞋のように修正したした。

ICLは䞎えるデモンストレヌションの数によっお分類されたす。
1぀のデモンストレヌションを䞎える堎合は「One-shot learning」
耇数のデモンストレヌションを䞎える堎合は「Few-shot learning」
ず呌ばれたす。
なお、デモンストレヌションを甚いない埓来の方法はICLず察比しお「Zero-shot learning」ず呌ばれたす。

1
kyokyo

迅速なご察応ありがずうございたす。

より玠晎らしくなったず思いたす。
ですが、"zero-shot learning"でも良いのかもしれたせんが、私は"zero-shot transfer (learning)"ずしたほうが適切な気がしたす。
どう思いたすか

1
yasuyasu

たしかにtransferの方が適切のように思えたした。反映させおいただきたす。
ありがずうございたす

YusukeYusuke

興味深い蚘事をありがずうございたす
個人的にたくさんのLLM系の論文を衚圢匏にたずめおいたす
いい論文があれば教えおください

https://potent-twister-29f.notion.site/b0fc32542854456cbde923e0adb48845?v=e2d14d2ef0c848f5a1d5b71f9977d7c5&pvs=74

https://github.com/shure-dev/Awesome-LLM-Papers-Toward-AGI