Excel VBAで会話するChatGPT

第1回

Excel VBAを使ってChatGPTのAPIを呼び出す関数を作成しよう!

 この記事はインプレス刊『生成AIをWord&Excel&PowerPoint&Outlookで自在に操る超実用VBAプログラミング術』(近田伸矢 著/古川渉一 監修)の一部を編集・転載しています(編集部)

『生成AIをWord&Excel&PowerPoint&Outlookで自在に操る超実用VBAプログラミング術』

 ChatGPTやDALL-Eなどの生成AIを身近に感じる機会がグッと増えていると感じる方は多いのではないでしょうか? 中でもマイクロソフト社の「Copilot Pro」や「Copilot for Microsoft 365」など、生成AIをWordやExcel、PowerPoint、Outlookなどで活用できるサービスが大きな注目を集めているようです。

 Officeアプリ上で生成AIを活用する方法は、こうしたサービスだけではありません。それが各生成AIをVBAプログラミングでコントロールする方法です。書籍『生成AIをWord&Excel&PowerPoint&Outlookで自在に操る超実用VBAプログラミング術』では、そんなプログラミング術を余すことなく解説しています。ここではその可能性を感じてもらうべく、ExcelとChatGPTを連携するプログラミング方法を紹介しましょう。

サンプルファイル(ZIP形式:47KB)


※右クリックメニューからダウンロードしてください

APIを使った「ChatGPT」関数の作成

 Excel VBAを使用して、ChatGPTのAPIを呼び出す関数を作成します。始めに、ChatGPTへの質問とその回答を管理するワークシートの設計を行い、続いてプログラム処理の流れを整理します。この処理の流れを基に、具体的な作成方法を詳しく解説していきます。

「質問」に質問内容を入力(①)し、右上にある[会話する](②)をクリックすると、ChatGPTからの回答が「回答」に表示(③)される

ChatGPT シートの設計と処理の流れ

 以下のサンプルファイルを使用します。シート上でChatGPTに与えるプロンプト(会話内容)、Role-SystemなどAPIに引き渡すパラメータを入力できるようにします。ChatGPTからの応答内容も同じシート上の「回答」に表示させます。プロンプトに会話内容を入力し、「会話する」ボタンをクリックするとChatGPTからの回答が表示されるというシンプルな仕組みです。

サンプルファイル(ZIP形式:47KB)


※右クリックメニューからダウンロードしてください

サンプルファイルにはあらかじめ書式やボタン(①) が用意されている
処理の流れ

Function プロシージャ「ChatGPT」の作成

 OpenAIのChatGPTをVBAから活用する核心部分であり、他のOfficeアプリからも呼び出すことができる汎用的な関数となります。大きく分けて次のような処理構成となっています。ここでは順に作成、解説していきます。

  1. APIキーの設定
  2. 関数と引数の設定
  3. モデルの設定
  4. JSON文字のエスケープ
  5. JSON文字のアンエスケープ
  6. リクエストボディの構築
  7. リクエスト実行とレスポンスの取得
  8. JSONのパースと再リクエスト

モジュールの作成

 まず、これからコードを記述していくモジュールを作成します。Visual Basic Editor画面で、標準モジュールを挿入し、オブジェクトブラウザーで名前を「GPT」に変更しましょう。

VBEを起動して[挿入](①)をクリックし、[標準モジュール](②)をクリックする
標準モジュールが挿入(③)されたこと確認して、オブジェクトブラウザーにある[(オブジェクト名)]に「GPT」(④)と入力する
プロジェクトエクスプローラーのモジュール名が「GPT」(⑤)に変更された

APIキーの設定

 ChatGPT APIを利用するにはAPIキーが必要です。まず、GPTモジュールの先頭に、変数宣言を必要とするOption Explicitを記述し、変数にまつわるコーディングミスを減らせるようにします。記述したら、APIキーを設定する以下を入力します。

サンプル03-01.txt

 「Your APIkey」にはOpenAIから取得したAPIキーを設定します。広域のPublicで定数を宣言することで、以降、どのモジュールからもAPIkeyの値が参照できるようになります。

ChatGPT APIのパラメータに対応した引数の設定

 ChatGPTのAPIにはさまざまなパラメータがあります。リクエストのたびに可変となるパラメータは、目的や状況に応じて呼び出し時に指定できるよう、ChatGPT関数の引数として受け取れるようにします。テキストメッセージは必須の引数、その他は省略可能(Optional)として、使い勝手の向上を図ります。使用するChatGPTのモデルはChatGPT関数呼び出し時に指定できるようにしますが、指定されなかったときに参照するPublic変数「GPTmodel」も宣言します。別のプロシージャ「SetGPTmodel」によりGPTmodelにモデル名を格納します。

