Python

ChatGPTのAPI新機能「Function calling」をPythonで実装!

Function calling
記事内に商品プロモーションを含む場合があります
ウマたん
ウマたん
当サイト【スタビジ】の本記事では、ChatGPT(正確にはGPTモデル)のAPIに新しく追加されたFunction callingという機能について解説していきたいと思います。実際にPythonを使ってFunction callingでどんな処理が構築できるのか実装していきますよ!

こんにちは!

データサイエンティストのウマたん(@statistics1012)です!

この記事ではChatGPTの話題のFunction callingについてどんなことができるか実装例とともに見ていきたいと思います!

Function callingを使うとChatGPTのAPIを利用してプログラムを構築する際の幅がめちゃくちゃ広がるのでぜひおさえておきましょう!

Function callingとは?

robot

Function callingはOpenAIが2023年6月13日に公開したChatGPT(正確にはChatGPTというかGPTモデル)のAPI新機能であり、処理の幅が広がるため界隈で非常に話題になっている機能です。

ざっくり言うと、あらかじめ特定の関数をこちらで定義して渡しておけば、人間の指示に対してGPTモデル側がよしなに必要な関数をピックアップして処理を行い結果を返してくれるというもの。

たとえば、色んな人のスケジュールが格納されているデータベースがありそこから特定の人の特定の日付のスケジュールを取得する関数を作成したとしましょう。

その関数をGPTのAPIに渡してFunction callingの設定をしてあげると・・・

自然言語で”田中さんの6/30のスケジュールを教えてー!”と入力すると、その結果を元に関数を呼び出すかどうか判断して必要であれば関数を呼んでその情報をもとに出力を返してくれる優れものなのです!

Function calling

複数の関数を定義することが可能なので、GmailのAPIを利用してメールを送る関数などを定義しておくと”田中さんの6/30のスケジュールをxxxxx.gmail.comにおくってー”などと伝えるだけで、複数の関数を呼び出して実行してくれます。

めちゃくちゃすごいです。

このような処理を自然言語の指示で出来てしまうのは画期的ですし、ChatGPTのAPIを利用する幅が大きく広がりました!

Function callingの実装例

それでは実際にどうやってFunction callingを実装するのか見ていきましょう!

今回は、先ほどお伝えした「誰かの特定日付のスケジュールを取得する」ような処理を簡単なデモで実装していきます。

この時、処理構築の流れとしては以下です。

・独自functionの定義
・GPTのAPIを呼ぶ処理
・独自functionを使うかどうか判断する処理

まず処理構築に入る前に例によって以下のように各種必要なライブラリやAPIキーの設定をしておきましょう!

import openai
import json
openai.api_key = "<自分のOpenAIのAPIキーを入れる>"

独自functionの定義

まずは独自functionを定義していきましょう!以下のように記述していきます!

def get_schedule(date, person):
    """
    スケジュール取得用の関数を定義
    - ここではdateとpersonがパラメータとして渡りそれに対するscheduleが返ってくる仕様
    - 本来であればパラメータを元に適切なスケジュールが返ってくるようになるべきだが簡単のために今回は固定値を返す
    """
    schedule_info = {
        "date": date,
        "person": person,
        "schedule": "10時:A社とMTG、12時:友人Bとランチ"
    }
    return json.dumps(schedule_info)

get_scheduleはまさにスケジュールを取得する関数であり、dateとpersonを引数としてscheduleを取得します。

今回は簡単のためscheduleは固定値を入れています。

GPTのAPIを呼ぶ処理

続いてGPTのAPIを呼ぶ処理を作っていきます。

def run_conversation(prompt):
    # GPTのAPIへのリクエストを定義
    messages = [{"role": "user", "content": prompt}]
    functions = [
        {
            "name": "get_schedule",
            "description": "特定の日付のスケジュールを取得して返す",
            "parameters": {
                "type": "object",
                "properties": {
                    "date": {
                        "type": "string",
                        "description": "日付"
                    },
                    "person": {
                        "type": "string",
                        "description": "人の名前"
                    },
                },
                "required": ["date","person"]
            }
        }
    ]
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        function_call="auto",
    )
    response_message = response["choices"][0]["message"]

