プログラミング

Streamlitで無料のチャットツールを実装してみた #Python #Groq

streamlit プログラミング
この記事はこんな方にオススメ

こんにちは、zawato(@zawato7)です!

今回は、Streamlitでチャットツールを実装してみたので、コードを解説したいと思います。

StreamlitでChatGPTのようなチャットツールを実装したいと考えている方は、是非参考にしてみてください。

実装結果

今回、実装したチャットツールのGUIは以下になります。

実装内容

GitHubにて、コードを公開してます。

GitHub - zawato/groq_streamlit
Contribute to zawato/groq_streamlit development by creating an account on GitHub.

環境

  • Python 3.11.7

プログラムの全体像

今回、作成したコード(app.py)は以下になります。

import os
import streamlit as st
from groq import Groq

# メインタイトル
st.title("StreamlitのAIチャットツール")

# メッセージの値を保持
if "messages" not in st.session_state:
    st.session_state["messages"] = [{"role": "assistant", "content": "何か気になることはありますか?"}]

# セッションで管理しているメッセージを全て出力
for msg in st.session_state.messages:
    st.chat_message(msg["role"]).write(msg["content"])

# サイドバー
with st.sidebar.container():
    ### サイドバータイトル
    st.title("各種設定")
    ### Groq APIキーの入力
    api_key = st.text_input('APIキー', placeholder='APIキーを入力してください')
    st.divider()
    ### モデル選択
    selected_model = st.selectbox(
        'モデル',
        ['llama3-70b-8192', 'llama-3.1-70b-versatile']
    )
    st.divider()
    ### 最大トークン数
    max_tokens = st.slider('最大トークン数', 100, 1000, 100)
    st.divider()
    ### Tempperature
    temperature = st.slider('Temperature', 0.0, 2.0, 1.0)

# ユーザーの入力が送信された際に実行される処理
if prompt := st.chat_input("Groqにメッセージを送信する"):
    client = Groq(
        api_key=api_key
    )
    st.session_state.messages.append({"role": "user", "content": prompt})
    st.chat_message("user").write(prompt)

    # システムプロンプトをセット
    system_prompt = {
        "role": "system",
        "content": "あなたは日本語で回答する便利なアシスタントです。"
    }

    # ユーザのプロンプトをセット
    user_input = prompt
    user_prompt = {
        "role": "user", "content": user_input
    }

    # チャット履歴を格納
    chat_history = [system_prompt, user_prompt]

    # 回答を格納
    response = client.chat.completions.create(model=selected_model,
                                                messages=chat_history,
                                                max_tokens=max_tokens,
                                                temperature=temperature)
    
    # メッセージを取得
    msg = response.choices[0].message
    # セッションにメッセージを追加
    st.session_state.messages.append({"role": "assistant", "content": msg.content})
    # メッセージを出力
    st.chat_message("assistant").write(msg.content)

プログラムの詳細

ここからは、プログラムの処理について詳しく紹介していきます。

今回は、Streamlitと呼ばれるPythonでWebアプリを簡単に作れるフレームワークを利用します。

また、今回は生成AIとして「Groq」を利用します。こちら、無料でLLM APIを利用することができるので採用しました。

以下の記事にて、Groqの概要とAPIの利用方法についてまとめていますので、APIキーを事前に取得しておいてください!

APIキーを取得できましたら、新規でpyファイルを作成します。

以下、コードの解説になります。

import os
import streamlit as st
from groq import Groq

まずは、必要なライブラリをインポートします。もし無い場合は、事前にインストールしてください。

# メインタイトル
st.title("StreamlitのAIチャットツール")

チャットツールの画面に表示するタイトルを設定します。タイトルは何でも良いので、お好きな文字列を設定してください。

# メッセージの値を保持
if "messages" not in st.session_state:
    st.session_state["messages"] = [{"role": "assistant", "content": "何か気になることはありますか?"}]

Streamlitでは,ブラウザのタブ単位でセッションを管理しています。そのため、入力したチャットや出力されたチャットを保持しておくために、Session Stateとして辞書形式で保存するようにします。

