はじめに:なぜStreamlitとGeminiなのか?
背景: 初心者でも簡単にAIチャットを作ってみたい!
ということで、今回、PythonライブラリのStreamlitとGoogle Geminiに目を付けました。
Gemini APIの魅力: 強力なLLM(大規模言語モデル)を自分のアプリに簡単に組み込める。
Streamlitの魅力: HTML/CSS/JavaScript不要。Pythonの知識だけでWeb UIが作れる。
1. 開発環境のセットアップと基礎(Pythonと隔離)
まず、依存関係の衝突を防ぐために仮想環境を作成する。
・仮想環境(venv)の作成と有効化
$ python -m venv venv
$ source venv/bin/activate # (venv)が表示されることを確認
・ライブラリのインストール
Web UI作成用の streamlit と、GoogleのAIサービスを利用するための google-genai SDKを導入する。
$ pip install streamlit
$ pip install google-genai
・APIキーの設定
export GEMINI_API_KEY="..." を使用。セキュリティのため、APIキーをコードに直接書き込まず、環境変数としてシェルに設定する。~/.bashrc に設定しておくと便利。
APIキーはGoogle AI Studioから無料で取得できます。
export GEMINI_API_KEY="YOUR_API_KEY"
2. Streamlitの基本構造と動作原理
app.py の作成と実行
StreamlitアプリのエントリーポイントとなるPythonスクリプトを作成し、
$ streamlit runでWebサーバーとして起動する。
なんとこのコマンド、コードを保存するたびに、サーバーを再起動することなく、ブラウザのアプリが自動で更新され、素早く変更を確認することができます。
UIコンポーネントの配置
st.title(), st.chat_input(), st.chat_message() などのStreamlit関数を呼び出すだけで、ユーザーインターフェースが自動的にレンダリングされる。
スクリプトの再実行
Streamlitは、ユーザーがボタンを押したり、テキストを入力したりするたびに、app.py 全体を上から下まで再実行するというユニークなモデルで動く。
3. 実装とエラー対策
3-1. 【重要】クライアントの初期化とキャッシュ
Streamlitの再実行問題(リクエスト失敗エラー)を回避するため、genai.Client() の初期化を @st.cache_resource で保護します。
import streamlit as st
import os
from google import genai
# @st.cache_resource を使って、クライアントのインスタンスをキャッシュ
@st.cache_resource
def get_gemini_client():
if not os.getenv("GEMINI_API_KEY"):
st.error("GEMINI_API_KEY 環境変数が設定されていません。")
return None
return genai.Client()
client = get_gemini_client()
# クライアントがなければ処理を停止
if not client:
st.stop()
3-2. 履歴保持の仕組みとセッション初期化
st.session_state を使って、会話履歴とチャットセッション(Geminiの履歴管理機能)を保持します。
st.title("Streamlit + Gemini 履歴保持チャット 💬")
# チャットセッションを初期化
if "chat_session" not in st.session_state:
st.session_state.chat_session = client.chats.create(model="gemini-2.5-flash")
# Streamlit表示用のメッセージ履歴を初期化
if "messages" not in st.session_state:
st.session_state.messages = [
{"role": "model", "parts": "私はGeminiモデルです。何でも質問してください!"}
]
3-3. メインのチャットロジック
ユーザー入力を受け付け、履歴を表示し、chat_session.send_message() で応答を生成する中心部分です。
# 過去の会話履歴を表示
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["parts"])
# ユーザー入力の受付
prompt = st.chat_input("メッセージを入力")
if prompt:
# ユーザー入力を履歴に追加
st.session_state.messages.append({"role": "user", "parts": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Geminiからの応答を生成
with st.chat_message("model"):
with st.spinner("Geminiが思考中..."):
# chat_session.send_message() を使用
# エラーハンドリングは省略しています
response = st.session_state.chat_session.send_message(prompt)
# 応答を画面に表示
st.markdown(response.text)
# Geminiの応答をStreamlitの表示用履歴に追加
st.session_state.messages.append({"role": "model", "parts": response.text})
3-4. ソースコード
import streamlit as st
import os
from google import genai
# クライアント初期化とエラー対策
GEMINI_API_KEY_NAME = "GEMINI_API_KEY"
# APIクライアントをキャッシュ
@st.cache_resource
def get_gemini_client():
"""Gemini APIクライアントを初期化。APIキーがなければ停止。"""
if not os.getenv(GEMINI_API_KEY_NAME):
st.error(f"エラー: {GEMINI_API_KEY_NAME} 環境変数が設定されていません。")
st.stop()
return genai.Client()
client = get_gemini_client()
# UIとセッションの初期化
st.title("💬 Streamlit + Gemini 履歴保持チャットデモ")
# チャットセッションとメッセージ履歴の初期化
if "chat_session" not in st.session_state:
# chat_session オブジェクトが自動的に履歴を管理
st.session_state.chat_session = client.chats.create(
model="gemini-2.5-pro"
)
if "messages" not in st.session_state:
# Streamlitの表示用メッセージ履歴を初期化
st.session_state.messages = [
{"role": "model", "parts": "私はGeminiモデルです。何でも質問してください!"}
]
# 履歴の表示
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["parts"])
# ユーザー入力と応答ロジック
prompt = st.chat_input("メッセージを入力...")
if prompt:
# ユーザー入力を履歴に追加し、画面に表示
st.session_state.messages.append({"role": "user", "parts": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Geminiからの応答を生成
with st.chat_message("model"):
with st.spinner("Geminiが思考中..."):
response = st.session_state.chat_session.send_message(prompt)
# 応答を画面に表示
st.markdown(response.text)
# Geminiの応答を履歴に追加
st.session_state.messages.append({"role": "model", "parts": response.text})
4. 実行と動作確認
アプリを起動し、対話ができるか確認します。
# (venv)が有効な状態で実行
$ streamlit run app.py
ちゃんと動作しましたね!
これで私もAIエンジニアに一歩近づいたと言っても過言ではないでしょう!
最後に
Streamlitを用いて簡単なGeminiチャットを作ってみました。Streamlitを使えば、今後本格的な機械学習やLLMの構築をする際に、簡単に可視化されたデモを見ながら開発を進められることがわかりました。
今後の展望として、今回作ったデモを元にGeminiを特定の分野に特化させたり、実行時に外部サービスを呼び出したりなど、ユニークなAIのサービスを作れたらいいなあと考えています。
参考
