広告

【ChatGPT】Function callingを本格実装

【ChatGPT】Function callingを本格実装 ChatGPT

当サイトではアフィリエイト広告を利用しています。

広告

はじめに

今回は、ChatGPTの新機能であるFunction callingを試します。
自分で作成したアプリから、ChatGPTの機能が呼び出せるとアイディア次第では便利ですね!

他にも私のブログで、ChatGPTについて解説している記事がありますのでご覧ください。

ChatGPTについて

ChatGPTは、OpenAIによって開発された大規模な自然言語処理モデルです。

ChatGPTについては以下の記事もご覧ください。

【ChatGPT】エンジニアが試してみた
何かと話題のAI、「ChatGPT」を試してみました。

また、有料プランもあります。
以下の記事も参考にしてください。

ChatGPT Plusの申し込み方法
有料プランであるChatGPT Plusに申し込む方法と、試しに使ってみました。

Function calling

Function callingは、ユーザーの入力に応じてChatGPTのAPIが判断し関数を呼ぶことができます。
予め定義したプロパティ値を取得することができ、それにより独自のアプリケーションと連携することができます。

詳しくは公式のドキュメントをご覧ください。

function-calling

手軽に独自アプリとChatGPTを連携させることができます。

VS Codeインストール

開発環境を構築します。

VS Codeのインストール方法は、以下の記事にまとめましたのでご覧ください。

【VS Code】インストール手順を解説 【Windows/M1 Mac対応】
今回はVS Codeのインストール手順を解説します。WindowsとMacのそれぞれ分けてまとめました。

VS Codeのオススメ設定や拡張機能などは、以下の記事にまとめました。

【VS Code】オススメの設定・拡張機能・便利機能・ショートカット【Win/Mac対応】
私的に最初に行う設定や、拡張機能、よく使うショートカットや便利な機能をまとめてみました。
広告

Docker Desktopのインストール

Macの場合はDockerのみですが、Windowsの場合はDocker(WSL2がバックエンド)が必要です。
Dockerのインストール方法は、以下の記事をご覧ください。

Windows
【Docker Desktop】Windowsにインストール(WSL2)
WindowsにDockerをインストールする手順を解説します。ついでにPython環境を、コンテナに構築してみたいと思います。
Mac
【Docker Desktop】Macにインストール【Monterey/M1】
MacにDockerをインストールする手順を解説します。ついでにPython環境を、コンテナに構築してみたいと思います。

ChatGPTのAPIキーの取得

ChatGPTのAPIを利用するためには、アカウントを作成し、APIキーを取得する必要があります。

アカウントの作成方法は以下の記事を参考にしてください。

【ChatGPT】エンジニアが試してみた
何かと話題のAI、「ChatGPT」を試してみました。

APIの登録方法については以下の記事を参考にしてください。

【ChatGPT】OpenAI API 有料アカウント登録
OpenAI APIの有料アカウントの登録方法をまとめました。

APIキーの利用には料金がかかります。詳しくはOpenAIのサイトをご確認ください。

ログインした状態で、以下のサイトにアクセスします。

platform.openai.com

右上のメニューから、「View API keys」をクリックします。

OpenAI View API keys

「Create new secret key」をクリックし、APIキーを作成します。

OpenAI Create new secret key

APIキーが表示されます。
この画面でしかコピーできず、再度表示することができませんので注意してください。

OpenAI API Key

APIキーは絶対に他人に知られないようにしましょう。

Dockerコンテナの設定

開発環境のコンテナを作成するための定義を用意します。

この設定ファイルは、プロジェクトを作成する度に活用できます。

任意の場所にプロジェクトフォルダを用意します。

Windows例:
\\wsl.localhost\Ubuntu\home\xxx\sample-app\
Mac例:
/users/xxx/Documents/sample-app

Windowsの場合、保存場所はWSLを指定しましょう。
Cドライブなどに保存した場合、ファイルシステムの関係で読み込みが遅くなります。

上記のフォルダの中に、「.devcontainer」フォルダを作成し、このようにファイルを作成します。

/
└ .devcontainer/
  ├ devcontainer.json
  └ Dockerfile

devcontainer.jsonを作成し中身を以下のようにします。
Dockerfileで作成ということと、拡張機能のインストールを記述します。

{
	"name": "Python Sample",
	// Dockerfileでイメージ・コンテナを作成
	"dockerFile": "Dockerfile",
	// リモート先のVS Codeにインストールする拡張機能
	"customizations": {
		"vscode": {
			"extensions": [
				"ms-python.python"
			]
		}
	},
}

Dockerfileを定義します。
Python環境のイメージを使用し、OpenAIのライブラリをインストールします。

