はじめに
今回は、ChatGPTの新機能であるFunction callingを試します。
自分で作成したアプリから、ChatGPTの機能が呼び出せるとアイディア次第では便利ですね!
他にも私のブログで、ChatGPTについて解説している記事がありますのでご覧ください。
ChatGPTについて
ChatGPTは、OpenAIによって開発された大規模な自然言語処理モデルです。
ChatGPTについては以下の記事もご覧ください。
また、有料プランもあります。
以下の記事も参考にしてください。
Function calling
Function callingは、ユーザーの入力に応じてChatGPTのAPIが判断し関数を呼ぶことができます。
予め定義したプロパティ値を取得することができ、それにより独自のアプリケーションと連携することができます。
詳しくは公式のドキュメントをご覧ください。
VS Codeインストール
開発環境を構築します。
VS Codeのインストール方法は、以下の記事にまとめましたのでご覧ください。
VS Codeのオススメ設定や拡張機能などは、以下の記事にまとめました。
Docker Desktopのインストール
Macの場合はDockerのみですが、Windowsの場合はDocker(WSL2がバックエンド)が必要です。
Dockerのインストール方法は、以下の記事をご覧ください。
ChatGPTのAPIキーの取得
ChatGPTのAPIを利用するためには、アカウントを作成し、APIキーを取得する必要があります。
アカウントの作成方法は以下の記事を参考にしてください。
APIの登録方法については以下の記事を参考にしてください。
ログインした状態で、以下のサイトにアクセスします。
右上のメニューから、「View API keys」をクリックします。
「Create new secret key」をクリックし、APIキーを作成します。
APIキーが表示されます。
この画面でしかコピーできず、再度表示することができませんので注意してください。
Dockerコンテナの設定
開発環境のコンテナを作成するための定義を用意します。
任意の場所にプロジェクトフォルダを用意します。
Windows例:
\\wsl.localhost\Ubuntu\home\xxx\sample-app\
Mac例:
/users/xxx/Documents/sample-app
上記のフォルダの中に、「.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
設定はこれだけです。
リモート先の設定と、Dockerコンテナの定義を行いました。
VS Codeの起動
VS Codeを起動し、F1キーを押しコマンドパレットを開きます。
「Open Folder in Container」と入力し選択します。
参考までに以前とメニューの表示方法が変わりました。
先程作成したフォルダを選択します。
プロジェクトにはDockerの設定も含まれているため、初回起動時にはイメージとコンテナが自動で作成されます。
完了しました。
この時点で、Python環境のコンテナが作成され、リモートしている状態です。
実装
ChatGPTのAPIを利用した実装
今回はPythonを使って実装します。
ChatGPTのAPIを利用して、Pythonで実装するやり方は以下の記事を参考にしてください。
メール送信
それでは早速、実装をしてみましょう。
試しにメールを送信する処理を考えてみます。
メール送信関数を定義し、送信したい内容をユーザが入力します。
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がユーザの入力内容から、それぞれのプロパティ値を取得します。
応答結果は以下のようになりました。
{
"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}"
}
}
他サービス
他にもAIの便利なサービスがあります。
ChatPDFについては、以下の記事を参考にしてください。
AIにアプリを作ってもらえる、GPTAppです。
WebChatGPTでWebの情報を回答してもらうことができます。
さいごに
今回は、ChatGPTの新機能であるFunction callingを試してみました。
ぜひ試してみてくださいね。
他にも私のブログで、ChatGPTについて解説している記事がありますのでご覧ください。
コメント