2023/03/14に更新

【GASでAI】chatGPTにまとめて質問する

APIスプレッドシート

chatGPTのAPIを使用し、スプレッドシートに書き込んだ質問にまとめて答えてもらうGoogle Apps Scriptです。消費したトークンも同時に記録します。

こんな悩みを解決します


  • chatGPTを検証・活用したいが、質問と回答を記録するのが面倒。
  • 日本語で問い合わせるとトークンの消費が激しいので、英語に変換してから質問したい。

用意するもの


特にありません。今お使いのスプレッドシートに組み込めます。

このスクリプトで出来ること


  • スプレッドシートに書き込んだ質問一覧を、まとめてchatGPTに投げる事ができます。
  • 2つのモードを用意しています。1つは質問文をそのままchatGPTに投げる標準モード、もう1つは質問文を英語に変換してからchatGPTに送信するトークン節約モードです。

使い方


1.事前準備

スクリプトの「事前設定エリア」を編集します。
必須で変更が必要なのは「api_key」だけで、他の値はそのままでも大丈夫です。
APIキーはopenAIのサイトですぐに発行できます。

次は質問文を用意します。
A列に質問を書いてGASを実行すると、B列に回答が書き込まれます。
C列以降には消費したトークン量が書き込まれます。
無駄な問い合わせをしないように、B列に文字が書き込まれている行はスキップします。

2.スクリプトの実行

さっそく実行してみましょう。まずは質問の日本語をそのまま送信する標準モードから。
上のメニューにある「スクリプト実行」から「すべての質問をchatGPTに答えてもらう(標準)」を実行します。

3.結果の確認

回答と消費トークンが書き込まれました。
回答が返ってきた順に1行ずつ反映されるようにしていますが、それなりに時間がかかります。

では、次は英訳してから送信するトークン節約モードを試してみます。
上のメニューにある「スクリプト実行」から「すべての質問をchatGPTに答えてもらう(トークン節約)」を実行します。

トークンの消費量は確かに減っているようです。
ですが、日本語がなんか不自然だったり堅いですね・・・細かいニュアンスを伝えるためには英訳せずに送信したほうがいいかもしれません。

スクリプト


/**
 * このスクリプトの説明、使い方はこちら。
 * https://myfunc.jp/items/00159/index.html
 */

function onOpen() {
  // スプレッドシートを開いたときに実行される関数

  // UIの取得
  const ui = SpreadsheetApp.getUi()

  // メニューの表示名
  const menu = ui.createMenu('スクリプト実行');

  // メニューに追加するボタン
  menu.addItem('すべての質問をchatGPTに答えてもらう(標準)', 'get_chatgpt_answers_normal');
  menu.addItem('すべての質問をchatGPTに答えてもらう(トークン節約)', 'get_chatgpt_answers_saving_token');

  // メニューを画面に追加する
  menu.addToUi();
}

// 標準モード(入力したテキストをそのままAPIに送信する)の呼び出し関数
function get_chatgpt_answers_normal() {
  get_chatgpt_answers('standard');
}

// 節約モード(入力したテキストを英語に変換してから送信し、トークンの節約を図る)の呼び出し関数
function get_chatgpt_answers_saving_token() {
  get_chatgpt_answers('save');
}

// メイン関数
function get_chatgpt_answers(mode) {

  // 開いているスプレッドシートオブジェクトを取得
  const ss = SpreadsheetApp.getActiveSpreadsheet();

  // 開いているシートオブジェクトを取得
  const sheet = ss.getActiveSheet();

  // 質問を取得するため、シートの使われている部分の値を取得。
  const values = sheet.getDataRange().getValues();

  // 1行ずつループ
  for (let i = 1; i < values.length; i++) {

    // B列に値が入っている = すでに回答が書き込まれている行はスキップする
    if (values[i][1]) {
      continue;

    } else {

      // chatGPTの回答をしまっておく変数を定義
      let answer;


      if (mode == 'standard') { // 標準モードの場合

        // 質問はそのままchatGPTに投げる
        answer = chatgpt_api_req(values[i][0]);

      } else if (mode == 'save') { // 節約モードの場合

        // LanguageAppを利用し、日本語から英語に変換した上でchatGPTに質問する
        answer = chatgpt_api_req(LanguageApp.translate(values[i][0], 'ja', 'en'));

        // 英語で質問すると回答も英語で返ってくるため、英語から日本語に変換する
        answer[0] = LanguageApp.translate(answer[0], 'en', 'ja');
      }

      // 回答および消費トークンを記録するため、rangeオブジェクトを取得
      let range = sheet.getRange(i + 1, 2, 1, answer.length);

      // 範囲に答えを書き込む
      range.setValues([answer]);

      // 書き込んだ答えを1行ずつ反映させたいため、flushする
      SpreadsheetApp.flush();
    }
  }
}

// chatGPT APIへの問い合わせを実行するための関数
function chatgpt_api_req(question) {

  // ########## 事前設定エリア ここから ##########

  // 必要なパラメータをセットする
  const api_key = 'XXXXXXXXXXXXXXXXXXXXX'; // 発行したAPIキー
  const model = 'gpt-3.5-turbo'; // モデルの指定
  const temperature = 0.5; // 回答の多様性を指定(0から1の間) 大きいほどバリエーションが増えるらしい。
  const max_token = 1024; // 回答に使用されるトークンの最大値。大きいと消費が激しくなる。最大は4096。

  // ########## 事前設定エリア ここまで ##########

  // APIリクエスト先のURL
  const url = 'https://api.openai.com/v1/chat/completions';

  // ChatGPTに投げる役割とメッセージを定義。質問文(question)は関数の引数で受け取る。
  // roleは「誰が発言しているかの設定」質問するならuserでOKらしい。
  const msg = [{ 'role': 'user', 'content': question }];

  // リクエストヘッダを作成
  const headers = {
    'Authorization': 'Bearer ' + api_key,
    'Content-type': 'application/json'
  };

  // payload部分をJSONで作成
  const payload = JSON.stringify({
    'model': model,
    'max_tokens': max_token,
    'temperature': temperature,
    'messages': msg
  });

  // オプションの設定
  const options = {
    'method': 'POST',
    'headers': headers,
    'payload': payload
  };

  // APIにリクエストを送信し、回答をもらう
  let response = UrlFetchApp.fetch(url, options).getContentText();

  // JSON形式なのでパースする
  response = JSON.parse(response);

  // 関数の戻り値を格納するための配列を用意
  const result = [];

  // 必要な値を取得し戻り値に追加していく

  // chatGPTの回答。なぜか先頭に改行が含まれるので消している
  result.push(response.choices[0].message.content.replace(/^\n+/, ''));

  // 消費したトークン量(質問)
  result.push(response.usage.prompt_tokens);

  // 消費したトークン量(回答)
  result.push(response.usage.completion_tokens);

  // 消費したトークン量(合計)
  result.push(response.usage.total_tokens);

  // 呼び出し元にAIの回答等を返す
  return result;
}

関連するアプリ


タグ一覧

最新のアプリ

人気のアプリ

ページトップに戻る
myfunc.jp