FROM python:3 
ENV PYTHONUNBUFFERED 1
 
RUN pip install openai

PYTHONUNBUFFERED」は、Pythonの標準出力のバッファリングを無効にします。
アプリケーションの出力(ログなど)をリアルタイムで確認できるようになります。

設定はこれだけです。
リモート先の設定と、Dockerコンテナの定義を行いました。

以降の解説キャプチャはWindowsをベースにしていますが、Macでの操作も同様です。

VS Codeの起動

VS Codeを起動し、F1キーを押しコマンドパレットを開きます。
「Open Folder in Container」と入力し選択します。

VS Code Open Folder in Container

参考までに以前とメニューの表示方法が変わりました。

【VS Code】Dev Containersで「Open Folder in Container」などのメニューが表示されない
Dev Containers拡張機能のメニューの表示に仕様変更があったためまとめました。

先程作成したフォルダを選択します。
プロジェクトにはDockerの設定も含まれているため、初回起動時にはイメージとコンテナが自動で作成されます。

VS Code Dev Container Building image

完了しました。
この時点で、Python環境のコンテナが作成され、リモートしている状態です。

VS Code Dev Container start

実装

ChatGPTのAPIを利用した実装

今回はPythonを使って実装します。
ChatGPTのAPIを利用して、Pythonで実装するやり方は以下の記事を参考にしてください。

【Python】ChatGPT APIを使って連携
PythonでChatGPTのAPIを利用して実装します。

メール送信

それでは早速、実装をしてみましょう。
試しにメールを送信する処理を考えてみます。

メール送信関数を定義し、送信したい内容をユーザが入力します。

import openai
import json

# TODO: APIキーのハードコーディングは避ける
openai.api_key = "APIキー"

# ユーザ入力
sentence = "明日の10時から打合せする件メールを送信する。佐藤さんのアドレスはxxxxxxxx.sato@gmail.comです"

# ユーザの入力した情報から、指定したプロパティを取得する
response = openai.ChatCompletion.create(

    # モデルを指定する
    model="gpt-3.5-turbo-0613",

    messages=[
        {
            "role": "user",
            "content": sentence
        },
    ],

    # 関数定義(複数の定義が可能)
    functions=[
        {
            "name": "send_email",
            "description": "メールを送信する",
            "parameters": {
                "type": "object",
                # プロパティ
                "properties": {
                    "email": {
                        "type": "string",
                        "description": "送信先メールアドレス"
                    },
                    "subject": {
                        "type": "string",
                        "description": "メール件名"
                    },
                    "content": {
                        "type": "string",
                        "description": "メール本文"
                    }
                },
                "required": ["email"]
            }
        }
    ],
    function_call="auto",
)

# 応答結果の出力
print(response["choices"][0]["message"])


# argumentsを出力する場合
#arguments = json.loads(response["choices"][0]
#                       ["message"]["function_call"]["arguments"])
#print(arguments)

ユーザ入力によって、関数を呼ぶか通常のChatGPTを呼ぶか変わります。
そのため、応答結果の「function_call」が含まれない場合がある点に注意です。

上記のように関数を定義し、取得したいプロパティを指定します。
ChatGPTがユーザの入力内容から、それぞれのプロパティ値を取得します。

応答結果は以下のようになりました。

{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "send_email",
    "arguments": "{\n  \"email\": \"xxxxxxxx.sato@gmail.com\",\n  \"subject\": \"\u660e\u65e5\u306e\u6253\u5408\u305b\u306b\u3064\u3044\u3066\",\n  \"content\": \"\u660e\u65e5\u306e10\u6642\u304b\u3089\u6253\u5408\u305b\u3092\u884c\u3044\u307e\u3059\u3002\u4f1a\u8b70\u5ba4\u3067\u304a\u5f85\u3061\u3057\u3066\u304a\u308a\u307e\u3059\u3002\"\n}"
  }
}
{'email': 'xxxxxxxx.sato@gmail.com', 'subject': '明日の打合せについて', 'content': '明日の10時から打合せを行います。会議室でお待ちしております。'}

プロパティが取得できたら、独自アプリの処理と回答結果を生成します。

# 応答メッセージを取得する
message = response["choices"][0]["message"]

