1. 主要ページへ移動
  2. メニューへ移動
  3. ページ下へ移動

QES ブログ

記事公開日

【Python】StreamlitとAzure OpenAIを使ってAIチャットボットWebアプリを作成してみた!

  • このエントリーをはてなブックマークに追加

こんにちは!DXソリューション営業本部の近藤です。

私は現在、新人課題でPythonと生成AIを使った課題に取り組んでおり、その一環で「AIチャットボットのWebアプリ化」を行いました。
最初は、どうやってWebアプリを作成すれば良いか分かりませんでしたが、調べているうちにPythonにはフレームワークというものがあることを知りました。
そのフレームワークの中でも、「Streamlit」というものが比較的簡単に使うことができると知りました。

そこで今回は、Pythonのフレームワーク「Streamlit」を使って、AIチャットボットのWebアプリを作成してみました。


Streamlitとは?

Streamlitとは、Python専用のオープンソースのWebアプリケーションフレームワークです。
特徴としては、プログラミングの知識(HTML/CSS/JavaScriptなど)がなくてもPythonのコードだけでWebアプリケーションを非常に簡単に、かつ迅速に作成できる点です。
そのため、他のフレームワークよりも手軽にWebアプリを構築することができます。


開発環境

今回作成したAIチャットボットアプリの開発環境について紹介します。

  • Python(バージョン:3.13.7)
  • Azure OpenAI Service(モデル:gpt-5.0)

必要なライブラリのインストール

今回使用するライブラリのインストールをします。以下のコマンドを実行すればインストールできます。

$ pip install streamlit openai python-dotenv

ファイル構成

今回作成するAIチャットボットアプリは、以下のシンプルなファイル構成で成り立っています。開発の開始前に、プロジェクトのルートディレクトリにこれらのファイルを作成してください。

streamlit_chatbot_project/
├── .env                  # 機密情報(APIキー、エンドポイントなど)を格納
└── test.py                # Streamlitアプリのメインコード

これで開発の準備は完了です。次のステップとして、OpenAIのAPIキーを取得・設定する方法について解説していきます。


Azure OpenAI APIキーの取得と設定

AIチャットボットを動かすには、Azure OpenAIのサービスを利用するための「鍵」となるAPIキーが必要です。また、セキュリティのため、この鍵をコード内に直接書き込まず、環境変数として管理します。

.envファイルの作成とキーの記述

プロジェクトのルートディレクトリに.envファイルを作成し、そのファイルの中に、以下の形式で取得したキーを記述します。
AZUREOPENAI_API_KEY = YOUR_API_KEY
AZUREOPENAI_ENDPOINT = YOUR_ENDPOINT
AZUREOPENAI_API_VERSION = YOUR_API_VERSION
AZUREOPENAI_GPT_MODEL = YOUR_GPT_MODEL

※この.envファイルには機密情報が含まれるため、GitHubなどのバージョン管理システムに絶対にアップロードしないよう、.gitignoreファイルに追記することを忘れないでください。


Pythonコード内で環境変数を読み込む

Streamlitアプリのコード(今回はtest.py)の一番最初で、dotenvライブラリを使って環境変数を読み込みます。
# test.py の先頭に追加
import os
from dotenv import load_dotenv
from openai import AzureOpenAI # AzureOpenAIをインポート

# .envファイルを読み込む
load_dotenv()

# AzureOpenAIクライアントのインスタンスを作成
client = AzureOpenAI(
    # .envから読み込んだ環境変数を設定
    azureopenai_endpoint=os.getenv("AZUREOPENAI_ENDPOINT"),
    azureopenai_api_key=os.getenv("AZUREOPENAI_API_KEY"),
    azureopenai_api_version=os.getenv("AZUREOPENAI_API_VERSION")
)

この方法により、機密情報をコードに直接書き込むことなく、安全にAzure OpenAIを利用することができます。これで、準備は万全です。次のステップでは、いよいよStreamlitのコードを書き始め、チャットアプリを作成していきます。


アプリの基本構成

チャットボットのベースとなる画面を作成し、ローカルで実行できる状態にします。

アプリの雛形と初期設定

まず、メインファイルである test.py に、環境変数の読み込みとAzure OpenAIクライアントの初期化処理、そしてアプリのタイトルを設定します。
import os
from dotenv import load_dotenv
from openai import AzureOpenAI # AzureOpenAIをインポート
import streamlit as st
import time # AI応答のタイピング速度を調整するために使用

load_dotenv()

# AzureOpenAIクライアントのインスタンスを作成
client = AzureOpenAI(
    # .envから読み込んだ環境変数を設定
    azureopenai_endpoint=os.getenv("AZUREOPENAI_ENDPOINT"),
    azureopenai_api_key=os.getenv("AZUREOPENAI_API_KEY"),
    azureopenai_api_version=os.getenv("AZUREOPENAI_API_VERSION")
)

