Google ChatのBotにOpenAIのchatGPTを繋げてみた【GAS】

以前、Google ChatのBotをGoogle Apps Scriptで作成しました。これに対して最近話題のOpenAIのGPT-3で自動応答するボットを作成できないかなと思いたち、色々と情報を収集。OpenAIのGPT-3モデルのAPIを利用して、スラッシュコマンドを使って投げて応答を得るというものを追加で実装してみました。

よって、以下のエントリーを先に閲覧してからこのエントリーを参照していただくと理解がしやすいと思います。サービスアカウントの作成やらBotの作成については今回は省略しています。

Google Apps ScriptでGoogle Chatにメッセージを送る【GAS】

今回利用するスプレッドシート

今回はOpenAIのGPT-3, gpt-3.5-turboに投げる部分のみを追加実装していますので、そこの解説になります。

OpenAIについて

今話題になってる、人工知能chatGPTの作成元。現在誰でも簡単に利用できるAIチャットサービスですが、GoogleやらMicrosoftやらがこの登場によって急にザワザワし始めたかなり凄いという話で盛り上がってるサービスです。

図:こんな感じで応答してくれる

概要とGPT-3について

OpenAIではブラウザ上で使える形ではchatGPTを提供しています。しかし、まだ2023年2月時点では、招待制という形でこちらから使いたいというリクエストを投げて限られた人に対してだけ、chatGPTのAPIを提供するという形式になっているため、普通の人はchatGPTのAPIを利用したアプリケーションは作れません(試しにウェイトリストには登録してみた)。

現在、OpenAIで普通に提供されてるのはGPT-3.5と呼ばれるAPIであり、18ドル分の無償枠がついた有償のREST APIとなっています。つまり、chatGPTではありません。有効期限は登録月から4ヶ月。

APIはNode.jsやPython用にライブラリも用意されていますが、Google Apps Scriptからも普通にHTTPリクエストで利用することが可能です。よって今回作ってるものも、GPT-3.5と呼ばれるモデルになります。

※最新のGPT-4搭載のBingが誕生しています。

※本物のchatGPTのAPIがgpt-3.5-turboとしてリリースされました。

※2023年6月現在、この無償枠は5ドルとなっていて有効期限も3ヶ月と短縮。またこの無償枠は、最初の電話番号認証したものに対して有効なので、メアドに対してではない為、複数アカウントで無償枠を取ることは出来ません。

図:waitlistに登録してみた

chatGPT APIがリリースされた

2023年3月1日、OpenAIからchatGPTで使われているものと同じModelである「gpt-3.5-turbo」がリリースされました。つまり、本物のchatGPTのAPIが使えるようになっています。同時に音声テキスト変換のWhisper APIもリリースされています。

少々GPT-3とはリクエストの内容が異なり、また返ってくる答えの内容も異なりますので、コードも少しだけ変える必要があります。chatGPTを叩くコードは後述に記しておきます。

企業向けの大容量プランも出てきており、Microsoftも出資するなどこの領域が加速してきてます。

chatGPT Plusがリリースされました

2023年2月1日にはアナウンスされて、Bingの新版に搭載されて話題になったchatGPT-4ことchatGPT Plus。3月15日ついに日本でもエントリーが開始されました。ただし、chatGPT Plusは月額20ドルの有償版なので無償では利用ができません。すでにリファレンスにもgpt-4としてModelが登録されています。

特徴として、25000字にも及ぶプロンプト入力に対応しており、有償なのでピーク時でもアクセス応答時間が非常に短いという。また、画像を情報として与えて回答を得るといったことも可能になるようです。また、chatGPTの一番の問題点であった「適当な嘘を平気で回答する」という点にも改良が入ってるようで、少しだけわからないことはわからないと答えるようになったようです(ただし学習データは2021年9月までのデータを利用してる様子)

応答の能力も司法試験下位10%程度の能力だったものが、GPT-4からは上位10%に入るレベルというまことしやかな比較が伝えられています。現在はまだ100件/4時間程度の制限が加えられているようです。

コード体系もchatGPT 3.5 Turboと殆ど同じようなので、Modelの指定以外に変更はなさそうです。お試しはウェブはこちらから。

APIキーを取得する

