💬

Streamlitを使ってチャットアプリを簡単に作る

2023/07/02に公開

はじめに

Streamlitが更新され、チャットUIが追加されたため、こちらを使ったチャットデモのサンプルを作ってみたいと思います。

詳細は以下の公式ドキュメントを参照して下さい。
https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps
https://docs.streamlit.io/library/api-reference/chat

Streamlitのインストールに関しては以下を参照して下さい。
https://docs.streamlit.io/library/get-started/installation

先に結果をお見せすると次のようになります。

お試し

実装

とくに何か前置きがあるわけではないため、早速コードの記載してしまおうと思います。

import streamlit as st

st.title("Streamlitのチャットサンプル")

# 定数定義
USER_NAME = "user"
ASSISTANT_NAME = "assistant"
MORIAGE_YAKU_NAME = "moriage_yaku"

# チャットログを保存したセッション情報を初期化
if "chat_log" not in st.session_state:
    st.session_state.chat_log = []

# ユーザーのアバターを設定
avator_img_dict = {
    MORIAGE_YAKU_NAME: "🎉",
}

user_msg = st.chat_input("ここにメッセージを入力")
if user_msg:
    # 以前のチャットログを表示
    for chat in st.session_state.chat_log:
        avator = avator_img_dict.get(chat["name"], None)
        with st.chat_message(chat["name"], avatar=avator):
            st.write(chat["msg"])

    # 最新のメッセージを表示
    assistant_msg = "もう一度入力してください"
    moriage_yaku_msg = "アンコール!アンコール!"
    with st.chat_message(USER_NAME):
        st.write(user_msg)
    with st.chat_message(ASSISTANT_NAME):
        st.write(assistant_msg)
    with st.chat_message(MORIAGE_YAKU_NAME, avatar=avator_img_dict[MORIAGE_YAKU_NAME]):
        st.write(moriage_yaku_msg)

    # セッションにチャットログを追加
    st.session_state.chat_log.append({"name": USER_NAME, "msg": user_msg})
    st.session_state.chat_log.append({"name": ASSISTANT_NAME, "msg": user_msg})
    st.session_state.chat_log.append({"name": MORIAGE_YAKU_NAME, "msg": user_msg})

チャットのログはセッションに保存しており、常に表示する形としています。

チャットアイコンも簡単に指定でできるのが、非常にいいですね。
以下の"ユーザー名"に"user"と指定すると人の顔、"assistant"と指定するとロボットの顔がデフォルトで設定されているようです。
avator部分に"🎉"のように絵文字を入力すると、それがアイコンになるのもGood!

with st.chat_message("ユーザー名", avator=None):
	st.write("メッセージ")

実行

上のコードをコピペしてsample.pyファイルを作成して下さい。
その後、そちらのファイルが保存されているフォルダまで移動して、以下のコマンドで実行できるはずです。

streamlit run sample.py

実行後は以下のURLからチャット画面が確認できるかと思います。
http://localhost:8501/

結果

アンコールがだいぶうるさいですが、まあいいでしょう。
(↓の動画は最初に"こんにちは"と必ず返すコードとしていた際の結果のため、上のコードの場合は"こんにちは"は表示されません。)

アイコンに画像を設定する

上の例ではアイコンとして絵文字を設定できましたが、絵文字ではなく画像も設定できるようなのでさらに試してみました。

実装

import streamlit as st
import numpy as np
from PIL import Image

st.title("Streamlitのチャットサンプル")

# 定数定義
USER_NAME = "user"
ASSISTANT_NAME = "assistant"
MORIAGE_YAKU_NAME = "moriage_yaku"
MORIAGE_YAKU2_NAME = "moriage_yaku2"

# チャットログを保存したセッション情報を初期化
if "chat_log" not in st.session_state:
    st.session_state.chat_log = []

# ユーザーのアバターを設定
img_moriyage_yaku2 = np.array(Image.open("moriage_yaku2.jpeg"))
avator_img_dict = {
    MORIAGE_YAKU_NAME: "🎉",
    MORIAGE_YAKU2_NAME: img_moriyage_yaku2,
}

user_msg = st.chat_input("ここにメッセージを入力")
if user_msg:
    # 以前のチャットログを表示
    for chat in st.session_state.chat_log:
        avator = avator_img_dict.get(chat["name"], None)
        with st.chat_message(chat["name"], avatar=avator):
            st.write(chat["msg"])

    # 最新のメッセージを表示
    assistant_msg = "もう一度入力してください"
    moriage_yaku_msg = "アンコール!アンコール!"
    moriage_yaku2_msg = "そっれ、アンコール!アンコール!"
    with st.chat_message(USER_NAME):
        st.write(user_msg)
    with st.chat_message(ASSISTANT_NAME):
        st.write(assistant_msg)
    with st.chat_message(MORIAGE_YAKU_NAME, avatar=avator_img_dict[MORIAGE_YAKU_NAME]):
        st.write(moriage_yaku_msg)
    with st.chat_message(
        MORIAGE_YAKU2_NAME,
        avatar=avator_img_dict[MORIAGE_YAKU2_NAME],
    ):
        st.write(moriage_yaku2_msg)

    # セッションにチャットログを追加
    st.session_state.chat_log.append({"name": USER_NAME, "msg": user_msg})
    st.session_state.chat_log.append({"name": ASSISTANT_NAME, "msg": user_msg})
    st.session_state.chat_log.append({"name": MORIAGE_YAKU_NAME, "msg": user_msg})
    st.session_state.chat_log.append({"name": MORIAGE_YAKU2_NAME, "msg": user_msg})

以下のようにavator部分に画像データを入れることで簡単に挿入できますね!

# 画像読み込み
img_moriyage_yaku2 = np.array(Image.open("moriage_yaku2.jpeg"))

# チャット表示
with st.chat_message(
MORIAGE_YAKU2_NAME,
avatar=img_moriyage_yaku2,
):
	st.write(moriage_yaku2_msg)

実行

sample.pyを上の実装コードで書き換えて下さい。
また、sample.pyと同じフォルダにアイコンとして使用したい"moriage_yaku2.jpeg"という名前の画像ファイルを置いて下さい。

これで先ほど同様に以下のコマンドで実行できるはずです。

streamlit run sample.py

結果

Streamlit、便利すぎる。。。

その他

ChatGTPのようなストリーミングで表示するチャットに関しては以下を参照してください
https://zenn.dev/nishijima13/articles/3b1a50b8728261

GitHubトレンドチェック

こちらのアカウントでGitHub TrendingにあがっているリポジトリをChatGPTで要約して日々ポストしています。
これから話題になりそうな技術をいち早く知る助けになるかと思います。
気になった方はぜひフォローしてみて下さい。
https://x.com/nishijima_13v2
こんな感じで情報を日々ポストしています。

Discussion