スポンサーリンク

whisperとChatGPTのAPIを組み合わせた音声ファイルの要約ツールを作った

3月1日にOpenAIが提供しているChatGPTとwhisperのそれぞれがAPIとして使えるようになりました。

whisperの方はこれまではpythonの環境を整えてpipから導入することはできましたが、今回のAPIの登場によってローカルPCのマシンパワーを使わずに使用できるようになったと言えるかなと思います(もちろん費用は掛かる)。

今回は両APIを使った音声ファイルの要約ツールを1本作ってみました。

whisperとChatGPTのAPIについて

どちらも使い方は簡単で指定のエンドポイントに対して、OpenAIの管理画面で発行可能なAPIキーをセットしたリクエストを送るだけで使えます。

↓whisper API sample
$ curl https://api.openai.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: multipart/form-data" \
  -F model="whisper-1" \
  -F file="@/path/to/file/openai.mp3"

↓chatgpt API sample
$ curl https://api.openai.com/v1/chat/completions \
 -H "Authorization: Bearer $OPENAI_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "model": "gpt-3.5-turbo",
 "messages": [{"role": "user", "content": "What is the OpenAI mission?"}] 
 }'

作ったものについて

GitHub - imo-tikuwa/whisper-chatgpt-summarize: OpenAIのwhisperとChatGPTのAPIを使用した音声ファイルの要約ツール
OpenAIのwhisperとChatGPTのAPIを使用した音声ファイルの要約ツール. Contribute to imo-tikuwa/whisper-chatgpt-summarize development by creating an account on GitHub.
  1. MP3の音声ファイルについてwhisper APIで文字起こし
  2. 文字起こし結果をChatGPT APIで要約
  3. whisperの文字起こし結果とChatGPTの要約の結果をそれぞれ出力

というシンプルな流れのプログラムになります。
環境構築にDockerが必要なことと、OpenAIのログイン後の画面で発行するAPIキーが必要です。

以下、昨日の夜に作ったindex.jsの内容全コピペ。

const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");
const program = require("commander");

// CLI引数をパース
program.option("-f, --file <path>", "Path to MP3 file");
program.option("-r, --request <text>", "ChatGPTへのリクエスト内容", "以下の文字列について要約をお願いします。");
program.parse(process.argv);

const options = program.opts();
if (!options.file) {
  console.error("Missing required argument: -f/--file");
  process.exit(1);
} else if (!options.file.toLowerCase().endsWith(".mp3")) {
  console.error("Invalid file");
  process.exit(1);
}

(async () => {
  // whisper APIのリクエスト実行
  const form = new FormData();
  form.append("model", "whisper-1");
  form.append("file", fs.createReadStream(options.file));
  try {
    const transcriptionResult = await axios
      .post("https://api.openai.com/v1/audio/transcriptions", form, {
        headers: {
          Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
          ...form.getHeaders(),
        },
      })
      .then((response) => response.data.text);

    // ChatGPT APIのリクエスト実行
    const summarizeResult = await axios
      .post(
        "https://api.openai.com/v1/chat/completions",
        {
          model: "gpt-3.5-turbo",
          messages: [
            {
              role: "user",
              content: `${options.request}「${transcriptionResult}」`,
            },
          ],
        },
        {
          headers: {
            Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
            "Content-Type": "application/json",
          },
        }
      )
      .then((response) => {
        return response.data.choices[0].message.content;
      });

    // 結果出力
    console.log("---------- whisper result ----------");
    console.log(transcriptionResult.trim());
    console.log("\n");
    console.log("---------- chatgpt result ----------");
    console.log(summarizeResult.trim());
  } catch (error) {
    console.log(error.response.data);
    process.exit(1);
  }
})();

ツールの使い方について

詳細は上記GitHubリポジトリ内のマークダウンをご確認いただければと思います。

index.jsに対してのCLIオプションとしてMP3ファイルを指定します。

$ node index.js -f [mp3ファイルの相対パス]

デフォルトではwhisperによって取得した文字列について「以下の文字列について要約をお願いします。」という内容の指示をChatGPTに渡していますが、-rオプションから別の指示を渡すことが可能です。

$ node index.js -f [mp3ファイルの相対パス] -r "箇条書きで要約してください"

動作確認してみたときのキャプチャ

20秒くらいの音声についてwhisperで文字起こし→ChatGPTで要約は5秒くらいで出来ました!
箇条書きで~という指示のときは結果として箇条書きで改行コード入りのレスポンスが取得できていること、箇条書き+英語の指示についても問題なく行えることが確認できました。

メモ

  • 今回はNode(axios)からAPIリクエストしたが、要はcurl相当のことができればよいので他の言語でも大掛かりなライブラリはインストールせずに汎用的なAPIリクエストのコードで動作確認するところまで持っていけそう。
  • whisperは正しいAPIリクエストが行えた場合、レスポンスとしてtextというプロパティのデータのみが返ってくる。
  • chatgptの方は消費したトークンの情報とかも含まれてるので、実際にサービスに組み込む場合はその辺の情報を見ながら作る必要がありそう。
    • 今回のサンプルでは1回のAPIリクエストで受け取ったレスポンスで完結するような内容ですが、https://chat.openai.com/chat のチャットサービスのようなものを作りたい場合はレスポンスに含まれるmessagesをスタックさせていく必要があるためなんだかんだで結構費用が掛かってしまいそうなイメージがある。。

参考リンク

タイトルとURLをコピーしました