[初心者向け]スプレッドシート + GAS で ChatGPT API を使ってみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、annotationのあのふじたです。

ChatGPTのAPIを試す機会がなかったため スプレッドシート + GAS を使用してやり取りしてみました。

スプレッドシートにはすでにアドオンで ChatGPT 関数 が用意されており、簡単に利用できますが
やり取りした履歴も保存しておきたいのでGASを利用して履歴シートに保存するようにします。
尚、本記事内容は安全性を保証するものではないため、利用する際はご自身で十分検証の上、よろしくお願いいたします。

完成イメージは以下の通りです。

入出力シートのセル 'A1' に質問内容を記述し、送信ボタンを押すと、セル 'B1' に結果が返ってきます。

概要

  1. ChatGPT の APIキー 取得
  2. スプレッドシート上で 入出力シート, 履歴シート と 送信ボタンを作成
  3. Google App Script で ChatGPT APIとやりとりするコードを記述

1. ChatGPT の APIキー 取得

まずは OpenAI のアカウントを作成します。
アカウント作成後、API Keys 管理画面から APIキー を発行します。
Create new secret key を押してください

Popupしてきた APIキー の Copy ボタンを押しコピーして自分だけがアクセスできるような場所で管理してください。

2. スプレッドシート上で 入出力シート, 履歴シート と 送信ボタンを作成

入力と結果が返ってくる入出力シートと履歴保存用の履歴シートを作成します。

送信ボタンの図形を作ります。入出力シート選択後に図形描画を選んで...

図形描画エディタの上部のメニューから図形を選び角丸四角形を選びます。

今回はChatGPTに送信と記述して完成とします。
完成したら保存と終了を押します。

確認しやすいように入力シートの 'A1' と 'B1' を大きくしたりボタンの配置を変更しました。

3. Google App Script で ChatGPT APIとやりとりするコードを記述

Googleスプレッドシートの拡張機能からApps Scriptを選びます。

左側の歯車アイコンからプロジェクトの設定を表示し、一番下にあるスクリプトプロパティを追加からAPIKEYとしてAPIキーを保存します。

保存後に左側の<>アイコンからエディタに戻り、最初から記載されている myFunction を削除し以下のScriptを貼ります。

function chatGptRequest() {
  // OpenAIのAPIキーを取得
  const apiKey = ScriptProperties.getProperty('APIKEY');
  // OpenAIのエンドポイント
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  // System パラメータ
  const systemPrompt = '一人称は某でお願いします'
  // 入出力シート
  const sheetPrompt = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('入出力シート');
  // 履歴シート
  const sheetHistory = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('履歴シート'); 
  // 履歴取得回数
  // token数の制限に引っかかるのであまり多くしないこと
  const historyNum = 2 
 
  // 送信メッセージを定義
  let messages = [{'role': 'system', 'content': systemPrompt},];
 
  // 履歴シートから過去のやり取りを取得
  let history = sheetHistory.getRange(1,1,2,historyNum).getValues();

  // 過去の履歴を送信メッセージに追加する
  for (let i in history.reverse()){
    // 過去の履歴が空欄ではない場合は追加する
    if (history[i][0] && history[i][1]){
      // ユーザの質問
      messages.push({'role': 'user', 'content': history[i][0]});
      // ChatGPTのAPIレスポンス
      messages.push({'role': 'assistant', 'content': history[i][1]});
    }
  }

  // 入出力シートからの入力情報を取得
  let promptCell = sheetPrompt.getRange("A1");
  let prompt = promptCell.getValue();

  // 質問内容を追加
  messages.push({'role': 'user', 'content': prompt});

  // パラメータ設定
  const requestBody = {
    'model': 'gpt-3.5-turbo',
    'temperature': 0.7,
    'max_tokens': 2048,
    'messages': messages
  }
 
  // 送信内容を設定
  const request = {
    method: "POST",
    muteHttpExceptions : true,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + apiKey,
    },
    payload: JSON.stringify(requestBody),
  }

  // 回答先のセルを指定
  responseCell = sheetPrompt.getRange("B1");
  try {
    //OpenAIのChatGPTにAPIリクエストを送り、結果を変数に格納
    const response = JSON.parse(UrlFetchApp.fetch(apiUrl, request).getContentText());
    // ChatGPTのAPIレスポンスをセルに記載
    if (response.choices) {
      responseCell.setValue(response.choices[0].message.content);
      // 履歴シートの先頭に行を追加する
      sheetHistory.insertRowsBefore(1,1);
      // 今回のプロンプトの結果を履歴シートにコピー
      sheetPrompt.getRange(1,1,1,2).copyTo(sheetHistory.getRange(1,1,1,2));
    } else {
      // レスポンスが正常に返ってこなかった場合の処理
      console.log(response);
      responseCell.setValue(response);
    }
  } catch(e) {
    // 例外エラー処理
    console.log(e);
    responseCell.setValue(e);
  }
}

apiKeyは自身で取得したAPIキーに書き換えてください。
以下の部分は任意のシステムプロンプトに書き換え可能です。

 const systemPrompt = '一人称は某でお願いします'

複数行で定義したい場合はバッククォートで囲います。

 const systemPrompt = `
あなたは「某」です。以下の制約を厳密に守って会話してください。

# 制約条件

* 名前を聞かれたら、某には名前はありませんと答えて下さい。
* 某はユーザーにフレンドリーに接します。
`

システムプロンプトの役割については参考にした記事から抜粋した説明を記載します。

https://dev.classmethod.jp/articles/generated-kanji-quiz-using-chatgpt/

systemパラメータについて初心者にもわかるように説明してください。
ChatGPTのChatCompletion APIで使う system パラメータは、対話においてシステム側の発話を表すテキストを指定するためのパラメータです。
このパラメータは、対話システムの開発者が、システムが発話するテキストを制御するために使用されます。 例えば、システムがある情報を提供する際に、事前に決められたテキストを返すように指定することができます。 system パラメータに指定されるテキストは、対話システムが自動生成するテキストではなく、開発者が手動で指定することが一般的です。 指定されたテキストは、対話の流れに合わせて自動的にシステムからユーザーへの発話として使用されます。

送信ボタンを押すと実行できるようにスクリプトを割り当てします。
図形を右クリックすると三点リーダー(縦) が表示されるのでクリックしスクリプトの割り当てを選びます。

先ほど作成したchatGptRequestを記述し確定します。

あとは入出力シートの'A1'に質問内容を記述後に実行すると'B1'に回答が表示されるのですが
初回実行時に権限の許可が必要なので許可をして下さい。

実行に成功すると'B1'に回答が表示されます。

履歴シートにも転記されていますね。

駆け足でしたが、以上です。

終わりに

外部からシート記述後にChatGPTに送信し、その返答を行うような処理を書けば、Botも簡単に作成できます。
今回は書きませんが、上記のGASとDiscord.jsを利用して、簡単にDiscordのBotも作成できました。
尚、トークンやモデル等のパラメーターを変更する際はOpenAI公式Webサイトをご確認ください。

この記事が誰かの参考になれば幸いです。

参考

[ChatGPT] AIで子どもの漢字ドリルを作ってみた
ChatGPTのAPIをGoogle Apps Script(GAS)で試してみた