if message.get("function_call"):
    # 関数呼び出しの場合

    function_name = message["function_call"]["name"]

    if function_name == "send_email":
        # 呼び出された関数によって制御

        # プロパティを取得
        arguments = json.loads(message["function_call"]["arguments"])

        # ユーザの入力から値を取得できる
        # TODO: ここで独自アプリの処理を行う。例えばメールを送信する
        print(arguments.get("email"))
        print(arguments.get("subject"))
        print(arguments.get("content"))

        # 関数の応答結果(必要に応じて追加する)
        function_response = json.dumps({
            "email": arguments.get("email"),
            "subject": arguments.get("subject"),
            "content": arguments.get("content"),
        })

        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                # ユーザ入力
                {
                    "role": "user",
                    "content": sentence
                },
                # ChatGPT応答
                message,
                {
                    # 関数、応答結果
                    "role": "function",
                    "name": function_name,
                    "content": function_response,
                },
            ],
        )

        # 回答結果を取得
        print("-------------")
        chat_results = second_response["choices"][0]["message"]["content"]
        print(chat_results)

TODOと記載しましたが、取得できたプロパティ値を基に独自の処理を行いましょう。
その回答結果をChatGPTに生成させます。

最終的な回答結果は以下のように出力されました。

明日の10時から打合せがあります。参加してください。
佐藤さんのアドレスはxxxxxxxx.sato@gmail.comです。
以上の内容でメールを送信しました。

検索クエリの取得

記事を検索するための関数を作成してみました。

import openai
import json

# TODO: APIキーのハードコーディングは避ける
openai.api_key = "APIキー"

# ユーザ入力
sentence = "Laravelのログイン機能の記事を検索したい"

# ユーザの入力した情報から、指定したプロパティを取得する
response = openai.ChatCompletion.create(

    # モデルを指定する
    model="gpt-3.5-turbo-0613",

    messages=[
        {
            "role": "user",
            "content": sentence
        },
    ],

    # 関数定義(複数の定義が可能)
    functions=[
        {
            "name": "get_articles",
            "description": "WordPressの記事を検索し一覧を取得します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "検索クエリ"
                    }
                },
                "required": ["query"],
            },
        }
    ],
    function_call="auto",
)

print(response["choices"][0]["message"])

# argumentsを出力する場合
#arguments = json.loads(response["choices"][0]
#                       ["message"]["function_call"]["arguments"])
#print(arguments)

以下のようにプロパティ値(検索クエリ)を取得できました。

{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_articles",
    "arguments": "{\n  \"query\": \"Laravel \u30ed\u30b0\u30a4\u30f3\u6a5f\u80fd\"\n}"
  }
}
{'query': 'Laravel ログイン機能'}

記事一覧を返却する処理を書いてみましょう。

# 応答メッセージを取得する
message = response["choices"][0]["message"]

if message.get("function_call"):
    # 関数呼び出しの場合

    function_name = message["function_call"]["name"]

    if function_name == "get_articles":
        # 呼び出された関数によって制御

        # プロパティを取得
        arguments = json.loads(message["function_call"]["arguments"])

        # ユーザの入力から値を取得できる
        # TODO: ここで独自アプリの処理を行う。例えば検索をする
        print(arguments.get("query"))

        # 関数の応答結果
        # 検索結果を取得した想定でデータを作成
        function_response = json.dumps({
            "query": arguments.get("query"),
            "articles": [
                {
                    "url": "https://chigusa-web.com/blog/laravel8-breeze/",
                    "title": "【Laravel8/9/10】認証機能の導入 (Breeze)"
                },
                {
                    "url": "https://chigusa-web.com/blog/laravel-sail/",
                    "title": "Laravel Sailで開発環境構築【Vite対応】"
                },
            ]
        })

        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                # ユーザ入力
                {
                    "role": "user",
                    "content": sentence
                },
                # ChatGPT応答
                message,
                {
                    # 関数、応答結果
                    "role": "function",
                    "name": function_name,
                    "content": function_response,
                },
            ],
        )

        # 回答結果を取得
        print("-------------")
        chat_results = second_response["choices"][0]["message"]["content"]
        print(chat_results)

以下のように回答結果を取得できました。

以下の記事は、Laravelのログイン機能についての情報を提供しています:

