StreamlitでチャットUIと簡易ダッシュボードを作ってみる

こんにちは、エキサイトでエンジニアをしております、吉川です。 エキサイトHDアドベントカレンダー2025の14日目の記事になります。

qiita.com

Streamlitとは

Streamlitは、Pythonでデータサイエンスや機械学習のWebアプリケーションを素早く構築できるオープンソースフレームワークです。HTMLやCSSJavaScriptを書くことなく、Pythonのコードだけでインタラクティブなダッシュボードやデータ可視化ツールを作成できます。

特徴として以下が挙げられます。

  • シンプルな記法: st.write()st.button()など、直感的なAPIで簡単にUIコンポーネントを配置できる
  • 自動リロード: コードを変更すると即座にブラウザに反映される開発体験
  • 豊富なコンポーネント: グラフ、テーブル、チャットなど、データアプリに必要な機能が揃っている

今回は、Streamlitを使ってチャットUIとグラフUIを実装してみながら、その使い勝手と適用場面について考えてみます。

実際に使ってみる

事前準備(インストール)

以下でインストールします。

pip install "streamlit>=1.27" pandas numpy

チャットUIの実装

Streamlitではst.chat_messagest.chat_inputを使うことで、簡単にチャットUIを構築できます。

import streamlit as st

st.title("チャットアプリ")

# チャット履歴を保持
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.write(message["content"])

# ユーザー入力
if prompt := st.chat_input("メッセージを入力"):
    # ユーザーメッセージを追加
    st.session_state.messages.append({"role": "user", "content": prompt})
    with st.chat_message("user"):
        st.write(prompt)
    
    # アシスタントの返答(ここでは単純なエコー)
    response = f"あなたは「{prompt}」と言いました"
    st.session_state.messages.append({"role": "assistant", "content": response})
    with st.chat_message("assistant"):
        st.write(response)

このコードをapp.pyとして保存し、以下のコマンドで実行できます。

streamlit run app.py

たったこれだけで、ChatGPTのようなチャットインターフェースが完成します。セッション管理もst.session_stateで簡単に実装でき、LLMと連携すれば本格的なチャットボットもすぐに作れます。

グラフUIの実装

データ可視化も非常にシンプルです。Streamlitは主要なグラフライブラリをサポートしています。

import streamlit as st
import pandas as pd
import numpy as np

st.title("データ可視化ダッシュボード")

# サンプルデータ生成
np.random.seed(0)
chart_data = pd.DataFrame(
    np.random.randn(20, 3),
    columns=['A', 'B', 'C']
)

# 折れ線グラフ
st.line_chart(chart_data)

# インタラクティブな要素
selected_column = st.selectbox("表示する列を選択", ['A', 'B', 'C'])
st.area_chart(chart_data[[selected_column]])

Streamlitを立ち上げたまま(再起動してもOK)、app.pyファイルの中身をこのコードに変えると、複数のグラフとインタラクティブな選択UIを持ったダッシュボードが表示されます(ファイル変更時は基本的に自動で再読み込みされます)。

Streamlitの魅力

ここまで見てきたように、Streamlitの最大の魅力は圧倒的な開発速度です。数十行のPythonコードで、綺麗なUIが即座に立ち上がります。プロトタイプを素早く作成したい場合や、データサイエンティストがフロントエンドの知識なしでツールを作りたい場合に非常に有効です。

向いているケース、向いていないケース

Streamlitの制約

開発速度が速いStreamlitですが、万能ではありません。いくつかの制約があります。

1. 認証・認可の機能が弱い

Streamlit自体には本格的な認証機能がありません。Streamlit Cloudの認証機能やサードパーティライブラリを使う方法はありますが、細かい権限制御や複雑な認証フローには対応しづらいです。

2. デザインのカスタマイズ性が低い

用意されたコンポーネントの範囲内でしかUIを構築できず、独自のデザインシステムを適用したり、細かいレイアウト調整をするのは困難です。CSSでのカスタマイズも可能ですが、本格的に行うと結局手間がかかります。

3. コードが複雑化しやすい

Streamlitは上から順に実行されるため、状態管理やイベント処理が複雑になると可読性が低下します。st.session_stateでの状態管理は便利ですが、アプリが大きくなるとコードの見通しが悪くなりがちです。

4. パフォーマンスの限界

ユーザーの操作ごとにスクリプト全体が再実行される仕組みのため、大規模なデータ処理や複雑な計算を含む場合、レスポンスが遅くなることがあります。

向いているケース

以下のような場面ではStreamlitが非常に有効です:

  • 社内向けダッシュボード: デザインよりも機能性が重視され、認証も基本的なもので済む場合
  • データ分析のプロトタイプ: 仮説検証や実験的なツールを素早く作りたい場合
  • デモアプリケーション: 機械学習モデルやアルゴリズムの動作を視覚的に見せたい場合
  • 個人プロジェクト: 小規模で開発リソースが限られている場合

これらのケースでは、Streamlitの「速く作れる」という利点が欠点を大きく上回ります。

向いていないケース

一方、以下のような場面では別の技術選定を検討すべきです:

  • 外部ユーザー向けプロダクト: デザインやUXの品質が重要な場合
  • 複雑な権限管理が必要: 組織やロールに応じた細かいアクセス制御が必要な場合
  • 高度なインタラクション: 複雑なUI/UXやリアルタイム性が求められる場合
  • 長期運用が前提: コードベースが大きくなることが予想される場合

こうした要件がある場合は、最初からReactやVue.jsなどのフロントエンドフレームワークと、FastAPIやDjangoなどのバックエンドフレームワークを組み合わせた構成にする方が、長期的には開発効率が高くなるでしょう。

まとめ

Streamlitは、Pythonだけで素早くデータアプリケーションを構築できる強力なツールです。ただしUIを数十行のコードで実現できる代わりに、認証機能(特に細かな認可)を自前で用意しづらい、デザインの自由度が低い、状態管理が複雑になるとコードが見通しづらい、といった制約があることも事実です。個人的には最初は簡単に作れても、要件が増えるにつれて技術的な限界に直面しやすいと感じています。

重要なのは、「Streamlitでも十分なのか」を冷静に判断することです。社内ツールやプロトタイプなど、スピード重視で機能面にフォーカスできる場面では最適な選択肢となります。一方で、外部公開するプロダクトや長期運用が前提のシステムでは、初期の開発速度よりも拡張性や保守性を優先し、従来のフロントエンド・バックエンド分離構成を選ぶ方が賢明でしょう。

適材適所でStreamlitを活用し、開発効率を最大化していきましょう。