# セッションで管理しているメッセージを全て出力
for msg in st.session_state.messages:
    st.chat_message(msg["role"]).write(msg["content"])

Session Stateに保存されているメッセージを全て出力します。

# サイドバー
with st.sidebar.container():
    ### サイドバータイトル
    st.title("各種設定")
    ### Groq APIキーの入力
    api_key = st.text_input('APIキー', placeholder='APIキーを入力してください')
    st.divider()
    ### モデル選択
    selected_model = st.selectbox(
        'モデル',
        ['llama3-70b-8192', 'llama-3.1-70b-versatile']
    )
    st.divider()
    ### 最大トークン数
    max_tokens = st.slider('最大トークン数', 100, 1000, 100)
    st.divider()
    ### Tempperature
    temperature = st.slider('Temperature', 0.0, 2.0, 1.0)

こちらは、Web画面のサイドバーに表示する項目の設定を行っています。

サイドバーでは、以下の項目を設定するようにしています。

  • APIキー
  • 生成AIのモデル
  • 出力する最大トークン数(文字数に相当する項目)
  • Temperature(生成AI モデルの出力をコントロールするためのパラメータ。温度が高いほどランダム性の高い出力結果が得られます。)

上記のコードは、GroqのAPIとモデルを利用する想定のものですので、他の生成AIモデルやAPIを利用される方は適宜変更してください。おそらく、似たような書き方になるかと思います。

# ユーザーの入力が送信された際に実行される処理
if prompt := st.chat_input("Groqにメッセージを送信する"):
    client = Groq(
        api_key=api_key
    )
    st.session_state.messages.append({"role": "user", "content": prompt})
    st.chat_message("user").write(prompt)

    # システムプロンプトをセット
    system_prompt = {
        "role": "system",
        "content": "あなたは日本語で回答する便利なアシスタントです。"
    }

    # ユーザのプロンプトをセット
    user_input = prompt
    user_prompt = {
        "role": "user", "content": user_input
    }

    # チャット履歴を格納
    chat_history = [system_prompt, user_prompt]

    # 回答を格納
    response = client.chat.completions.create(model=selected_model,
                                                messages=chat_history,
                                                max_tokens=max_tokens,
                                                temperature=temperature)
    
    # メッセージを取得
    msg = response.choices[0].message
    # セッションにメッセージを追加
    st.session_state.messages.append({"role": "assistant", "content": msg.content})
    # メッセージを出力
    st.chat_message("assistant").write(msg.content)

こちらでは、ユーザーがテキストを送信するたびに実行される処理を記述しています。

システムプロンプトには、目的に合った回答をしてもらうために、事前に制約を設定できます。Groqはたまに英語で回答する時があるため、日本語で回答させるような文言を設定しておきます。

動作確認

コンソール上で、streamlitを実行させます。

streamlit run app.py

すると、ブラウザに新しいタブが開かれ、Web画面が表示されます。

サイドバーに、APIキーを入力し、モデル・最大トークン数・Temperatureを設定しておきます。

試しに、「Groqについて教えてください。」と送信してみた結果が以下の通りです。

それっぽい回答が得られました。

何度か使ってみた感想ですが、回答精度はそこまで高くない印象でした。たまに変な文字列が混じって出力されることもありましたので、あまり実用的ではないのかなという感想です。

ただ、無料で利用できますので、試作品を作る際には使い勝手が良いのではないかと思います。

おわりに

今回は、Streamlitでチャットツールを実装してみました。

実装してみた感想や改善点などがありましたら、是非コメントしてください!

お問い合わせは、こちら

プロフィール
zawato

データサイエンティストとして3年の実務経験あり。
情報学修士卒。Python歴6年。
このブログでは、主にプログラミングやIT技術関連、エンジニア向けにちょっとした役立つ情報を発信しています。

zawatoをフォローする!
よかったらシェアしてね!
zawatoをフォローする!

コメント

タイトルとURLをコピーしました