# ページ設定
st.title("AIアシスタントへようこそ。")

会話履歴の管理(セッションステート)

Streamlitでは、ユーザーがメッセージを送るたびにアプリ全体が再実行されるため、会話履歴を保持するためにst.session_stateを使用します。


履歴の初期化

st.session_stateに"messages"というキーがない場合(アプリが初めて起動されたとき)に、履歴リストを初期化します。リストの最初の要素として、AIの人格(システムメッセージ)を定義しておきます。

# test.py (st.titleの直後に追加)

# セッションステートにメッセージ履歴がなければ初期化する
if "messages" not in st.session_state:
    st.session_state.messages = [
        # AIの役割を定義するシステムメッセージ
        {"role": "system", "content": "あなたは親切で丁寧なAIアシスタントです。"}
    ]

履歴の表示

st.session_state.messagesに格納されている過去のメッセージをループで取り出し、st.chat_messageを使ってチャット形式で表示します。システムメッセージはユーザーには見せる必要がないため、表示対象から除外します。

# test.py (セッションステート初期化の直後に追加)

# 過去のメッセージ履歴を表示
for message in st.session_state.messages:
    # システムメッセージは表示しない
    if message["role"] != "system":
        with st.chat_message(message["role"]):
            st.markdown(message["content"])

ユーザー入力フォームの設置と一次処理

画面下部にst.chat_inputを使ってメッセージ入力フォームを設置し、ユーザーがメッセージを送信した際の最初の処理を定義します。

# test.py (履歴表示の直後に追加)

# ユーザーからの入力を受け付け、変数 user_input に格納
if user_input := st.chat_input("AIアシスタントにメッセージを入力"):
    
    # ① ユーザーメッセージを履歴に追加
    st.session_state.messages.append({"role": "user", "content": user_input})
    
    # ② ユーザーメッセージを即座にUIに表示
    with st.chat_message("user"):
        st.markdown(user_input)
    
    # この後のステップで、ここにAIからの応答処理(API呼び出し)が入ります

APIリクエストの準備(コンテキストの保持)

AIからの応答を表示するためのコンテナを用意し、APIリクエストを実行します。

# test.py (ユーザー入力フォームの設置と一次処理の直後に追加)

# AIの応答処理ブロック
with st.chat_message("assistant"):
    
    # Azure OpenAI APIへのリクエスト
    response_stream = client.chat.completions.create(
        # モデルのデプロイ名
        azureopenai_model=os.getenv("AZUREOPENAI_GPT_MODEL"), 
        messages=[
            # システムメッセージを含む全履歴を渡すことでコンテキストを保持
            {"role": m["role"], "content": m["content"]}
            for m in st.session_state.messages
        ],
        stream=True # ストリーミングを有効化
    )

ストリーミング表示

APIから返ってくるチャンクを処理し、画面にリアルタイム表示するロジックです。

# test.py (APIリクエストの準備の直後に追加)

    # ストリーミング表示ロジック
    full_response = ""
    # 応答のテキストをリアルタイムで置き換えるためのプレースホルダー
    placeholder = st.empty() 
    
    for chunk in response_stream:
        # chunkからテキストコンテンツを取得
        if chunk.choices and chunk.choices[0].delta.content:
            full_response += chunk.choices[0].delta.content
            # リアルタイムでUIを更新(末尾にカーソル "▌" を追加)
            placeholder.markdown(full_response + "▌")
            # タイピング速度調整のための短い遅延
            time.sleep(0.04)
    # ストリーミング完了後、最終的な応答でカーソルを削除
    placeholder.markdown(full_response)

AI応答の履歴への保存

AIからの回答がすべて確定した後、その内容をセッション履歴に保存し、処理を終了します。

# test.py (ストリーミング表示の直後に追加)

# AIの回答を履歴に追加
st.session_state.messages.append({"role": "assistant", "content": full_response})

これで、AIチャット機能の全てのロジックが完成しました。


完成した test.py の全体像

import os
from dotenv import load_dotenv
from openai import AzureOpenAI # AzureOpenAIをインポート
import streamlit as st
import time # AI応答のタイピング速度を調整するために使用