18ドル分の枠内を超えた場合にはクレジットカードを登録して有償で利用することになりますが、プログラムで利用するためにはAPIキーを取得する必要があります。以下の手順でAPIキーを手に入れましょう。

  1. こちらのページにアクセスしてGET STARTEDをクリック
  2. アカウント作成画面になるので、今回は自身のGoogleアカウントでログインする
  3. 名前の入力などが出るのでそのまま進める。
  4. 電話番号入力欄が出るので自身の携帯電話番号を入れると、SMSで二段階認証のコードが飛んでくる
  5. 2段階認証を終えたら、アカウント作成完了
  6. overviewのページに辿り着くので右上の自身のアイコンをクリックする
  7. View API Keysをクリックする
  8. create new secret keyをクリックするとAPI Keyが生成されるのでコピーしておく。このキーは第三者と共有したり漏れたりしないように注意が必要です。

図:API Keyが手に入った

利用可能なモデル

現在、このAPIで利用可能なエンジンは4種類。今回のコードはこの中のGPT-3と呼ばれるtext-davinci-003というものを利用します。

  • text-davinci-003:今回利用する最も高性能なGPT-3モデルのAPI
  • text-curie-001:翻訳や要約などに向いてる高速なAPI
  • text-babbage-001:高速だけれど簡単な分類などに向いてるAPI
  • text-ada-001:一番最速で動くけれど性能は一番低い。

利用コスト

利用コストですが、試しに1日目に5回リクエスト、2日目に2回リクエストで使ってみました。ちょっとした質問とそこそこの回答を得ている状態ですが、以下のスクショのような感じで、1日目が0.02ドル、2日目が0.01ドルと18ドルの枠とは言えなかなかテストとしては利用ができそうです。

GPT-3のtext-davinciの場合は、1000トークン(1000語返す)毎に$0.02掛かります。概ね5問程度で1000トークンと仮定した場合、1ユーザが1日5問の問い合わせをしたとして、22営業日であるならば$0.44。ユーザ数が100人であるならば月間$44掛かる感じ。年間であるならば$528($1=135円ならば71,280円が年間コスト)。

トレーニングのコストというものもあるので単純計算できませんが、10万円程度を見た場合安いと考えるか?高いと考えるか?今後の進化の仕方次第で変わって来そうです。

※トークンはリクエストとレスポンスの合計でカウントされるみたいよ。

※この1トークンは、「あひる」で1ワード = 1トークンとなるようです。

※chatGPT APIの場合は1000トークン当たり$0.002なのでGPT-3よりも1/10のコストで現在利用可能です。音声テキストAPIであるWhisper APIのほうは、1分当たり$0.006という設定になっています。

図:結構使えると思います。

Chat APIにスラッシュコマンドを追加

GCP側のChat APIに対してスラッシュコマンドの受付を追加します。

  1. GCP側プロジェクトを開く
  2. サイドバーからAPIとサービス→有効なAPIとサービスを開く
  3. Google Chat APIをクリック
  4. 構成タブを開く
  5. スラッシュコマンドの項目で、新しいスラッシュコマンドを追加をクリック
  6. 今回はIDを2とし、コマンドを/gpt3として追加しました。このIDはソースコードのonMessageの中で判定に使います。

注意点として、onMessageはシンプルトリガーでありユーザの承認が不要で使える特殊な関数なのですが、Google Apps Scriptとは異なりタイムアウトが30秒までとなっているため、chatGPTからのレスポンスが30秒を超えてしまうと、タイムアウトでエラーとなってしまいます。

図:スラッシュコマンドを追加しておく

GPT-3を使ったケース

ソースコード

OpenAIにリクエストを投げるコード

リクエストと言っても特殊な部分はpayloadの部分だけ。ほかは一般的なRest APIと変わりません。リクエストのエンドポイントURLは「https://api.openai.com/v1/completions」で、APIキーはスクリプトプロパティのopenaikeyに格納していあります。

payloadの中でmodelではtext-davinci-003を指定、max_tokensが最大値2048ですがこれが返ってくる答えの文字数上限。temperatureは最大値2で返ってくる言葉のランダム性を指定します。分類などの場合は0で指定すると良い。他にもtop_pやecho, stop, presence_penalty, frequency_penaltyなどのパラメータなどもあるようです。

スラッシュコマンドを受け付けるコード

