🐙

【Function Calling】プロンプトエンジニアリングを使ってテキストをJSON化する【ChatGPT】

2023/06/28に公開

この記事は、6/26開催のAIねじ伏せプロンプト選手権で発表したLT資料を技術記事化したものになります。
https://zenn.dev/algorithms/articles/b3f0072d3c3d8c

はじめに

テキストをJSON化させるのは、データ分析の前処理などで利用できます。
例えば、自由記述の文章から分析で使いたいデータをJSONで抽出して、分析可能な表形式データにしたいなどのケースがあります。

スクリーンショット 2023-06-27 20.56.01.png

例題1

月収: 20万円 ~ 30万円 というテキストから、以下のような形式でJSONデータを抽出しようと思います。

{
   "minimum_monthly_salary": 200000,
   "maximum_monthly_salary": 300000
}

Function CallingでJSONにする

Function Callingを利用することで、JSON形式のデータ抽出が容易に可能です。

functions = [
 {
        "name": "extract", 
        "description": "テキストからJSONを抽出する", 
        "parameters": {
            "type": "object",
            "properties": {
                "minimum_monthly_salary": { 
                    "type": "number",
                    "description": "", 
                },
                "maximum_monthly_salary": {
                    "type": "number",
                    "description": "",
                },
            },
            "required": ["minimum_monthly_salary", "maximum_monthly_salary"], 
        },
    }
]

function_call = {"name": "extract"}
response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                {
                    "role": "user",
                    "content": text
                },
            ],
            functions=functions,
            function_call=function_call

    )

スクリーンショット 2023-06-27 21.04.17.png

単純にカラム名を指定しているだけですが、ChatGPTが勝手に解釈をしてその形式でJSONを返してくれました。

例題2

続いて年収: 500万円 というテキストから、月収に計算してJSON化させます。
スクリーンショット 2023-06-27 21.07.06.png

先ほどのFunction Callingをすると・・・

特に何も変更せず、先ほどのFunction CallingでJSON化させると、以下のように、よく分からない結果が返ってきました。

スクリーンショット 2023-06-27 21.10.34.png

Chain Of Thoughtを入れてみる

スクリーンショット 2023-06-27 21.11.15.png

プロンプトエンジニアリングのテクニックに、Chain Of Thoughtと呼ばれるものがあります。
これはただ単純に答えを出力させるのではなく、計算過程や思考過程を出力させることで計算精度が上がるというものです。

シンプルにJSONにthought_proess(思考回路)というカラムを追加してあげます。

functions = [
 {
        "name": "extract", 
        "description": "テキストからJSONを抽出する", 
        "parameters": {
            "type": "object",
            "properties": {
                "thought_process": {
                    "type": "string",
                    "description": "", 
                },
                "minimum_monthly_salary": { 
                    "type": "number",
                    "description": "", 
                },
                "maximum_monthly_salary": {
                    "type": "number",
                    "description": "",
                },
            },
            "required": ["minimum_monthly_salary", "maximum_monthly_salary", "thought_process"], 
        },
    }
]

その結果、きちんと12で割った計算結果が入ってきました。

スクリーンショット 2023-06-27 21.13.49.png

FewShotをさせる

もう一つ有効なプロンプトエンジニアリングにFew Shotを使いましょう。
具体例をChatGPTに与えると、それに沿ってその後の回答をしてくれます。
以下のように、年収400万円というテキストが入ってきた時に、どのようなJSONを返して欲しいのかを具体例で渡してあげます。

examples = [
    {"role": "user", "content": "年収400万"},
    { "role": "assistant", "content": None, 
     "function_call": { 
         "name": "extract", 
         "arguments": '''
            {
            "minimum_monthly_salary": 333333.33,
            "maximum_monthly_salary": 333333.33,
            "thought_process": "
                We can calculate the minimum and maximum monthly salary by dividing the annual salary by 12. 
                We need to convert the amount from Japanese characters to a number."
            }''' 
      } 
    }
]

function_call = {"name": "extract"}
response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                *examples,
                {
                    "role": "user",
                    "content": text
                },
            ],
            functions=functions,
            function_call=function_call

例で与えたように小数第2位まで計算してくれ、thought_processもこちらの意図通りの思考回路で計算してくれたことが記述されています。

スクリーンショット 2023-06-27 21.17.03.png

更なる改善

ログを残す

AIあるあるですが、精度100%にはなりません
全く想定外のアウトプットを返すことがあるので、きちんとログをとって改善に繋げましょう。

スクリーンショット 2023-06-27 21.23.15.png

リグレッションテストをする

自由記述な文章はいろいろなパターンがあるため、うまくいかなかったものはFunctionsの定義を詳細に書いたりFew Shotの追加で対応していきます。 (このあと完全歩合制など書いてある求人が出てきたりします・・・)
このようにプロンプトを改善していると、デグレしていないか気になってきますよね。
そこで対応したいケースをカバーしたリグレッションテストを記述することをお勧めします。
自動テスト化させると、毎回OpenAIとのAPIが発生してコストがかかるので、全く同じリクエストであれば同じレスポンスを返すキャッシュサーバを配置することでAPIコストを削減できます。

この辺は弊社プロダクトのLangCoreを活用していただくと、ログやキャッシュを行ってくれます(宣伝)

結論

1️⃣ Function CallingでJSONにする
2️⃣ Chain Of Thoughtで思考回路を出力させる
3️⃣ Few Shotで具体例を与えてこちらの意図を伝える
4️⃣ ログやテストで改善

最後に

スクリーンショット 2023-06-27 20.23.54.png

今回の内容は実案件で実施した内容になっています。LTでの登壇や今回の技術記事化に快く承諾していただいたフォワード様ありがとうございました。
フォワード社はかなり最先端なChatGPT APIを活用してプロダクトを作っていますので、副業等興味ある方はぜひTwitterから連絡してください!

Discussion