サンプル03-02.txt
パラメータと引数
引数説明省略
Textモデルに対する主要な入力テキスト不可
RoleSystemChatGPTに対する全体的な役割を指定します可能
Temperatureモデルが出力する一貫性やランダム性を指定します。引数で指定がない場合は、デフォルト値を0.4としています可能
MaxTokensAPIの応答として受け取ることができるトークンの最大数でトークンは、テキストを分割する単位で、英語の場合、1トークン=1単語となっていますが、日本語の場合の詳細は明らかになっておらず、およそ1000トークンで6~700文字程度と考えられています。引数で指定がない場合は2000トークンをデフォルト値としています可能
WaitChatGPTのレスポンスを待つ最大時間(秒)です。指定がない場合のデフォルト値は60秒としています。この時間を超えると、再度リクエストします可能
Model使用するGPTモデルを指定します可能
PrevU連続的な会話を行う際、会話履歴をChatGPTに提供するための引数です。過去のユーザーメッセージを「;;;」で区切って、新しい順に文字列として指定します。この「;;;」は、引数PrevUとPrevAでのみ使用する特別な区切り文字です。単発の会話を行う場合は、この引数は不要です可能
PrevAPrevUと対をなす過去のアシスタントのメッセージを示す引数です。PrevUと同じく、新しい順に「;;;」で区切って指定します。通常、過去の会話はユーザーとアシスタントが交互に行うため、PrevUとPrevAの会話履歴の数は等しくなります。同数としなくても、ChatGPTは受け取りますが、過去の会話の流れが乱れ、おかしな解釈となる可能性があるため、注意が必要です可能
【ワンポイント】2つの重要なパラメータを理解する

 APIへ送信するメッセージには「role」と「content」の二つのフィールドがあります。「role」はメッセージの役割を示し、「content」はその内容を表します。「role」に「system」を設定すると、ChatGPTの振る舞いに関する指示やガイダンスを「content」に記述でき、「あなたは小学校の先生です」といった特定のキャラクターやトーンで応答させることができるようになります。また「role」に「user」を設定した場合は質問やその履歴に、「assistant」は回答の履歴に使われます。「role:system」はChatGPTとの会話をより楽しむための有用なパラメータといえるでしょう。

【Column】創造性をコントロールできる「Temperature」パラメータ

 「Temperature」は、生成されるテキストの一貫性と多様性のバランスを調整します。この設定は0.0 ~ 2.0で行い、低い値(たとえば0.1、0.2)は一貫した確実な回答に、高い値(たとえば0.8、1.0)は多様性と意外性を増加させます。最大値の2.0近くでは非理論的な回答となる場合もあります。標準的な回答を求める場合は低めに、創造的なアイデアが欲しい場合は少し高め(1.0まで)に設定すると良いでしょう。

ChatGPT モデルの設定

 プロシージャ開始時に、使用するChatGPTモデルの設定を行います。ChatGPTモデルにはいくつかのバージョンが存在し、性能や料金が異なります。モデルは、ChatGPT関数呼び出し時に指定可能としますが、指定されなかったときは、モジュールの冒頭で宣言したPublic変数「GPTmodel」を適用します。このGPTmodelは、別のプロシージャ「SetGPTmodel」でモデルを指定します。いずれの指定もない場合は、性能のよい「gpt-4-1106-preview」モデルを適用します。

サンプル03-03.txt

※2024年1月に新しいモデルであるGPT-4 Turboが発表されています。新しいモデルを指定するには、サンプル03-03.txtの18行目にある「gpt-4-1106-preview」を書き換えます。例えば、最新のGPT-4 Turboを指定するには「gpt-4-0125-preview」と書き換えましょう。その他、他のモデルを指定するときは、以下にあるOpenAIのWebページを参考にしてください。

ChatGPT のモデルとコスト

 ChatGPTのモデルには、大きく分けてGPT-3.5と、さらに改良を加えたGPT-4があり、それぞれ、トークン数やコストが異なるさまざまなバージョンが存在しています。2023年11月に開催されたOpenAI DevDayというイベントで発表され、使用できるようになった新しい2種類のモデル、GPT-4 Turbo(gpt-4-1106-preview)、GPT-3.5 Turbo(gpt-3.5-turbo-1106)は大きく進化し、既存バージョンのモデルすべてを置き換えることができるほどの性能とコストパフォーマンスを兼ね備えています。性能よりコストを重視する場合は、デフォルトを「gpt-3.5-turbo-1106」に変更するとよいでしょう。

ChatGPTの利用価格

 「gpt-4-1106-preview」に関しては、発表から数週間程度でプレビュー(評価)版から正式版への移行がアナウンスされています。それに伴い、モデル名が「gpt-4-turbo」に変更されることが見込まれていますので、最新のモデルや価格に関して、OpenAIの公式サイトで確認し、それに合わせて、モデル名を指定するコードを変更しましょう。

