こんにちは、JS2IIUです。
Streamlitは、Pythonでインタラクティブなウェブアプリケーションを簡単に作成できるフレームワークです。データサイエンスや機械学習の分野で人気ですが、Chat elementsとst.session_stateを活用することで、ChatGPTのような本格的なチャットアプリも開発できます。
この記事では、st.chat_message()、st.chat_input()、そしてst.session_stateを使い、さらには生成AIのChatGPTも活用し、チャットアプリを構築する方法をステップバイステップで解説します。今回もよろしくお願いします。
Chat elementsの紹介
st.chat_message()
st.chat_message() は、チャットのメッセージを表示する関数です。
- シグネチャ:
st.chat_message(name, *, avatar=None) name:メッセージの送信者名。avatar:送信者のアバター画像のURL。
サンプルプログラム:
import streamlit as st
# ユーザーからのメッセージ
with st.chat_message("user", avatar="https://www.gravatar.com/avatar/HASH"):
st.write('Hello, this is JS2IIU.🖐️')
# アシスタントからのメッセージ
with st.chat_message("assistant"):
st.write('Hi, how are you?')
st.chat_input()
st.chat_input() は、チャットの入力欄を表示する関数です。
- シグネチャ:
st.chat_input(placeholder="Your message", *, key=None, max_chars=None, disabled=False, on_submit=None, args=None, kwargs=None) placeholder:入力欄に表示するプレースホルダーテキスト。key:ウィジェットの識別子。max_chars:入力可能な最大文字数。disabled:入力欄を無効にするかどうか。on_submit:送信ボタンがクリックされたときに実行するコールバック関数。
サンプルプログラム:
import streamlit as st
user_input = st.chat_input("Enter your message here...")
if user_input:
st.write(f"You said: {user_input}")
st.session_stateの説明
st.session_stateは、Streamlitアプリケーション内で変数の値をセッション全体にわたって保持するための仕組みです。これにより、ユーザーの入力やアプリケーションの状態を維持することができます。
st.session_stateは辞書のように扱えます。- 初期値を設定しない場合、キーに対応する値は存在しません。
- セッションがアクティブな間は、
st.session_stateに保存された値は保持されます。
サンプルプログラム:
import streamlit as st
if "count" not in st.session_state:
st.session_state.count = 0
st.button("Increment", on_click=lambda: st.session_state.update({"count": st.session_state.count + 1}))
st.write(st.session_state.count)このプログラムでは、ボタンをクリックするたびにst.session_state.countの値が1ずつ増加し、その値が表示されます。
サンプルプログラム
以下のサンプルプログラムは、StreamlitでChatGPT風のチャットアプリを実現するものです。
import streamlit as st
# セッションステートを初期化
if "messages" not in st.session_state:
st.session_state.messages = []
# メッセージ履歴を表示
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# ユーザーからの入力を受け取る
if prompt := st.chat_input("What is up?"):
# ユーザーのメッセージを履歴に追加
st.session_state.messages.append({"role": "user", "content": prompt})
# チャットメッセージとして表示
with st.chat_message("user"):
st.markdown(prompt)
# AIからの応答を生成 (ここでは例としてユーザーの入力をそのまま返す)
response = f"Echo: {prompt}"
# AIのメッセージを履歴に追加
st.session_state.messages.append({"role": "assistant", "content": response})
# チャットメッセージとして表示
with st.chat_message("assistant"):
st.markdown(response)サンプルプログラムの解説
- セッションステートの初期化:
st.session_stateを使用して、チャットのメッセージ履歴をmessagesというキーで保存します。 - メッセージ履歴の表示:
st.session_state.messagesに保存されたメッセージをループ処理し、st.chat_message()を使用して表示します。 - ユーザーからの入力を受け取る:
st.chat_input()を使用してユーザーからの入力を受け取ります。 - ユーザーのメッセージを履歴に追加: ユーザーが入力したメッセージを
st.session_state.messagesに追加します。 - AIからの応答を生成: ここでは例として、ユーザーの入力をそのまま返すシンプルな処理をしています。実際のアプリケーションでは、OpenAI APIなどを利用してAIの応答を生成します。
- AIのメッセージを履歴に追加: 生成されたAIの応答を
st.session_state.messagesに追加します。
ChatGPTの実装
上のサンプルでは、AIからの返事が返ってくるところを省略していました。OpenAIのAPIを使ってgpt-4oと会話できるようにしていきます。
OpenAIへの登録、API Keyの取得
コードを実行するにはOpenAIのAPI KEYが必要です。入手するためにはOpenAIに登録して、KEYを生成するところまでいくつかステップがあります。詳しく解説している良記事がたくさんあります。いくつか挙げておきますので、これらを参照して、API KEYを取得して下さい。APIの使用に対しては従量制で費用が発生しますのでご注意ください。
- 【初心者向け】ChatGPTのAPI Keyの取得手順|4つのステップで紹介 – AI総研|AIの企画・開発・運用を一気通貫で支援
- OpenAI API Key の取得方法 | 登録時の注意事項も解説 | Hakky Handbook
openaiのインストール
PythonからOpenAIのAPIを使うためのパッケージをインストールします。
pip install openaiインストールが成功するとこのような表示が出ます。
Successfully installed distro-1.9.0 httpcore-1.0.7 httpx-0.28.1 jiter-0.8.2 openai-1.59.3 tqdm-4.67.1サンプルコード
サンプルコードを示します。
5行目のapikey=のところにはOpenAIで入手したAPI KEYを入れて下さい。実際のキーはsk-から始まる長い文字列です。以下のようにAPI KEYがダブルクォーテーションで囲まれた形にして下さい。
api_key="sk-proj-abcdefg-******"OpenAIの生成AIモデルはgpt-4o-miniを使っています。用途とコストのバランスで色々と選べます。この記事は2025年1月時点のものです。今後次々と新しい、より良いモデルが出てくると思いますので、こちらのページを見てどのようなモデルが使えるかを確認してみて下さい。Models – OpenAI API
import streamlit as st
from openai import OpenAI
# OpenAIクライアントを生成
client = OpenAI(api_key="YOUR API KEY HERE") # ここにあなたのAPIキーを入力してください
# セッションステートを初期化
if "messages" not in st.session_state:
st.session_state.messages = []
# メッセージ履歴を表示
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# ユーザーからの入力を受け取る
if prompt := st.chat_input("What is up?"):
# ユーザーのメッセージを履歴に追加
st.session_state.messages.append({"role": "user", "content": prompt})
# チャットメッセージとして表示
with st.chat_message("user"):
st.markdown(prompt)
# OpenAI APIを使ってAIからの応答を生成
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
*st.session_state.messages,
]
)
response_content = response.choices[0].message.content
# AIのメッセージを履歴に追加
st.session_state.messages.append({"role": "assistant", "content": response_content})
# チャットメッセージとして表示
with st.chat_message("assistant"):
st.markdown(response_content)動作確認の様子
実際に動作させてみた様子を動画でみていきます。最初は英語で問いかけてみました。
日本語でも同様に動作しています。
サンプルコードの解説
ステップバイステップで解説していきましょう。
1. 必要なライブラリをインポート
import streamlit as st
from openai import OpenAIstreamlit: ユーザーインターフェースを構築するためのライブラリです。openai: OpenAIのAPIにアクセスするためのライブラリです。
2. OpenAIクライアントを生成
client = OpenAI(api_key="YOUR API KEY HERE") # ここにあなたのAPIキーを入力してくださいOpenAI(api_key="YOUR API KEY HERE")でOpenAIのAPIにアクセスするためのクライアントオブジェクトを生成します。YOUR API KEY HEREの部分を、ご自身のOpenAI APIキーに置き換えてください。
3. セッションステートを初期化
if "messages" not in st.session_state:
st.session_state.messages = []st.session_stateは、Streamlitが提供するセッション状態管理機能です。- このコードでは、
messagesというキーでチャットのメッセージ履歴をリストとして保存します。 if "messages" not in st.session_state:で、セッション状態にmessagesが存在しない場合(つまり、アプリが初めて起動された場合)に、空のリスト[]をst.session_state.messagesに代入して初期化しています。
4. メッセージ履歴を表示
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])st.session_state.messagesに保存されているメッセージ履歴をforループで一つずつ取り出します。- 各メッセージについて、
st.chat_message(message["role"])を使ってチャットメッセージを表示します。message["role"]は、メッセージの送信者が “user” か “assistant” かを示します。
st.markdown(message["content"])で、メッセージの内容をMarkdown形式で表示します。
5. ユーザーからの入力を受け取る
if prompt := st.chat_input("What is up?"):
# ユーザーのメッセージを履歴に追加
# ...st.chat_input("What is up?")で、”What is up?” というプレースホルダーテキストを持つチャット入力欄を表示します。- ユーザーが入力して送信ボタンを押すと、入力されたテキストが
promptに代入されます。 if prompt := ...は、promptに値が入力された場合にのみ、以降の処理を実行することを意味します。
6. ユーザーのメッセージを履歴に追加
st.session_state.messages.append({"role": "user", "content": prompt})- ユーザーが入力した
promptを、{"role": "user", "content": prompt}という辞書形式でst.session_state.messagesに追加します。 - これにより、メッセージ履歴にユーザーの入力が保存されます。
7. ユーザーのメッセージを表示
with st.chat_message("user"):
st.markdown(prompt)st.chat_message("user")を使って、ユーザーのメッセージをチャット画面に表示します。
8. OpenAI APIを使ってAIからの応答を生成
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
*st.session_state.messages,
]
)
response_content = response.choices[0].message.contentclient.chat.completions.create(...)で、OpenAIのAPIを呼び出してAIからの応答を生成します。model="gpt-4o-mini": 使用する言語モデルをGPT-4o-miniに指定します。messages=[...]: AIに渡すメッセージのリストを指定します。{"role": "system", "content": "You are a helpful assistant."}は、AIの役割を「役に立つアシスタント」として設定します。*st.session_state.messagesで、これまでのメッセージ履歴をすべてAIに渡します。これにより、AIは過去の会話の流れを踏まえて応答を生成できます。
response.choices[0].message.contentで、APIのレスポンスからAIが生成したテキストを取り出します。
9. AIのメッセージを履歴に追加
st.session_state.messages.append({"role": "assistant", "content": response_content})- AIが生成した
response_contentを、{"role": "assistant", "content": response_content}という辞書形式でst.session_state.messagesに追加します。
10. AIのメッセージを表示
with st.chat_message("assistant"):
st.markdown(response_content)st.chat_message("assistant")を使って、AIのメッセージをチャット画面に表示します。
これで、ユーザーが入力したメッセージに対して、GPT-4が応答を生成し、チャット形式で表示されるアプリケーションが完成します。
さらに改良したい方
ChatGPTのWEBサイトのように、パラパラと徐々に文字が表示されて、あたかも喋っているかのように見せるUIが特徴的ですよね。今回のサンプルは生成AIの回答がばっと一気に表示されました。パラパラと表示させるにはストリーミングという方法を使います。そのやり方についてはこちらの記事を参照して下さい。
参考
- Streamlit公式ドキュメント – Chat elements
- Streamlit公式ドキュメント – st.session_state
- Streamlit公式チュートリアル – Build a ChatGPT-like app
最後に、書籍のPRです。
最新のOpenAIのチャットAPIの使い方もしっかりと解説されている良書です。2024年11月初版発行、「LangChainとLangGraphによるRAG・AIエージェント[実践]入門」西見、吉田、大嶋著。
最後まで読んでいただきありがとうございました。73



コメント