🤖

GPT-3.5を使ってPEST分析できるアプリを作った話

2023/05/23に公開

はじめに

GPT-3.5を使って、PEST分析ができるアプリを作りました。

https://twitter.com/yui_active/status/1660488153143160835

アプリの紹介

https://analyzeme.vercel.app/

UIとしてシンプルにしたかったので、業界名を入力してボタンを押したらすぐにPEST分析が始まるようにしています。

分析が完了したら右上のボタンからPDFまたはCSVでデータのダウンロードが可能です。

技術スタック

使用技術はいつものNext.jsTypeScriptChakraUI、そしてコアとなるOpenAIのAPIです。ホスティングはVercelで行っています。

ただし今回は初の試みとしてNext.js13系から追加されたappディレクトリを利用して開発しています。

OpenAIから理想の返却値を得るために工夫したこと

今回、一番難しかったのはOpenAIから理想の返却値を得るということです。最終的に以下のように、条件を設定したら割とうまくいくということがわかりました。

    messages: [
      { role: "system", content: ${ここにOpenAIの役割を入れる。例えばあなたは〇〇の専門家です。など} },
      {
        role: "user",
        content: `〇〇を次の指示に基づいて実施します。1.${条件1} 2.${条件2} 3.${条件3}`,
      },
    ],

例えば、OpenAIあるあるで、「わかりました。以下に結果を示します。」など返事をしてしまって割と鬱陶しいと思うのですが、そういうのは余計な文字や返事は出力しない。というような条件である程度制御できました。

また、決まった形式で返却してほしい場合、各要素は次の形式で示す: ${ここに理想な形式を入れる}というような条件を入れればある程度工夫できるとわかりました。

他にもいろんな工夫方法はあると思いますが、よければ上記形式を参考に出力させてみてください。
それでもどうしても返却値が思い通りでない場合があるので、私はそれに加えて返却値を正規表現を用いて整形しなおしたりしています。

Streaming通信を利用して徐々に回答を得られるようにする

Vercelの無料プランだと5分でタイムアウトが来てしまうため、Streaming通信を利用する必要がありました。
そこで、この部分は以下の記事を参考に書きました。

https://levelup.gitconnected.com/how-to-stream-real-time-openai-api-responses-next-js-13-2-gpt-3-5-turbo-and-edge-functions-378fea4dadbd

一つだけ記事と異なるところがあるとすればconfigでのexportだと現在非推奨でビルドエラーになるため、公式サイトを参考に書き換えたぐらいです。

// src/app/api/gpt/route.ts
export const config = {
  runtime: "edge",
};

上記部分を以下に。

// src/app/api/gpt/route.ts
export const runtime = "edge";

あとは上述の記事そのままで動きました。

レートリミットの追加

OpenAIのAPIは万が一間違えて叩かれ過ぎてしまったりするとかなり高額になってしまうため、一応レートリミットを入れました。
今回はlru-cacheを利用しています。

こちらに関しては以下の記事でで詳しく書いてますのでよければご参考ください。

https://zenn.dev/yui/articles/4ab2249cb39c4e

ReactコンポーネントをPDFでダウンロードする

PDF化に関してはKimura KazukiさんのReact Component を PDFファイル に変換する方法を参考に行いました。

私が追加したところは、PDF化する際に画面幅いっぱいまで広げるのと、向きをポートレートに限定するというスタイリング部分です。

    html2canvas(target, { scale: 2.5 }).then((canvas) => {
      const imgData = canvas.toDataURL("image/png", 1.0);
      let pdf = new jsPDF("p", "mm", "a4"); // ポートレート向き、A4サイズのPDFを生成
      const imgProps = pdf.getImageProperties(imgData);
      const pdfWidth = pdf.internal.pageSize.getWidth();
      const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
      pdf = new jsPDF("p", "mm", [pdfWidth, pdfHeight]); // ポートレート向き
      pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight);
      pdf.save(`${theme}.pdf`);
    });

配列形式のJSONをCSVでダウンロードする

夫がデータをCSVでダウンロードできたらいいかもと言ってきたので追加した機能です。
こちらに関しては以下の記事でで詳しく書いてますのでよければご参考ください。
https://zenn.dev/yui/articles/32b02c23e70dbc

最後に

一般向けというよりはニッチな分野でのアプリになりましたが、今回OpenAIから理想の返却値を得るにあたって色々と工夫したりできて作りながら結構勉強になりました。もしこのアプリを使って分析してみたいというような企業さんがいましたら、ぜひ利用していただけると幸いです。

この記事が少しでも参考になればいいねを押してもらえれば励みになります!
最後まで読んでいただきありがとうございました。

Discussion