一般公開用インフラ 実践編2「Slack Bot&ChatGPTで月額費用削減(aws+nginx+php-fpm)」
まえがき
諸注意
本ナレッジの内容はざっくりとした方向性やプログラム設計に関する知識・ノウハウを記載したものとなっております。
そのため、Slack BotとChatGPTを連携するアプリ開発のための手順書ではない点にご注意ください。
外部リンクを記載しており、リンク切れやリンク先の情報が不適切であることもあります。
すべての内容を鵜呑みにせず、ご自身で理解された上で実践される際の参考にされて頂けたら幸いです。
本ナレッジは、2024/07/12に執筆した時点での情報となっております。
本ナレッジの概要
概要としてChatGPTの費用を抑えつつSlack BotとAWS Lightsailを使ってみようという趣旨の元、記載しております。
用語について
ざっくりと記載していますがわからないことはご自身で調べつつ、より詳しくノウハウ等を知りたい時は契約されているメンティーへ相談しましょう。
- Slack:特定のメンバーのみで会話が行えるコミュニケーションツールです(テキスト及びボイスチャット)
- Slack Bot:Slackのアプリ内に追加できるロボット機能。
- ChatGPT:入力されたテキスト内容を理解し、内容に応じた回答テキストを生成するAIです。
画像や音声などのAI機能もありますが主にChatGPTというとチャット機能を指していることが多いようです。 - GPT4o(GPT3.5~など):ChatGPTのモデルのタイプです。モデルタイプに応じて学習したデータ量やシステムが異なるためより最もらしい返答をえるには最新のモデルの利用が推奨されるが、利用制限があったり高価である。
- プロンプト:ChatGPTへ私要求データの塊です。システム・ユーザー・アシスタントなどのカテゴリーがある。
- アシスタント (ChatGPT):ChatGPTの質問の回答を行う役割を持ったプロンプト
- ユーザー (ChatGPT):ChatGPTの質問を行う役割を持ったプロンプト
- システム(ChatGPT):アシスタントに特別な役割やルールを持たせるためのプロンプト
- AWS:Amazon Web Serviceの略称。クラウド上の仮想コンピューター・仮想ネットワークなどの提供を行うサービス。
+AWS Lightsail:AWS上で少ない工数で仮想コンピューターを起動させて利用するためのサービス。
LightSailは料金体系が明確なので意図せず使いすぎる心配をある程度、減らすことができる。
完成品「Slack Bot+ChatGPT(CocoAI)」の品質について
今回はモデルとしてGPT4oを使っていますが言葉を省略すればするほど返答は意図していない(私としては)ものになったりします。
少ない言葉から正しい言葉を選ぶのって人間ですら難しい(解釈の仕方は人それぞれ、考え方や前後関係の記憶や個性もある)のでこんなものかな?という印象です。
MENTAのURLに関しては最初から正解でしたが、URLを文章内に埋め込むとURLが崩れるので途中で1行に分けるように指示を出しました。
ChatGPTのマークダウン形式にされるとSlackでおかしくなるのでマークダウン・マークアップは禁止にしています。
この辺りはもっとうまいやり方がありそうですが追々考えることとします。
GPT4o miniに切り替えてみました
動作確認も兼ねた専用共有チャンネルを作ってPythonのGUIライブラリについて聞いてみました。
ライセンス周りの最終判断はちゃんと各ライブラリのページを確認しないと危険ですが・・・
オープンソース採用時の概要情報が気軽に得られるのは便利ですね。
目的:Slack Bot&ChatGPTで月額費用削減とは?
一般的に、何かしらの不満点や改善したいことがあるから、ツール・アプリ・機能を作ろうというのが自然な流れです。
そのため、まずはSlack Bot&ChatGPTで月額費用削減を行おうと考えたきっかけをお伝えします。
ChatGPTを個々に契約すると固定費用が必要
一人で個人的に利用するのみであればさほど気にする必要はないところですが・・・
今後の拡張を踏まえた時に固定費用や利用制限といったものは後々問題になりかねないです。
- 個人でGPT4oなど最新機能を利用するにはPlusプランで毎月$20の費用が掛かる
- 新機能に関しては時間に対する利用制限がある
- 私自身はひと月にそこまで利用しない
- 複数人でChatGPTを少しだけ利用したいという場合に手立てがない
拡張性:チームや企業で利用する場合を想定
今回、Slack BotにChatGPT(API)を搭載したいと考えた理由がいくつかあります。
- 月額契約メンターさんにSlack上でSlack Botを提供したい
- プロンプトにシステムを用いた設定付けやキャラ付けを半固定で行いたい
- ChatGPTのAPIは学習データとして収集されないことになっている
(セキュリティ的な安心材料:100%安全だとは思えないが) - 独自実装を追加していくことでChatGPTをより目的に沿った高度なAIにできる
画像や音声から文字起こししたり、画像生成・自動翻訳などの機能をSlack Botに集約が行える
また独自のDBを用いることで企業データとの照合によりより特化型AIにもできる
ちなみに法人契約というものがあるがどういった機能やセキュリティ対策があるかは問い合わせてみるしかなさそうです。
https://exawizards.com/column/article/chatgpt/corporate-contracts/
その他の理由
- AWSのLightsailで本番稼働
月額$5~のお安いサーバーが固定で契約できるので性能等の検証をしてみたい(90日間は無料のようですし) - 独自フレームワークの長期動作テスト
独自に開発しているPHP用フレームワークの本番環境動作を想定した運用をしてみたい
目的のまとめ
まとめますと、多人数で利用しても固定月額を抑えてより便利に、今後の拡張も見据えたAIを使えるようにしたいからが目的です。
AWS Lightsail+Slack Bot+ChatGPI(OpenAI API)で運用をしつつ、独自フレームワークの超小規模サーバー運用の実績も得られるのも大きなポイントです。
Slack Bot&ChatGPT連携の大まかな実装の流れ
ざっくりと私が初期バージョンの「Slack Bot&ChatGPT連携」を実現するまでに行った実装の流れを紹介します。
Slack Botの名前はMENTAで契約を頂くメンターさんから不評にならない程度の設定として”CocoAI”と名付けました。
開発環境・ネットワーク構成について(要求仕様・要件・基本設計)
ツール・アプリ作成を行う上での環境決めの情報収集は重要な要素です。
予算等を考えた上で、環境構築を行っていきます。
環境に関して、Slack BotとChatGPTの組み合わせで検索するとAWS/GCPのサーバーレス構成が多いです。
サーバーレス/マイクロサービス/コンテナ化が多いこのご時世ですが・・・
同じ構成を同じように作っても味気ないのでほとんどの人がやっていない方法で実装しました。
コンテナ化していないのはdockerやcontainerにメモリを使いたくないためとなります。
($5のLightsailのPCは400MBしかないので)
ざっくりと説明しますと以下の通りです。
開発環境
- Windows Subsystem for Linux(WSL)を用いたAmazonLinux2023(Linux)環境を構築
- Linux上にdockerを構築し、nginxとphp-fpmを個々のコンテナとして展開
- WSLに合わせやすいVSCodeでコーディング&デバッグ
開発環境では、他にも開発しているプロジェクトがあるので競合を避けるためにコンテナ化しています。
本番環境
- 開発環境にQA環境として開発環境とは別のパラメータを持ったフォルダを作成
別フォルダを用意しているのは、ドメイン・セキュリティ・APIテスト方式が異なるため - AWS Lightsailの最少額構成のAmazonLinux2023をOSのみで立ち上げ
開発環境のDockerFileに合わせてnginx/php-fpmをインストール - SSL証明書を配置しnginxをSSLに対応して外部へ公開
- Slack APIへ登録、Slack Bot作成・権限設定を行い、Workspaceへインストール、OAuth Tokenを取得
- OpenAI APIへ登録、API Keyを取得
APIの実行権限を得るため$10分のデポジットの入金を行う
※安全が確認できるまでは自動課金は無効です(API実行の無限ループなどして多額請求されないように)
サーバーアプリの構成について
今回の要件として選択しているサーバーアプリの構成について採用理由の補足説明を致します。
私が開発している独自フレームワークを採用したウェブシステムがあります。
こちらは、nginx+php-fpm+MariaDB+Redisの構成でDockerファイルがそのまま使えるから採用しています。
PHPに関しては目的にも書いている通り、独自フレームワークのテストが目的でもあります。
本番環境でコンテナ化しない理由は上述の通り(メモリ削減)です。
上記の点よりAWSは使いますが、LambdaやDynamoDBといったサーバーレス化はしません。
また、費用面でもサーバーレス化は厳しいと考えます。
特にLambda・DynamoDBは利用状況に応じて料金が発生するためコントロールがやや難しいです。
なお、OpenAI APIは事前のデポジットによる制限や完全なる上限も設定できるのでLightsailの$5サーバーと組み合わせても費用を固定化しやすいです。
Slack Bot&ChatGPTの他の実装手法について
AWSを利用したサーバーレスの構成
LambdaとDynamoDBの組み合わせ、DBを使っているパターンです。
https://dev.classmethod.jp/articles/slack-chat-gpt-bot/
GCPを利用したサーバーレスの構成
Google Apps Script(GAS)で実現しているようです。
https://zenn.dev/lclco/articles/712d482d07e18c
Slackアプリと各サーバーの連携フローについて(要求仕様・要件・基本設計)
初期実装はシンプルな連携フローとしました。
ChatGPTの要素としてシステムを追加したプロンプトを用いることで役割やルールに沿った文章の生成を実施します。
Slackのアプリ上でCocoAIをメンションしてスレッドを追加
CocoAI(Slack Bot)に対してメンションしてスレッドを追加することで各処理が発動します。
Slack APIのEvent Subscriptionの機能を使うことで指定したURLへSlackのスレッドへ投稿された情報がnginxサーバーへ通知されます。
nginxサーバーのPHPにてSlack APIから受け取ったチャンネルとタイムスタンプを基に返答先スレッドを特定します。
PHPの処理内でSlack APIから投稿され受け取ったテキストを基にシステムプロンプトやユーザーの質問文などのデータを構築してOpenAI APIサーバーへリクエストします。
OpenAI APIサーバーから返信を受け取ったら、アシスタントが生成した文字列をSlackのスレッドへ返信する形で投稿します。
追加質問時は履歴を参照
Slackのスレッド内へ追加で質問を投稿した場合は5往復程度を想定し、ある程度の履歴データを含めた形でChatGPTのAPIを呼び出すようにしている。
履歴を含めることで過去質問から次の質問の内容から推測させて回答を得ることができるので、短い文章でも質問者の意図に沿った回答を得やすくしています。
大まかなクラス構成図(基本設計)
大まかなファイル構成
ざっくりとしたファイル構成は以下のようにしました。
Custom Engine/Custom Frameworkの部分はLaravelやCakePHPなどに置き換えて考えてください。
- index.php
これはクラスではなく最初にnginxから呼ばれて実行されるエントリーファイル - Custom Engineクラス群
リクエスト・レスポンス処理と全体のフロー管理がCustom Engineクラス群の役割+PHPの低レベルAPIを使いやすくしたクラス群 - Custom Frameworkクラス群
アクセスURLに応じたルーティング、リクエスト内容のチェック、後続処理とのつなぎ合わせ部分のフレームワーク化を行うクラス群 - mainクラス
正しいURLであればmainのクラスが生成されてリクエストに応答 - slackEventAnalyzerクラスとslackChatクラスによるSlack関連の実装処理
slackEventAnalyzerはリクエストデータの解析のみでslackChatがスレッドデータをSlackAPIで取得したりスレッドへ書き込み等を行うクラス - chatGPT_ChatクラスによるChatGPTのチャット関連の実装処理
プロンプトのデータを作成してOpenAIのAPIを実行するクラス
今後、機能拡張の際はchatGPT_ImageやchatGPT_Audioといった画像・音声系のクラスも作っていく予定です。
MySQLかMariaDBあたりを導入してChatGPTへの追加データの付与や履歴データを保持したりなども行う予定です。
(なお、DB関連はCustom Engine/Custom Frameworkに搭載済み)
Linuxサーバーのリソース使用状況
今回は高頻度アクセスを想定していないサーバーなので省スペックです。(2 Cpus/500MB RAM)
nginxとphp-fpmも省スペックPCに合わせてさばけるリクエストを抑えることでメモリ使用量は50MB程度に抑えてあります。
SwapメモリはCPU負荷につながりやすいのでなしでも良い気と思いますが、メモリサイズとアクセス数を考慮して一旦は様子見です。
実装テスト時のOpenAIコスト
初期のAPI実行テスト段階ではGPT3.5 Turboを利用しました。
その後、ある程度の動作が安定した時点で、GPT4oに切り替えています。
あとがき
MENTAのナレッジ投稿は1年ぶりくらいですが、そこそこのボリュームの記事になったのではと思います。
方針決めくらいの役には立つかと思いますし、Slack APIやOpenAI APIとのやりとりやデータの流れといった部分は参考になるかと思います。
アプリ実装の学習としては有用だと思いますので興味のある方はぜひ挑戦して頂けたらと思います。
実装時の諸注意&ノウハウとして、Slack Event Subscriptionに3秒ルールがあり、3秒以内に応答しないとリトライリクエストを飛ばしてきます。
これのおかげで、Slack Botが複数回書き込みされてしまったのであたふたしました。
連続してボットの投稿をしないようにとかファイルの排他制御を使ってロックするとかSlack Event Subscriptionにはすぐにレスポンスを返してリトライさせないとか試行錯誤しました。
結局、うまくいったのはファイルによるロックとボットの連続投稿禁止ですね。
質問を受け付けたタイミング(Event Subscription)で"ちょっと待ってにゃ~"と先に投稿してレスポンスコードも出力させました。
この辺りの細かなノウハウに関してはざっくりとしか記載はしないので気になる方はメンターさんに聞いてみてはいかがでしょうか。
どういった対策を行うか、どんな手法にも大小はあれどメリット・デメリットはあるものなのでメンターさんの趣向が反映される部分ではないかなと思います。