【Azure OpenAI Service】Streamlit×LangChainでAIアプリ開発に入門してみた

【6/19開催】Kong Community Japan Meetup #4
本イベントでは、Kong Inc. のVP of ProductであるReza Shafii氏もプレゼンターとして参加。当社からはアーキテクト マネージャーの槌野の登壇が決定!参加無料です!!

【6/21開催】開発者目線でのSBOMとの向き合い方
SBOMの導入から開発者がSBOMの作成・管理を自動で行っていくための方法(デモ)を紹介します。

【7/5開催】azd+Terraform? ~ポイントを押えてAzure上へのアプリケーション環境をラクチン構築~
ツールの概要説明から、実際の開発におけるポイントをお伝えします!

【7/19開催】現場で役立つAzure神小技10+α 〜生成AI,RAG,コスト削減など旬な技術満載のLT大会〜
Azureの最新技術や実用的な小技を紹介する特別なライトニングトーク大会を開催します!

【7/26開催】最適なIaCツールを選ぼう
プロジェクトでのツール選びに困らないための重要な観点をご説明します!

はじめに

こんにちは、サイオステクノロジーのあさりです。生成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アプリケーション開発の一助となれば幸いです。

参考

アバター画像
About あさり 7 Articles
サイオステクノロジー2023年新卒入社の新米エンジニアです。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる