はじめに
こんにちは、サイオステクノロジーのあさりです。生成AIアプリ開発の入門として、AIチャットbotを作成したので記事にしたいと思います。この記事では、Azure OpenAI Serviceを使用してGPT-3モデルをデプロイし、StreamlitとLangchainを使用してAIチャットbotを作成します。Azure OpenAI Serviceは、OpenAIのGPT-3などのAIモデルをクラウドで簡単に利用できるサービスです。また、StreamlitはPythonでWebアプリケーションを簡単に作成できるフレームワークで、Langchainは、OpenAIのモデルを簡単に扱うためのライブラリです。
この記事で作成するAIチャットbotの構成は下図のようになっています。
それでは、本題に入っていきましょう。
Azure OpenAI Serviceリソースの作成
Azure OpenAI Serviceを利用するには、事前にアクセス申請が必要です。申請用フォームに必要事項を入力して送信しましょう。各入力項目については、こちらの記事を参考にしてください。
Azure OpenAI Serviceのアクセス承認メールが届いたら、リソースを作成していきましょう。まず、Azure Portalにアクセスします。画面上部の検索ボックスに「openai」と入力し、「Azure OpenAI」というサービスをクリックしてください。
次に「+作成」をクリックします。
ここでは、必要な情報を入力します。サブスクリプション、リソースグループを選択(または新規作成)します。次にリージョンを選択、名前を入力し、価格レベルを選択します(価格レベルは現時点でStandard S0のみ)。すべての情報を入力したら、「次へ」をクリックします。
次にネットワークでアクセスレベルを選択します。ここでは、「インターネットを含むすべてのネットワークがこのリソースにアクセスできます。」を選択して、「次へ」をクリックします。
次に、タグを設定する必要があれば、設定をして「次へ」をクリックします。
最後にレビューおよび送信で設定した情報の確認を行います。情報が正しければ、「作成」をクリックします。リソースの作成には数分かかる場合があります。
以上がAzure OpenAI Serviceのリソース作成の手順です。次の章では、このリソースにモデルをデプロイする方法について説明します。
Azure OpenAI Serviceモデルのデプロイ
リソースの作成が完了したら、モデルをデプロイしていきましょう。さきほど作成したリソースに移動し、「モデル デプロイ」タブを開きます。「展開の管理」をクリックして、Azure OpenAI Studioに移動します。
「+新しいデプロイの作成」をクリックします。
デプロイしたいモデルとそのバージョンを選択していきましょう。モデルとバージョンについては、要件に応じてこちらを参考に決定してください。各モデルのコストについてはこちらを参考にしてください。今回はgpt-35-turboを選択します(gpt-35-turbo (0301) モデルと gpt-4 (0314) モデルは、2024 年 7 月 5 日以前に廃止予定)。デプロイ名については、任意の名前を設定してください(後ほど、APIを実行する際に使用します)。1分あたりのトークンレート制限(数千)については、1分あたりに消費できるトークン数の指定が可能です。120kの場合、1分間に120,000個のトークンを消費できます。入力できたら「作成」をクリックしてデプロイしましょう。
デプロイが完了したら次のように表示されます。
環境構築
デプロイが完了したら、環境構築をしましょう。
必要なライブラリのインストール
必要なライブラリ(streamlit, langchain, langchain-openai, python-dotenv)をpip installしましょう。langchain-openaiは、langchainでAzure OpenAIのモデルを使用するために必要となります。
pip install streamlit langchain langchain-openai python-dotenv
環境変数の設定
「.env」という名前のファイルを作成して、Azure OpenAIのAPIキーとエンドポイント、デプロイ名を設定します。APIキーとエンドポイントははじめに作成したリソースから確認できます。リソースに移動したら画面左のメニューから「キーとエンドポイント」をクリックしてください。①がAPIキー、②がエンドポイントになります。
デプロイ名については、モデルのデプロイの際に設定したものを以下のように設定してください。
# .env
AZUREOPENAI_API_ENDPOINT=https://*****.openai.azure.com/
AZUREOPENAI_API_KEY=*****
DEPLOYMENT_NAME_GPT=*****
チャットbotの実装
それでは、チャットbotを実装していきます。完成版のコードは以下のようになります。
# chatbot.py
import streamlit as st
from langchain_openai import AzureChatOpenAI
from langchain.schema import (HumanMessage, AIMessage)
import os
from dotenv import load_dotenv
load_dotenv()
def main():
llm = AzureChatOpenAI(
azure_endpoint= os.environ['AZUREOPENAI_API_ENDPOINT'],
openai_api_version="2023-03-15-preview",
deployment_name= os.environ['DEPLOYMENT_NAME_GPT'],
openai_api_key= os.environ['AZUREOPENAI_API_KEY'],
openai_api_type="azure",
)
# ページの設定
st.set_page_config(
page_title="My Great ChatGPT",
page_icon="😎"
)
st.header("My Great ChatGPT 😎")
# チャット履歴の初期化
if "messages" not in st.session_state:
st.session_state.messages = []
# ユーザーの入力を監視
if user_input := st.chat_input("聞きたいことを入力してね!"):
st.session_state.messages.append(HumanMessage(content=user_input))
with st.spinner("GPT is typing ..."):
response = llm.invoke(st.session_state.messages)
st.session_state.messages.append(AIMessage(content=response.content))
# チャット履歴の表示
messages = st.session_state.get('messages', [])
for message in messages:
if isinstance(message, AIMessage):
with st.chat_message('assistant'):
st.markdown(message.content)
elif isinstance(message, HumanMessage):
with st.chat_message('user'):
st.markdown(message.content)
else:
st.write(f"System message: {message.content}")
if __name__ == '__main__':
main()
まず、streamlitやlangchain、環境変数の読み込みに必要なライブラリをインポートします。
import streamlit as st
from langchain_openai import AzureChatOpenAI
from langchain.schema import (HumanMessage, AIMessage)
import os
from dotenv import load_dotenv
次に、「.env」ファイルに登録したAzure OpenAI Serviceに接続するための環境変数を読み込みます。
load_dotenv()
次にmain()
関数では、まずAzure OpenAI Serviceに接続するためのAzureChatOpenAI
クラスのインスタンスllm
を作成します。ここで環境変数から必要な情報を取得して、各種パラメータを指定しています。これによって、Azure OpenAIのAPIを使用することができます。
llm = AzureChatOpenAI(
azure_endpoint= os.environ['AZUREOPENAI_API_ENDPOINT'],
openai_api_version="2023-03-15-preview",
deployment_name= os.environ['DEPLOYMENT_NAME_GPT'],
openai_api_key= os.environ['AZUREOPENAI_API_KEY'],
openai_api_type="azure",
)
次は、st.set_page_config()
関数を使って、streamlitアプリケーションのページタイトルとアイコンを設定しています。page_title
にはページのタイトルを文字列で指定し、page_icon
にはページのアイコンを指定します。そして、st.header
関数を使って、ページの上部に表示する大きな見出しを設定します。
# ページの設定
st.set_page_config(
page_title="My Great ChatGPT",
page_icon="😎"
)
st.header("My Great ChatGPT 😎")
次は、チャット履歴の初期化をしています。Streamlitでは、st.session_state
でセッション状態を保持できます。このオブジェクトは辞書のように動作し、キーと値のペアを保存できます。ここでは、st.session_state
に"messages"
というキーが存在しなければ、新たに"messages"
というキーを作成し、その値として空のリストを設定しています。
# チャット履歴の初期化
if "messages" not in st.session_state:
st.session_state.messages = []
次のコードは、ユーザーからの入力を受け取り、それをAzure OpenAIのモデルに送信し、その応答を取得するためのものです。
まず、st.chat_input("聞きたいことを入力してね!")
を使用してユーザーからの入力を受け取ります。この関数は、ユーザーが何かを入力するとその値を返します。
次に、st.session_state.messages.append(HumanMessage(content=user_input))
を使用して、ユーザーからの入力をセッションのmessages
リストに追加します。ここで、HumanMessage
クラスはユーザーからのメッセージを表現するためのもので、content
にはユーザーの入力が設定されます。
その後、with st.spinner("ChatGPT is typing ..."):
ブロック内でモデルが応答を生成している間、ユーザーに対して”GPT is typing …”というメッセージを表示します。
response = llm.invoke(st.session_state.messages)
は、ユーザーからの入力をモデルに送信し、その応答を取得します。llm.invoke
メソッドは、messages
リストを引数として受け取り、モデルからの応答を返します。
最後に、st.session_state.messages.append(AIMessage(content=response.content))
を使用して、モデルからの応答をmessages
リストに追加します。ここで、AIMessage
クラスはモデルからのメッセージを表現するためのもので、content
パラメータにはモデルの応答が設定されます。
# ユーザーの入力を監視
if user_input := st.chat_input("聞きたいことを入力してね!"):
st.session_state.messages.append(HumanMessage(content=user_input))
with st.spinner("GPT is typing ..."):
response = llm.invoke(st.session_state.messages)
st.session_state.messages.append(AIMessage(content=response.content))
次のコードは、チャットの履歴を表示するためのものです。
まず、st.session_state.get('messages', [])
を使用して、セッションからmessages
リストを取得します。この関数は、指定したキーが存在する場合はその値を返し、存在しない場合はデフォルト値(ここでは空のリスト)を返します。
次に、forループを使用して、取得したmessages
リストを順に処理します。各メッセージに対して、その型をチェックし、それに応じて表示方法を変えます。
if isinstance(message, AIMessage):
ブロックでは、メッセージがモデルからの応答である場合、with st.chat_message('assistant'):
ブロック内でそのメッセージをMarkdown形式で表示します。
同様に、elif isinstance(message, HumanMessage):
ブロックでは、メッセージがユーザーからの入力である場合、with st.chat_message('user'):
ブロック内でそのメッセージを表示します。
最後に、メッセージが上記のどちらの型でもない場合、st.write(f"System message: {message.content}")
を使用して、システムメッセージとしてその内容を表示します。
# チャット履歴の表示
messages = st.session_state.get('messages', [])
for message in messages:
if isinstance(message, AIMessage):
with st.chat_message('assistant'):
st.markdown(message.content)
elif isinstance(message, HumanMessage):
with st.chat_message('user'):
st.markdown(message.content)
else:
st.write(f"System message: {message.content}")
ローカルで動作確認
最後に以下のコマンドを実行して動作確認をしましょう。
streamlit run chatbot.py
ブラウザが立ち上がり、以下のようにチャットができるようになれば成功です。
おわりに
この記事では、StreamlitとLangchainを使用してAIチャットbotを作成する方法を紹介しました。Azure OpenAI Serviceリソースの作成からモデルのデプロイ、環境構築、そして実装まで、一連のプロセスを経て、ローカル環境での動作確認まで行いました。この記事が皆さんのAIアプリケーション開発の一助となれば幸いです。
参考
- https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/create-resource?pivots=web-portal
- https://learn.microsoft.com/ja-jp/azure/ai-services/openai/quickstart?tabs=command-line%2Cpython-new&pivots=programming-language-python
- https://zenn.dev/ml_bear/books/d1f060a3f166a5
- https://qiita.com/moritalous/items/f8864d75c9855402952a