今回はIDが2として/gpt3というスラッシュコマンドを実装しています。よってこれが飛んできたら、上記のGPT-3のリクエストを投げる関数に渡す処理を追加しています。

実行結果

Google Chatで使った場合

実際に、Google Chatのスペースに作成したBotを追加して、スラッシュコマンドにて問い合わせをしてみました。以下のようなコマンド付きでチャット欄に入れてEnterを実行します。

上記の関数で受け取ってリクエストを投げて返ってきた内容がBotから返ってきました。GPT-3と言えどかなりいい加減な回答をすることも多く、まだまだ進化の過程とはいえ、これまでのようなチャットボットと違って、非常に人間的でただ単純に問い合わせに対して実直に答えてるだけではなく、その問い合わせに関連する内容までつけて返してくれるので、下手をすると人間よりもマシなケースもあります(1聞かれて1答えてるような人は、置き換えられちゃいますよ)

chatGPTのAPIがリリースされたら楽しみですね。今の所、特定の質問でテストしてみてますが、GPT-3のAPIとchatGPTでの回答は殆ど同じ。間違ってる部分も同じなので、十分な結果は得られてると言えます。

※もちろんスマフォ版のGoogle Chatアプリでも利用が可能です。社内用チャットボットに使えるかもしれませんね。

図:ただ回答が正しいとは限らない

図:もちろんスマフォのChatアプリでも使える

ユーザ定義関数として使った場合

実は上記のソースコードの「requestGPT3関数」は、そのままGoogle Spreadsheet上でのユーザ定義関数としても利用可能です。セルに関数名と引数に文字列を入れて上げれば、GPT3のAPIにアクセスして答えを返してくれます。

ユーザ定義関数としてだけ使う場合ならば、サービスアカウントであったりGCP連携等は必要無いので、一番最初にテストするケースとしては有用です。ただし、関数の場合スプレッドシートを開く度に実行されてしまうのと、関数の数だけリクエストが飛んでいってしまうので、使うシーンは限られると思います。

※ただし、関数として利用する場合タイムアウトが30秒程度なので、OpenAIからの応答が遅いとエラーになる事がある。GASの場合は最大6分までなのでまずエラーが起きることはないといった違いがあります。

Google Apps Scriptでユーザ定義関数を作る【GAS】

図:手軽にテストするならこのパターン

onMessageのタイムアウトを回避する

onMessageでスラッシュコマンドを受けて、chatGPTのレスポンスを同じ場所に返すように作られている今回のコードですが、onMessageがシンプルトリガーな為にタイムアウトは30秒が上限となっています。そのため、それ以上にレスポンスが遅れている場合には、タイムアウトエラーとなってしまうため、これを回避する必要があります。

  • この場合、onMessageでは質問文をプロパティに保存して、関数実行のトリガー設置だけで完了させる
  • トリガーは5秒後にrequestGPT_hookを実行するようにセットする
  • 予め、Google Chatの対象のルームのWebhookを取得しておく
  • requestGPT_hookは発火時に1.で格納しておいた質問文を取得後、プロパティを空にしてトリガーを削除してから、chatGPTに質問文を投げる
  • レスポンスデータが返って来たら、pushWebhookにて2.で取得しておいたWebhook宛に質問文を返すようにする
  • 複数名で利用する場合には、プロパティの値がバッティングすると思うので、そこはユーザプロパティを使う等のジョブキュー処理をより適切に構築する必要があります(例えばjobが0だったら質問を受け付ける。まだ0じゃない場合は、拒否して「ちょっと待て」と返して終わらせる等)

onMessageの30秒の制限を回避しつつ、GASの6分の制限を超えなければこれで複雑な質問文を投げたものを受け付けることが可能です。

図:タイムアウトしちゃった事例

図:Webhookで投げ返すのがポイント

図:無事に複雑な指示の答えが返ってきた

chatGPTを使ったケース

chatGPTことgpt-3.5-turboのリファレンスはこちらにあります。リクエストエンドポイントが異なる点と返り値が異なる点以外は、パラメータの指定も殆ど同じなので、GPT-3用コードを少し改造するだけで問題なく動作します。