functionsには独自関数名や関数の説明や関数に必要なパラメータなどをセットしていきます。

function_call=”auto”とすることで独自関数を使うか使わないかをGPTモデルが自動で選定してくれるようになります。

引数promptにはユーザーが入力する自然言語が入るようになってます。

独自functionを呼ぶ選択をしたかどうか判断し処理

続いて独自定義したfunctionを呼ぶかどうかを判断し次の処理に移ります。

先ほどのコードの続きであり、run_conversation関数の中に書いていきます。

 # 独自定義したfunctionを呼ぶのかどうか判断し処理
    if response_message.get("function_call"):
        available_functions = {
            "get_schedule": get_schedule,
        }
        function_name = response_message["function_call"]["name"]
        fuction_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        function_response = fuction_to_call(
            date=function_args.get("date"),
            person=function_args.get("person")
        )

        # 独自関数のレスポンスを渡す
        messages.append(response_message)
        messages.append(
            {
                "role": "function",
                "name": function_name,
                "content": function_response,
            }
        )  
        # 独自関数のレスポンスをもとに改めてAPIにリクエスト
        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=messages,
        )  # get a new response from GPT where it can see the function response
        return second_response
      
    else:
        return response_message

ここでは、functionを呼ぶ選択をした場合は、よしなにユーザーが入力したpromptから名前や日付を取得してそれを元に関数を呼び出し結果を返してくれます。

検証

それでは検証していきましょう!

最終的なコードは以下のようになります!

def get_schedule(date, person):
    """
    スケジュール取得用の関数を定義
    - ここではdateとpersonがパラメータとして渡りそれに対するscheduleが返ってくる仕様
    - 本来であればパラメータを元に適切なスケジュールが返ってくるようになるべきだが簡単のために今回は固定値を返す
    """
    schedule_info = {
        "date": date,
        "person": person,
        "schedule": "10時:A社とMTG、12時:友人Bとランチ"
    }
    return json.dumps(schedule_info)


def run_conversation(prompt):
    # GPTのAPIへのリクエストを定義
    messages = [{"role": "user", "content": prompt}]
    functions = [
        {
            "name": "get_schedule",
            "description": "特定の日付のスケジュールを取得して返す",
            "parameters": {
                "type": "object",
                "properties": {
                    "date": {
                        "type": "string",
                        "description": "日付"
                    },
                    "person": {
                        "type": "string",
                        "description": "人の名前"
                    },
                },
                "required": ["date","person"]
            }
        }
    ]
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        function_call="auto",
    )
    response_message = response["choices"][0]["message"]

    # 独自定義したfunctionを呼ぶかどうかの処理
    if response_message.get("function_call"):
        available_functions = {
            "get_schedule": get_schedule,
        }
        function_name = response_message["function_call"]["name"]
        fuction_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        function_response = fuction_to_call(
            date=function_args.get("date"),
            person=function_args.get("person")
        )

        # 独自関数のレスポンスを渡す
        messages.append(response_message)
        messages.append(
            {
                "role": "function",
                "name": function_name,
                "content": function_response,
            }
        )  
        # 独自関数のレスポンスをもとに改めてAPIにリクエスト
        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=messages,
        )  # get a new response from GPT where it can see the function response
        return second_response
      
    else:
        return response_message

では定義したrun_conversationを呼び出して実際にどんな回答が返ってくるのか検証してみましょう!

print(run_conversation("田中さんの6/30のスケジュールを教えて")["choices"][0]["message"]["content"])

結果は以下のようになりました!!

Function calling

ちゃんといい感じに回答を返してくれていることが分かります。

今回は固定値を返すというシンプルな方法で実装を試みましたが、これでもFunction callingの実装イメージが掴めたかと思います。