def main():

    load_dotenv()

    # AzureOpenAIクライアントのインスタンスを作成
    client = AzureOpenAI(
        # .envから読み込んだ環境変数を設定
        azureopenai_endpoint=os.getenv("AZUREOPENAI_ENDPOINT"),
        azureopenai_api_key=os.getenv("AZUREOPENAI_API_KEY"),
        azureopenai_api_version=os.getenv("AZUREOPENAI_API_VERSION")
    )

    # ページ設定
    st.title("AIアシスタントへようこそ。")

    # セッションステートにメッセージ履歴がなければ初期化する
    if "messages" not in st.session_state:
        st.session_state.messages = [
            # AIの役割を定義するシステムメッセージ
            {"role": "system", "content": "あなたは親切なAIアシスタントです。"}
        ]

    # 過去のメッセージ履歴を表示
    for message in st.session_state.messages:
        # システムメッセージは表示しない
        if message["role"] != "system":
            with st.chat_message(message["role"]):
                st.markdown(message["content"])

    # ユーザーからの入力を受け付け、変数 user_input に格納
    if user_input := st.chat_input("AIアシスタントにメッセージを入力"):
    
        # ① ユーザーメッセージを履歴に追加
        st.session_state.messages.append({"role": "user", "content": user_input})

        # ② ユーザーメッセージを即座にUIに表示
        with st.chat_message("user"):
            st.markdown(user_input)

        # AIの応答処理ブロック
        with st.chat_message("assistant"):
        
            # Azure OpenAI APIへのリクエスト
            response_stream = client.chat.completions.create(
                # モデルのデプロイ名
                azureopenai_model=os.getenv("AZUREOPENAI_GPT_MODEL"), 
                messages=[
                    # システムメッセージを含む全履歴を渡すことでコンテキストを保持
                    {"role": m["role"], "content": m["content"]}
                    for m in st.session_state.messages
                ],
                stream=True # ストリーミングを有効化
            )
        
            # ストリーミング表示ロジック
            full_response = ""
            # 応答のテキストをリアルタイムで置き換えるためのプレースホルダー
            placeholder = st.empty() 
        
            for chunk in response_stream:
                # chunkからテキストコンテンツを取得
                if chunk.choices and chunk.choices[0].delta.content:
                    full_response += chunk.choices[0].delta.content
                    # リアルタイムでUIを更新(末尾にカーソル "▌" を追加)
                    placeholder.markdown(full_response + "▌") 
                    # タイピング速度調整のための短い遅延
                    time.sleep(0.04)
            # ストリーミング完了後、最終的な応答でカーソルを削除
            placeholder.markdown(full_response)
        
        # AIの回答を履歴に追加
        st.session_state.messages.append({"role": "assistant", "content": full_response})

if __name__ == "__main__":
    main()

ローカルでの動作確認

ターミナルで以下のコマンドを実行し、アプリを起動します。

streamlit run test.py

 

実行すれば、以下のような画面が自動的に立ち上がります。

 

チャットボットの機能が動作するか確認するために、試しに「こんにちは」と入力してみます。

 

入力したメッセージとユーザーアイコンが表示され、それと共にAIからの回答が表示されました。

これで、AIチャットボットWebアプリを動作させることができました。


まとめ

今回、Streamlitを使ってAIチャットボットWebアプリを開発してみて、「こんなにも簡単に作成できるんだ!」というのが最初の正直な感想です。

Webアプリって、HTML、CSS、JavaScriptとか覚えることが山積みで難しいイメージでした。でも、StreamlitのおかげでPythonさえ書ければ、見た目がしっかりとしているWeb画面がすぐにできました。特に、st.session_stateで前の会話を覚えさせたり、AI の回答がタイピングみたいにリアルタイムで出てくるのを見たときは、感動しました!

AIとWebアプリを組み合わせるなんて難しいと思っていましたが、こんなにすぐに動くものが作れて本当に驚きました!

そして、このアプリはまだ始まったばかりです。今回の基本構造さえあれば、次のステップとして 様々な機能の実装やUIのカスタマイズなど、思いつくままに機能をどんどん追加できます。

皆さんもぜひ、自分のアイデアを Web アプリとしてどんどん形にしてみてください!

 

 

QUICK E-Solutionsでは、AIサービスを利用したシステム導入のお手伝いをしております。
それ以外でも様々なアプリケーションの開発・導入を行っております。提供するサービス・ソリューションにつきましては こちら に掲載しております。
システム開発・構築でお困りの問題や弊社が提供するサービス・ソリューションにご興味をお持ちいただけましたら、お気軽にお問い合わせください。

  • このエントリーをはてなブックマークに追加

お問い合わせ

Contact

ご質問やご相談、サービスに関する詳細など、何でもお気軽にご連絡ください。下記のお問い合わせフォームよりお気軽に送信ください。

お問い合わせ

資料ダウンロード

Download

当社のサービスに関する詳細情報を掲載した資料を、下記のページよりダウンロードいただけます。より深く理解していただける内容となっております。ぜひご活用ください。

資料ダウンロード