はじめに
社会人 1 年目の IT 初心者が、Amazon BedrockとStreamlitを用いてチャットボットアプリを開発してみました。簡易なチャットボットアプリをAWSで開発してみたい方、Streamlitに興味のある方におすすめです。この記事を読むことで、開発の大まかな流れを理解することができます。
※詳細な手順書を記載しているわけではないので、その点はご留意ください。
※誤っている記述などございましたらお気軽にコメントお待ちしております。
※エラー解決や行き詰った点に関しては別途記事にしていく予定です。
開発環境
- Windows 11
- Python 3.12.3
- streamlit 1.39.0
- boto3 1.35.41
- langchain 0.3.3
- langchain-aws 0.2.2
- langchain-chroma 0.1.4
- langchain-community 0.3.2
- langchain-core 0.3.11
- langchain-openai 0.2.2
アーキテクチャ図
今回開発したアーキテクチャ図の全体像は以下の図の通りです。
補足:セキュリティーグループとルートテーブルの通信設定に関して
セキュリティーグループ:
-
Security Group A
インバウンドルール(タイプ/プロトコル/ポート範囲/ソース)
カスタムTCP/TCP/8501/Security Group B
HTTPS/TCP/443/Security Group C
アウトバウンドルール(タイプ/プロトコル/ポート範囲/送信先)
すべてのトラフィック/すべて/すべて/0.0.0.0/0 -
Security Group B:
インバウンドルール(タイプ/プロトコル/ポート範囲/ソース)
HTTPS/TCP/443/自宅のIPアドレス(例)
HTTPS/TCP/443/社内プロキシ(例)
アウトバウンドルール(タイプ/プロトコル/ポート範囲/送信先)
すべてのトラフィック/すべて/すべて/0.0.0.0/0 -
Security Group C:
インバウンドルール(タイプ/プロトコル/ポート範囲/ソース)
HTTPS/TCP/443/Security Group A
HTTPS/TCP/443/Security Group C
アウトバウンドルール(タイプ/プロトコル/ポート範囲/送信先)
すべてのトラフィック/すべて/すべて/0.0.0.0/0 -
Security Group D:
インバウンドルール(タイプ/プロトコル/ポート範囲/ソース)
HTTPS/TCP/443/Security Group A
アウトバウンドルール(タイプ/プロトコル/ポート範囲/送信先)
すべてのトラフィック/すべて/すべて/0.0.0.0/0
ルートテーブル:
-
ルートA
送信先/ターゲット
0.0.0.0/0 / Internet Gateway
VPC IP / VPC IP
明示的なサブネットの関連付け
Public Subnet -
ルートB
送信先/ターゲット
0.0.0.0/0 / NAT Gateway
VPC IP / VPC IP
明示的なサブネットの関連付け
Pribate Subnet
アプリ概要
チャットボットによる社内文書検索と質問応答
社内文書(ガイドラインやルールなど)をもとにしたチャットボットを開発しました。
主な機能
質問応答:ユーザーが入力した簡単な質問に対して瞬時に回答を提供し、業務効率を向上させます。
参考資料一覧提示:社内に保存されている文書から関連する情報を抽出します。抽出した資料一を参考資料一覧として提示します。
チャットボット画面(イメージ)
本記事の流れ
- 1 章:開発背景と目的
- 2 章:VPC の作成からアプリケーションのセットアップまで
- 3 章:Bedrock の設定から S3 の準備まで
- 4 章:アプリケーションの開発とブラウザからのアクセスまで
- 5 章:その他設定に関して
- 6 章:振り返り
1 章:開発背景と目的
開発背景
社員がガイドラインから必要な情報を得るまでに多くの手順が必要であり、その情報量の多さから適切な情報にたどり着くまでに困難が伴っていました。そのため、情報の検索に多くの時間と労力を費やしてしまう課題が存在していました。
開発目的
ガイドラインの利用に伴うハードルを下げ、社員が必要な情報を迅速かつ容易に得られるようにすることを目指しました。これにより、情報検索にかかる時間と労力を削減し、作業効率を向上させ、情報の理解にかかる負担軽減を目的としました。
2 章:VPC の作成から アプリケーションのセットアップまで
この章では、VPCの作成からアプリケーションのセットアップまでの手順を説明します。以下のステップに従って私は進めました。各ステップには、私が初めてAWSマネジメントコンソールを触りながら作成した際、参考にした記事のリンクも掲載しているので、必要に応じて確認してください。
※大まかな作業内容を記載しているため、詳細な説明は省略しています。ご了承ください。また、最新の情報はAWSの公式ドキュメントを読むことを強くお勧めします。
ステップ1:VPCとSubnetの構築
VPCと3つのSubnetを構築しました。- 参考①
ステップ2:EC2インスタンスの作成
VPC内にEC2インスタンスを作成しました。- 参考②
ステップ3:Internet Gatewayの設置
VPC内にInternet Gatewayを設置し、Public SubnetとPrivate Subnetに分ける設定を行いました。(Internet GatewayとつながっているSubnetがPublic Subnet)- 参考②
ステップ4:NAT Gatewayの設置
2つのSubnetに、それぞれ1つずつNAT Gatewayを設置しました。- 参考②
ステップ5:ルートテーブル作成とルーティング設定
Internet GatewayとNAT Gatewayを使うために、Subnetのルートテーブルを変更する必要があるため行いました。- 参考②
ステップ6:Route 53で新規ドメインのリクエスト
Route 53で新規パブリックドメインの申請・取得のリクエストを行いました。- 参考③
ステップ7:サブドメインの登録とパブリック証明書の発行
サブドメインをRoute 53に登録し、証明書をリクエストしました。- 参考④
メモ:AWS Certificate Manager(ACM)で証明書をリクエストしたがステータスが「保留中の検証」から変化しない場合の対応:登録済みドメインと同じ名前のホストゾーンに登録したいレコード名とNSを追加することで解決しました。
ステップ8:ALB用のセキュリティグループ、ターゲットグループの作成
Application Load Balancer(ALB)用のセキュリティグループを作成しました。- 参考⑤
メモ:セキュリティーグループは、インターネットからALBへの通信。言い換えると、AWS外部からのインバウンド通信に該当します。ターゲットグループは、ALBからEC2への通信。言い換えると。AWS内部で完結する通信に該当します。
ステップ9:ALB作成
Application Load Balancer (ALB)を作成しました。- 参考⑤
ステップ10:ターゲットグループにターゲットを追加
ターゲットグループにターゲットを追加しました。- 参考⑤
ステップ11:EC2へのSession Managerを使ったアクセス
Private Subnetに配置されたEC2インスタンスに対して、Session Managerを使って接続しました。- 参考⑥, ⑦
ステップ12:アプリケーションのセットアップ
Python、StreamlitのインストールとStreamlitの起動を行いました。
参考記事でPythonインストール後に、以下のコマンドを実行しました。- 参考⑧
pip install streamlit
streamlit hello
メモ:次回以降は、以下のコマンドを入力すれば、EC2インスタンスでのStreamlitの起動と停止が行える。(1行ずつ実行)
sudo su - ec2-user
nohup streamlit hello &
ps -ef | grep streamlit
kill -9 確認したPID
最後に...
上記参考記事以外で、以下の記事がわかりやすくまとまっているので共有しておきます。- 参考⑨
ここまで完了した際のアーキテクチャ図:
参考記事とリンク
参考①:
参考②:
参考③:
参考④:
参考⑤:
参考⑥:
参考⑦:
参考⑧:
参考⑨:
3 章:Bedrock の設定から S3 の準備まで
この章では、Bedrock の設定から S3 の準備までの手順を説明します。以下のステップに従って私は進めました。参考にした記事とリンクも掲載しているので、必要に応じて確認してください。
※大まかな作業内容を記載しているため、詳細な説明は省略しています。ご了承ください。また、最新の情報はAWSの公式ドキュメントを読むことを強くお勧めします。
ステップ1:Bedrockの設定
Bedrockサービスの有効化をおこないました。- 参考⑩
補足:今回はanthropicのclaude-3-haikuのモデルを使用しました。
(modelId = 'anthropic.claude-3-haiku-20240307-v1:0')
ステップ2:Kendraの設定
Amazon Kendraのインデックスを作成しました。- 参考⑪
ステップ3:S3の設定
S3バケットの作成と検索対象データの準備を行いました。- 参考⑫
ステップ4:ローカルからEC2内への接続~sshセッション接続(主にファイル転送用)
社内PCからSession Managerを用いたEC2への接続の設定およびsshセッション接続を行いました。- 参考⑬, ⑭
補足①:aws-cliのインストール
社内のPCから接続する場合は、AWSのコマンドラインツールaws-cliが必要なため、インストールしました。また、別途session-manager-pluginが必要なので、こちらもインストールしました。- 参考⑬
補足②:アクセスキーの払い出し
アクセスキーとシークレット・アクセスキーを取得は以下の記事が参考になりました。- 参考⑮
メモ:うまくいかない時は、以下の記事が有用でした。- 参考⑯, ⑰
まとめ:この章では、Bedrock, Kendra, S3の設定とローカルからのSession Managerを用いたEC2接続の設定を行いました。また、ローカルからのssh接続によるファイル転送が可能となりました。
最後に...
上記参考記事以外で、以下の記事がわかりやすくまとまっているので共有しておきます。- 参考⑱
ここまで完了した際のアーキテクチャ図:
参考記事とリンク
参考⑩:
参考⑪:
参考⑫:
参考⑬:
参考⑭:
参考⑮:
参考⑯:
参考⑰:
参考⑱:
4 章:アプリケーションの開発とブラウザからのアクセスまで
この章では、アプリケーションの開発とブラウザからのアクセスまでの手順を説明します。以下のステップに従って私は進めました。参考にした記事とリンクも掲載しているので、必要に応じて確認してください。
※大まかな作業内容を記載しているため、詳細な説明は省略しています。ご了承ください。また、最新の情報はAWSの公式ドキュメントを読むことを強くお勧めします。
ステップ1:アプリケーション開発
以下の記事を参考にアプリを実装しました。
主に、StreamlitとLangchainを用いることでコードを実装しました。(後日、記事にする予定)
具体的なコードに関しては、今回の記事では割愛させていただきますが、基本的にこれらの参考資料をベースに完成させることができるはずです。- 参考⑲, ⑳, ㉑, ㉒, ㉓
メモ:うまくいかない時は、以下の記事が有用でした。- 参考㉔, ㉕
ステップ2:作成したPythonファイルをEC2内に転送
PythonファイルをローカルマシンからEC2インスタンスに転送しました。(方法は3章ステップ4を参照)
ステップ3:ブラウザからのアプリのアクセス
インターネット経由でドメイン名を使ってアクセスできるようコマンドを入力し、EC2内でアプリを立ち上げました。その後、ブラウザからのアプリを検索しアクセスできることを確認しました。(方法は2章ステップ12を参照)
メモ:ローカルマシンで開発したアプリをEC2内に転送し、立ち上げからkillするまでのコマンドまとめ(Windows PowerShellを使用)
# Session Manager経由でEC2に接続を自動化
# 下記コマンドを打つと、token-codeを求められるので、Authenticatorで認証する
$json = (aws sts get-session-token --serial-number arn:aws:iam::<自身の値を入力>:mfa/Authenticator --token-code "$(Read-Host token-code)" --no-verify | ConvertFrom-Json); aws configure set aws_access_key_id $json.Credentials.AccessKeyId --profile mfa; aws configure set aws_secret_access_key $json.Credentials.SecretAccessKey --profile mfa; aws configure set aws_session_token $json.Credentials.SessionToken --profile mfa
# Session Manager経由でEC2接続する
aws ssm start-session --target i-<インスタンスID> --profile mfa --no-verify
# sh-5.2$に切り替わるのを確認後exitする
sh-5.2$exitで抜ける。
#ローカルからファイルを転送する
scp -i "C:\Users\<自分の名前>\.ssh\chatbot-ec2-key.pem" <自分の作成したアプリのパス> ec2-user@i-<インスタンスID>:~/
#EC2内にSSH接続で入る
ssh -i C:\Users\<自分の名前>\.ssh\chatbot-ec2-key.pem ec2-user@i-<インスタンスID>
#転送したファイルがあるか確認
ls
#アプリの立ち上げ(環境変数の永続化)
nohup streamlit run /home/ec2-user/<アプリ名.py> &
#killしたい番号を表示させる
ps -ef | grep streamlit
#killする
kill -9 確認したPID
ここまで完了した際のアーキテクチャ図:
参考⑲:
参考⑳:
参考㉑:
参考㉒:
参考㉓:
参考㉔:
参考㉕:
5 章:その他設定に関して
ステップ1:EC2の自動起動・停止
EventBridgeを用いて、EC2インスタンスの停止と起動の設定を行いました。- 参考㉖
ステップ2:アプリ立ち上げの自動化
EC2起動時にアプリが自動で呼び出されるよう設定しました。- 参考㉗, ㉘
ステップ3:Cognitoの設定とALBとCognito連携
Cognitoを用いて認証や認可の設定を行いました。その後、ALBのホスト名をブラウザーで開いたときに認証画面を出すよう設定しました。- 参考㉙, ㉚
ステップ4:CloudWatchでのアプリケーション監視
CloudWatchを用いて、ログを収集するよう設定しました。- 参考㉛, ㉜
メモ:うまくいかない時は、以下の記事が有用でした。- 参考㉝
ステップ5:SNSトピックとサブスクリプションの作成とCloud watchとの連携
CloudWatchアラームとSNSを用いて、自分のメール宛に通知出す設定をしました。- 参考㉞
ここまで完了した際のアーキテクチャ図:
参考㉖:
参考㉗:
参考㉘:
参考㉙:
参考㉚:
参考㉛:
参考㉜:
参考㉝:
参考㉞:
6 章:振り返り
AWSのサービスを触ることが初めての初心者が、様々な試行錯誤をしながら社内向けのチャットボットを開発することができました。決して自分1人の力でできたわけではないですが、この開発経験を通じてAWSやStreamlitに関する知見をたくさん増やすことができました。
この経験を活かして、AWS SAA試験を受験したところ1発合格をすることができました!今度、試験対策の記事も執筆しようと思います。
最後に、チャットボット開発を進めるにあたり多くの助言と指導を行ってくださった先輩社員のHさんにここで感謝申し上げます。ありがとうございました!!