ぜひ色んな関数を定義してFunction callingを駆使して面白いプログラムを作ってみてください!

以下がOpenAIのFunction callingのドキュメントであり実装方法などが詳しく記載されているので是非参考にしてみてください。

ちなみにFunction callingと似たことができるライブラリとしてLangChainが存在しました。

Function callingとLangChainの違いはどんなところにあるのでしょうか?

個人的にはFunction callingの方が処理構築が分かりやすいのと出力が正確かつOpenAIが提供している公式機能であることから出来るだけFunction callingを利用した方がいいかなと思っています。

LangChainについては以下の記事で詳しく解説していますので是非チェックしてみてください!

LangChain
【5分で分かる】LangChainのPythonでの使い方 -チュートリアル-当サイト【スタビジ】の本記事では、大規模言語モデル(LLM)を上手く扱う上で非常に便利なLangChainというライブラリについて概要からPythonでの使い方まで見ていきたいと思います。LangChainを使うことで複雑な処理に対応したプログラムを簡潔に書くことができるのでLLMを組み込んだサービスを作るときなどに重宝します!...

Function calling まとめ

ここまでで、ChatGPTのAPIをフル活用するのに重要なFunction callingについてまとめてきました!

最近話題の生成系AIやLLMの実装方法についてより詳しくは当メディアが運営するスタアカの以下のコースを是非チェックしてみてください!

GPTモデルをはじめとした大規模言語モデルの理論やPythonでの扱い方などを幅広く学んでいきます!

スタアカは業界最安級のAIデータサイエンススクールです。

スタアカトップ
【価格】ライトプラン:980円/月
プレミアムプラン:98,000円
【オススメ度】
【サポート体制】
【受講形式】オンライン形式
【学習範囲】データサイエンスを網羅的に学ぶ
実践的なビジネスフレームワークを学ぶ
SQLとPythonを組みあわせて実データを使った様々なワークを行う
マーケティングの実行プラン策定
マーケティングとデータ分析の掛け合わせで集客マネタイズ

・BigQuery上でSQL、Google Colab上でPythonを使い野球の投球分析
・世界最大手小売企業のウォルマートの実データを用いた需要予測
・ビジネス・マーケティングの基礎を学んで実際の企業を題材にしたマーケティングプランの策定
・Webサイト構築してデータ基盤構築してWebマーケ×データ分析実践して稼ぐ

AIデータサイエンスを学んで市場価値の高い人材になりましょう!

データサイエンスやAIの勉強方法は以下の記事でまとめています。

【5分で分かる】データサイエンティストに必要なスキルと独学勉強ロードマップ!当サイト【スタビジ】の本記事では、データサイエンティストに求められるスキルとそれを身に付けるための勉強法について徹底的にまとめていきます!入門者でも、しっかりデータサイエンティストについて理解しある程度独学で駆け出しの状態までいけることを目指します。...
AIのロードマップ
【これだけ!】AI(人工知能)の勉強ロードマップを徹底的に解説!当サイト【スタビジ】の本記事では、AIを勉強するロードマップについて徹底的に解説していきます。まずは、AIの概要について理解して統計学の基本知識・機械学習の基本知識・Pythonでの実装・インフラ周りの知識などを包括的に理解していきましょう!...

PythonでのAPI開発にFastAPIを使った方法を以下の記事で解説しています。

fastapi
【入門】PythonのFastAPIの使い方についてわかりやすく解説!当サイト【スタビジ】の本記事では、FastAPIの使い方を解説していきます!FastAPIはPythonでWeb APIを構築するためのフレームワーク!実際にFastAPIを触りながら使い方をマスターしていきましょう!...
スタビジアカデミーでデータサイエンスをさらに深く学ぼう!

スタアカサービスバナースタビジのコンテンツをさらに深堀りしたコンテンツが動画と一緒に学べるスクールです。

プレミアムプランでは私がマンツーマンで伴走させていただきます!ご受講お待ちしております!

スタビジアカデミーはこちら