1. [【Laravel8/9/10】認証機能の導入 (Breeze)](https://chigusa-web.com/blog/laravel8-breeze/) - Laravel 8/9/10で利用できるBreezeパッケージを使用して、認証機能を導入する方法について解説しています。

2. [Laravel Sailで開発環境構築【Vite対応】](https://chigusa-web.com/blog/laravel-sail/) - Laravel Sailを使用して、開発環境を構築する方法について解説しています。この記事では、Viteと組み合わせて使用することも紹介されています。

これらの記事を参考にすると、Laravelのログイン機能を理解し、実装することができるでしょう。
広告

関数の複数定義

関数は複数定義できます。
ChatGPTがユーザの入力に応じて、関数を選択します。

import openai
import json

# TODO: APIキーのハードコーディングは避ける
openai.api_key = "APIキー"

# ユーザ入力
sentence = "明日の東京の天気は"

# ユーザの入力した情報から、指定したプロパティを取得する
response = openai.ChatCompletion.create(

    # モデルを指定する
    model="gpt-3.5-turbo-0613",

    messages=[
        {
            "role": "user",
            "content": sentence
        },
    ],

    # 関数定義(複数の定義が可能)
    functions=[
        {
            "name": "get_current_weather",
            "description": "指定された地域の天気を取得する",
            "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g. San Francisco, CA",
                        },
                        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                    },
                "required": ["location"],
            },
        },
        {
            "name": "send_email",
            "description": "メールを送信する",
            "parameters": {
                "type": "object",
                "properties": {
                    "email": {
                        "type": "string",
                        "description": "送信先メールアドレス"
                    },
                    "subject": {
                        "type": "string",
                        "description": "メール件名"
                    },
                    "content": {
                        "type": "string",
                        "description": "メール本文"
                    }
                },
                "required": ["email"]
            }
        },
        {
            "name": "get_articles",
            "description": "WordPressの記事を検索し一覧を取得します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "検索クエリ"
                    }
                },
                "required": ["query"],
            },
        }
    ],
    function_call="auto",
)

print(response["choices"][0]["message"])

arguments = json.loads(response["choices"][0]
                       ["message"]["function_call"]["arguments"])
print(arguments)

3つの関数を定義していますが、ユーザの入力で天気を聞いたところ、きちんと関数が応答されているのが分かります。

{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\n  \"location\": \"Tokyo\"\n}"
  }
}

このように、関数を定義し簡単にChatGPTと連携し、その応答結果により独自の処理を行うことができます。

他サービス

他にもAIの便利なサービスがあります。

【オススメ】AIサービス
厳選したオススメのAIサービスを紹介します。

ChatPDFについては、以下の記事を参考にしてください。

ChatPDFを試してみた
ChatPDFを試してみました。PDFファイルを読み込ませ、ChatGPTのようにチャットすることができます。

AIにアプリを作ってもらえる、GPTAppです。

【ChatGPT】GPTAppでアプリを作成【AI】
ChatGPT APIを利用しているサービスである、GPTAppを試してみました。

WebChatGPTでWebの情報を回答してもらうことができます。

WebChatGPTでWebの情報を回答してもらおう
ChatGPTを拡張して使用できる、WebChatGPTを試してみました。

さいごに

今回は、ChatGPTの新機能であるFunction callingを試してみました。

ぜひ試してみてくださいね。

他にも私のブログで、ChatGPTについて解説している記事がありますのでご覧ください。

AIChatGPTPythonツールプログラミング
広告

個人開発

千草 @chigusaweb

現役のITエンジニア。 気ままにコードを書いたり技術情報を発信しています。 Webアプリ/Windows・Macアプリ/モバイルアプリなど。 (Java, PHP, Javascript, Swift, Python, C#, 他) 個人開発:Clibor, Quipha, TXT-Crypter, 符計算特訓, チグサツール Kindle本: Laravel9 実践入門, 他

クリップボード履歴

Clibor

Windows

Cliborはシンプルで高機能なクリップボード履歴ソフトです。 また普段よく使うワードを定型文として登録し、いつでもクリップボードに保存することができます。高度なテキスト整形・FIFOモード・ホットキーに対応。

クリップボード履歴

Windows版Cliborの利便性を、そのままMacでも。 定型文登録、高度なテキスト整形、FIFOモードなど、便利なクリップボード履歴機能を利用できます。macOS最新のTahoeにも対応。

テキスト暗号化

テキストを暗号化してURLで共有・保存できる無料サービスです。 パスフレーズを知る人だけが復号できます。登録不要、データはサーバーに保存されません。 Notionでも利用できます。

学習

Quipha

Web / iOS

自分だけの問題集や問題を作成し、クイズを行い、学習に活用することができるアプリです。 例えば、学校の授業、語学学習、IT資格やその他の資格など多彩な分野での学習を支援します。 いつでも、どこでも、あなたの学習をサポート。

ツール

日常の「ちょっとした効率化」をサポートするWeb便利ツール集。 テキスト・データ処理から最新のAI連携まで、日々のちょっとした手間でググりがちなユーティリティを1つの場所に集約。

麻雀

麻雀の符計算をひたすら特訓しマスターしましょう。 初心者の方はもちろん、もっと速く計算したい方にも役立ちます。 5万対局以上の実践から問題を収録。

コメント

タイトルとURLをコピーしました