ソースコード

  • GPT-3の時に取っておいたAPI Keyでそのまま利用可能です。
  • 応答するスピードが向上してる気がします。
  • エンドポイントは「https://api.openai.com/v1/chat/completions」に変更されています。
  • payloadのModelではgpt-3.5-turboを指定します。「gpt-3.5-turbo-0301」というのも指定できるようです。
  • ユーザのテキストはpromptではなく、messagesで指定し、roleではuser, system, assistantの3種類が指定できるようです。
  • 返り値を取り出すにはresult.choices[0].message.contentで取得できますが、リクエストのmessagesで複数指定も可能になってるのでここは見極めが必要です。
  • messagesで複数含められるのは、過去の発言を取り込んでの発言を指定出来る点。userがユーザの発言、assistantがAPIが返した答えといった形で、配列に複数の指定が可能。以下がその指定例。
  • systemロールは、AIに対して設定を命令するもので、「○%の確率で文章に対して○○せよ」といったものがそれに該当します。参考事例はこちらのページがとてもわかり易いです。
  • Google Chatで上記の過去発言を元に使うような場合、発言のID、過去チャット使うというフラグとスプレッドシートに発言をログ(その際にユーザやアシスタントのフラグも付けておく)を元に、取得して判定させると良いかも。

実行結果

簡単な質問を投げてみた結果

簡単な質問をchatGPTに投げて返ってきた例です。細かくパラメータの指定やroleを指定して調整して返すことが出来るようになっています。リリース仕立てのAPIですが、素直に使えるように作られているため、あまり迷うことなく再構築ができました。

GPT-3でデプロイしていても、GAS上で再デプロイするだけでGCP側もいじらずにGoogle Chatの応答を変更出来るのでGASで構築は相性が良さそうです。

また、「美味しいお蕎麦の作り方について、どう考えますか?」と聞いたら、日本語じゃなく英語で返ってきました・・・・関数でテストしたら、日本語で返ってきました。ちょっとまだ不安定な様子です。

図:これで正式にchatGPTがアプリで使える

GASのコードを要求してみた

マイナーなWeb会議システムWebexのAPIを使って、Webhookを設置するGoogle Apps Scriptのコードを要求してみた。自分自身の書いたコードは以下のエントリーを参照してください。

Google Apps ScriptでWebex APIを操作する【GAS】

実際に返ってきたコードはなんかちょっと古い。けれど、概ね自分が書いたコードに近い。マイナーな上にGoogle Apps Scriptで書いてる記事は非常に少ないにも関わらず、ここまで書けるのはなかなか凄いのではないかと思う。自分はこのコードを書くまでの下調べでも相当掛かってるのに、割と答えに8割くらい近づけてしまうのは、ちょっとした恐怖ですよ。

関連リンク

Google ChatのBotにOpenAIのchatGPTを繋げてみた【GAS】” に対して3件のコメントがあります。

  1. ME より:

    お世話になっております。
    本ページの内容について非常に参考になっております。
    本ページの手順に従いましてGoogleChat botを作成し、ChatGPTにつなげることができましたが、
    botからスラッシュコマンドでGPTに質問を投げ、レスポンスが遅い場合に
    onMessage関数が30秒あたりでタイムアウトとなります。
    スプレッドシートからのカスタムユーザ関数で呼ばれた場合のタイムアウトは30秒だと認識しておりますが
    botから呼び出したonMessage関数は6分制限のはずではと思い調査しておりますが糸口がつかめません。
    GASの「実行数」から確認するとonMessage関数で種別は「アドオン」となっております。
    このような場合、どのような原因が考えられるでしょうか。

  2. officeの杜 より:

    ME様

    officeの杜管理人です。onMessageはシンプルトリガーとなるため、30秒が上限となります。そこでこれを回避するには、onMessageではchatGPTに質問を投げずに、スクリプトトリガーにてchatGPTに質問を投げる関数を予約として設置しておき、5秒後に発火させるようにします。

    そちらは6分の制限となるため、chatGPTからレスポンスを受け取ったら、Google ChatのルームのWebhookに対して投稿し返すように作ると、制限を回避する事が可能です。

    「onMessageのタイムアウトを回避する」としてコードを追記しましたので、ご覧ください。

  3. ME より:

    管理人様
    お忙しいところご回答いただきましてありがとうございます。
    追記していただきました内容を確認し再度試してみます、

    どうもありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。