JSON 文字のエスケープ処理

 ChatGPT APIとのデータ授受は、軽量なテキストベースのフォーマット「JSON形式」で行われます。しかし、VBAから入力された文字は、そのままではJSONとして処理できません。JSONではたとえばダブルクォート (") が文字列の開始と終了を示す役割を持っており、文字列中にダブルクォートが存在すると、JSONはそれを誤解釈してしまいます。これを解消するための手法がエスケープで、この場合、ダブルクォート (") を連続して ("") のように記述することで誤解釈を回避します。同様に、バックスラッシュや改行などの特定の制御文字もエスケープする必要があります。これらのエスケープ処理を簡単に行えるよう、Functionプロシージャ「EscapeJSON」として関数化します。この関数を呼び出すことで、ChatGPTのAPIがVBAからの入力を正確に解釈できるようになります。

サンプル03-04.txt
置き換える特殊文字
バックスラッシュ¥¥¥
スラッシュ/'¥/
バックスペース(vbBack)Chr(8)¥b
タブ(vbTab)Chr(9)¥t
ラインフィード(vbLf)Chr(10)¥n
垂直タブ(vbVerticalTab)Chr(11)¥t
フォームフィード(vbFormFeed)Chr(12)¥f
キャリッジリターン(vbCr)Chr(13)¥r
ダブルクォートChr(34)"¥" & Chr(34)
環境に応じた改行記号(vbNewLine)vbNewLine¥n

JSON 文字のアンエスケープ処理

 ChatGPT APIから受け取るレスポンスもJSON形式の文字列です。VBAでこの文字列を正しく扱えるよう、JSONの特殊文字やエスケープされた文字を通常の文字列に変換する処理が必要となります。Functionプロシージャ「UnescapeJSON」として関数化することで、これらの変換処理を簡単に行えるようにします。

サンプル03-05.txt
【Column】JSONのパースを理解するメリットとは

 JSON(JavaScript Object Notation)は、もともとJavaScriptで使うためのデータ表現方法として生まれました。その明瞭でシンプルな構造は、多くの技術者から高く評価され今ではさまざまなプログラミング言語やシステムでデータ交換のために採用されています。JSONは、基本的にキーと値のペアでデータを表現し、配列やネストされたオブジェクトといった複雑なデータ構造もシンプルに表すことができます。そのため、近年、APIの通信、設定ファイルの保存、そしてデータの格納など、さまざまな場面でJSONが使われるケースが増えています。Pythonなどの言語ではJSONをパース(解析)できるライブラリーを利用することで、簡単にJSONから必要な値を取り出すことができますが、本書で解説しているように自力でJSONをパースすることで、そのフォーマットを知り、解釈する力を身に付けることも価値あることではないでしょうか。

エスケープの実行

 ChatGPT関数のコードに戻り、作成したEscapeJSON関数をChatGPT関数から呼び出しましょう。これにより、ChatGPT APIに引き渡す文字列をJSON形式で正しく解釈されるよう変換できるようになります。変換処理を関数化したので、簡潔なコードで実行できます。

サンプル03-06.txt

リクエストボディの構築

 ChatGPTのAPIにリクエストする際の中身であるリクエストボディを構築していきます。

 まず、会話部分をmsgPartとして構築します。過去のユーザーとアシスタントのメッセージ(会話履歴)、RoleSystem(役割)、RoleUser(直近の会話、質問)の順に処理します。過去の会話履歴を適切に取り扱うことで、ChatGPTは以前のコンテキストを持って会話を継続できるようになります。

サンプル03-07.txt

リクエストボディのパラメータ処理

 次に、各種パラメータの設定値をリクエストボディとして構築します。先に構築した会話部分のmsgPartを使用してリクエストボディの構築過程を見やすくしています。

サンプル03-08.txt
書籍情報

『生成AIをWord&Excel&PowerPoint&Outlookで自在に操る超実用VBAプログラミング術』

  • 【価格】2,530円(本体2,300円+税)
  • 【発売日】2024年2月7日(水)
  • 【ページ数】336ページ
  • 【著者】近田伸矢【監修】古川渉一
  • 【サイズ】A5判
  • 【目次】
     第1章:生成AIを操るVBAの基礎知識
     第2章:知っておきたい生成AIの基本
     第3章:VBAで会話する(ChatGPT)
     第4章:VBAで画像を生成する(DALL-E)
     第5章:VBAで自然言語処理を行う(Embeddings)
     第6章:生成AIのAPIをユーザー定義関数として使用する
     第7章:すぐ使える! PowerPointマクロと生成AIの連携レシピ
     第8章:すぐ使える! Wordマクロと生成AIの連携レシピ
     第9章:すぐ使える! Outlookマクロと生成AIの連携レシピ
     第10章:すぐ使える! Excelマクロと生成AIの連携レシピ