はじめに
こんにちは!Web開発絶賛勉強中の学生です!
今日はChatGPTからの応答に追加で質問できるChrome拡張機能を作ったときの話をしたいと思います!
...という記事を書いていたのですが、執筆中に「念のため、、」と思い利用規約を調べたところ、Chatgpt.comの利用規約によりスクレイピングが完全に禁止されていました。今思えば開発前に確認するべき点でした。
よって、戒め、教訓としての記事として、同じ過ちを繰り返す方を出さないために、記事を公開します。
既に執筆済みの部分は拡張機能開発のtipsになればと思い残しておきます。
また記事の内容や、公開すること自体に問題があれば、コメントにて指摘していただけると幸いです。
chatgpt.comのスクレイピングは禁止です。絶対に行わないでください。
利用規約
禁止事項 お客様は、違法行為、有害行為、又は悪用する行為のために当社の本サービスを使用してはなりません。例えば、以下の事項は禁止されます。
データ又はアウトプット(以下に定義します)を自動又はプログラムにより引き出すこと。
出来たもの
今回作成した拡張機能は、ChatGPTの応答を取得し、それを基に追加の質問を行うことができるものでした。しかし、この機能を実現するために行ったスクレイピングがOpenAIの利用規約に違反していることを知り、公開を控えることにしました。
開発中の様子を簡単にご紹介します。
また、GoogleSearchAPIを使った簡易的なRAG(Retrieval-Augmented Generation)機能も実装していました。
追加で質問??
タイトルにも書いた「追加で質問」という文言、正直分かりにくいですよね。「そんなのもう一度その質問を送信すればいいのでは?」 という声が聞こえてきます。
例えば、QiitaについてChatGPTに質問した際、出力中に自分の知らない表現や単語があったとしましょう。
「ノウハウ」という単語の意味が分からない!となった場合、追加の質問をそのままChatGPTに投げてもよいのですが、これが大筋の質問に関係のない質問である場合、その後の出力に影響を及ぼす可能性があります。次に詳しい解説を書きます。
大筋に関係ない質問の影響
1. ChatGPTの文脈理解の弊害
ChatGPTは会話の履歴も入力に含めることで、文脈を考慮した応答生成を行います。ここで、大筋の質問に関係のない質問が入力された場合、これも会話履歴の一部として入力されてしまいます。
2. Attention機構への影響
現代のLLMの基盤となったTransformerに使われるAttention機構では、単語間の関係値をAttentionスコアとして計算します。このとき計算量は、入力トークン数nに対し$O(n^2)$で増加します。また、Attentionスコアは計算の際正規化されるため、不要な質問により重要なトークンのスコアが希釈される可能性もあります。
Attention機構の部分については、最近のモデルでは改善されつつあります。
実装
ということで、ChatGPTからの最新の応答を取得し、取得した応答について追加で質問を行える拡張機能を作りました。
大筋の質問からブランチを作り、そこで追加の質問を行うイメージでした。
また、情報の信頼性を担保するためにGoogleSearchAPIを使った簡易的なRAGも追加しました。
使用技術
今回は各言語の勉強もかねて、フレームワークは使わず、素のHTML/CSS/JSを使用しました。結果的に即応性の高い拡張機能が出来上がったので勉強にはなりました。
- HTML
- CSS
- JavaScript
- OpenAI API
- Google Search API
ディレクトリ構造
ディレクトリはこんな感じです。初めての開発で、右も左もわからない状況で作ったので、アドバイスがあればぜひ教えてほしいです。
Chrome拡張機能の開発では、一番下のmanifest.jsonが肝になります。
├── popup/
│ ├── popup.html # メインのポップアップUI
│ ├── popup.css # ポップアップのスタイル
│ └── popup.js # ポップアップの機能実装
├── settings/
│ ├── settings.html # 設定画面のUI
│ ├── settings.css # 設定画面のスタイル
│ └── settings.js # 設定機能の実装
├── scripts/
│ ├── background.js # バックグラウンドスクリプト
│ └── content.js # コンテンツスクリプト
├── images/
│ ├── icon-16.png # 拡張機能アイコン(16px)
│ ├── icon-48.png # 拡張機能アイコン(48px)
│ └── icon-128.png # 拡張機能アイコン(128px)
└── manifest.json # 拡張機能のマニフェストファイル
manifest.jsonについて
Chrome拡張機能開発では、拡張機能の概要を説明する、manifest.jsonを作成します。規定のプロパティの値を変更することで、どういう機能を持つ拡張機能であるかをChrome側に伝えることができます。TypeScriptのtsconfigに近いものと思っていただければ大丈夫です。
今回は下の様になっています。各プロパティはコメントにて説明します。
{
"manifest_version": 3 //マニフェストのバージョン。現在はv3が最新
"name":"Support chat",//拡張機能の名前
"version":"1.0",//拡張機能のバージョン
"description":"ChatGPTの応答に対してフォローアップ質問を簡単に行えるChrome拡張機能です。",//拡張機能の説明
//拡張機能が使用する機能の権限
"permissions":[
"activeTab",//アクティブタブへのアクセス
"storage",//ブラウザのストレージへのアクセス
"scripting",//スクリプトの挿入
],
//拡張機能がアクセスできるURLの指定
"host_permissions":[
"https://chat.openai.com/*"
],
//ツールバーアイコンの動作
"action":{
"default_popup":"popup/popup.html",//クリック時に開くHTMLファイルのパス
"default_icon":{//アイコンの画像ファイルのパス
"16": "images/icon-16.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
},
"default_title": "Support Chat"//マウスホバー時のテキスト
},
//ショートカットキーの設定
"commands": {
"toggle-popup": {
"suggested_key": {
"default": "Ctrl+Shift+Y"
},
"description": "Toggle the support chat popup"
}
},
//スクリプトの挿入に関連する部分
"content_scripts":[
{
"matches": ["https://chatgpt.com/*"],//挿入するサイト
"js":["scripts/content.js"]//挿入するスクリプトのパス
}
],
//バックグラウンドで実行されるスクリプトのパス
"background":{
"service_worker":"scripts/background.js"
},
//拡張機能のアイコンのファイルパス
"icons":{
"16":"images/icon-16.png",
"48":"images/icon-48.png",
"128":"images/icon-128.png"
}
}
全体のシーケンス
全体のシーケンスは次のようになっています。
ChatGPT.comからの応答の取得
まとめ
今回の経験から、利用規約をしっかりと確認し、遵守することの重要性を痛感しました。開発者として、サービスの提供元や他のユーザーに迷惑をかけないよう、倫理的な開発を心がける必要があります。
スクレイピング周りの処理なんて初めに規約を確認しに行かない方がおかしかったですね、、
今後は、公式のAPIや許可された方法を利用し、正しい手段で開発を進めていきたいと思います。
皆さんもスクレイピング等、規約違反にならないよう十分ご注意ください。