8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

StreamlitでAIチャットボットを作ってみた

Posted at

はじめに

引き続き生成AIの話題が続いていますね。

私も個人的なプロジェクトとして簡単なチャットボットを作ってみたいと思い、挑戦してみました。今回は、DifyというAIアプリケーション開発プラットフォームを使ってチャットボットのバックエンドを作成し、そのAPIをStreamlitというPythonライブラリを使って構築したフロントエンド/バックエンドと連携させるという試みについて紹介します。

前の記事にDifyについて書きましたので、良かったらご覧ください。

※ここに前の記事のリンクを挿入

Dify(AIアプリケーションを簡単に作成できるノーコードプラットフォーム)とStreamlit(データサイエンティストやエンジニアがウェブアプリケーションを簡単に作成できるPythonライブラリ)を組み合わせることで、比較的少ない労力で機能的なチャットボットを作ることができます。

最後に、Streamlit Cloudを使って無料でアプリのデプロイをやってみました。

Difyでチャットボットのバックエンドを作成

Difyを使ってチャットボットのバックエンドを作成するのは、すごく簡単です。
以下に、その手順を説明します。

まず、Difyの公式サイトにアクセスし、アカウントを作成します。

ダッシュボードから「Create New App」を選択し、チャットボット用の新しいアプリケーションを作成します。

次にLLMのモデルを選択しますが、Difyは複数のLLMモデルをサポートしています。今回はGPT-4oを選択しました(Difyの無料アカウントではGPT-3.5の200メッセージクレジットを無料で使えますが、無料枠を使い切った場合や、他のモデルを使いたい場合は、OpenAI等のAPIキーを登録する必要があります)。

続いてチャットボットの性格や応答スタイルを決定するプロンプトを設定します。今回はオフィスでたまに話題になるカラスをテーマにし、プロンプトを作成しました。

Screenshot 2024-08-23 at 8.01.12.png

アプリケーションの設定が完了したら、「API Access」タブからAPIキーとエンドポイントURLを取得します。これらは後でStreamlitアプリケーションと連携する際に使用します。

Screenshot 2024-08-23 at 8.06.50.png

Streamlitでフロントエンドとバックエンドを構築

Difyで作成したAPIを利用して、Streamlitでチャットボットのフロントエンドとバックエンドを構築します。Streamlitは、Pythonだけでインタラクティブなウェブアプリケーションを作成できるライブラリです。以下に、その実装手順を説明します。

まず、必要なライブラリをインストールします。

pip install streamlit --upgrade

**dify_streamlit_app.py**という名前のPythonファイルを作成し、以下のように基本的な構造を書きます。

requestsライブラリはHTTPリクエストを送るために使用され、streamlitはウェブアプリケーションを簡単に作成するためのライブラリです。st.secretsを使って、APIキーを安全に管理します。ここでは、DIFY_API_KEYという名前で保存されたAPIキーを取得しています。そしてDifyのAPIエンドポイントのURLも定義します。

import requests
import streamlit as st

dify_api_key = st.secrets["DIFY_API_KEY"]
url = 'https://api.dify.ai/v1/chat-messages'

st.titleでアプリのタイトルとして「カラスのお悩み相談室」が表示されます。

st.session_stateは、セッションの状態を保持するために使用されます。conversation_idmessagesがまだ存在しない場合、新しく空のものを作成します。conversation_idはDify上の会話のIDで、messagesは過去のメッセージを保持するリストです。

st.title('カラスのお悩み相談室')

if "conversation_id" not in st.session_state:
    st.session_state.conversation_id = ""

if "messages" not in st.session_state:
    st.session_state.messages = []

過去のメッセージを表示します。st.session_state.messagesに保存されている各メッセージをループで回し、ユーザーとAIのメッセージをそれぞれのロール(役割)に応じて表示します。

for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

st.chat_inputはユーザーがカラスに質問するための入力フィールドを表示します。入力された質問はpromptに保存されます。

ユーザーが質問を入力した場合、それを表示し、st.session_state.messagesにユーザーのメッセージとして追加します。下記のコードはすべて上記のif文の中に入ります。

prompt = st.chat_input("カラスに何か質問してみよう")

if prompt:
    with st.chat_message("user"):
        st.markdown(prompt)

    st.session_state.messages.append({"role": "user", "content": prompt})

次に、AIからの応答を生成し表示するために、APIリクエストを準備します。ヘッダーには認証情報としてAPIキーが含まれており、ペイロードにはユーザーの質問や会話IDなどの情報が含まれます。”response_mode”のところで、”blocking””streaming”を選択することが出来ますが、”blocking”だとチャットボットからの返信が出来上がってからしか返ってきません。”streaming”だと応答を部分的に生成しながら、できあがった部分から順次返します。応答が生成されるにつれて、すぐに表示されます。

with st.chat_message("assistant"):
    message_placeholder = st.empty()

    headers = {
        'Authorization': f'Bearer {dify_api_key}',
        'Content-Type': 'application/json'
    }

    payload = {
        "inputs": {},
        "query": prompt,
        "response_mode": "blocking",
        "conversation_id": st.session_state.conversation_id,
        "user": "alex-123",
        "files": []
    }

APIリクエストを送信し、AIからの応答を取得します。応答が成功すれば、会話IDが更新され、AIの応答が表示されます。エラーが発生した場合には、エラーメッセージが表示されます。

try:
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()

    response_data = response.json()

    full_response = response_data.get("answer", "")
    new_conversation_id = response_data.get("conversation_id", st.session_state.conversation_id)

    st.session_state.conversation_id = new_conversation_id

except requests.exceptions.RequestException as e:
    st.error(f"An error occurred: {e}")
    full_response = "An error occurred while fetching the response."

チャットボットからの最終的な応答を表示します。

message_placeholder.markdown(full_response)

最後に、チャットボットの応答をst.session_state.messagesに追加して保存します。

st.session_state.messages.append({"role": "assistant", "content": full_response})

Streamlit Cloudでアプリをデプロイ

Streamlit Cloudでデプロイすることは非常にシンプル、しかも無料なのでとても便利です。ただ、APIキーを利用しているアプリの場合には、アプリを悪用されないよう注意しましょう。特定の人しかアクセスできないようにしたり、使わない時にアプリをスリープさせたりできます。

ではデプロイしましょう!

まずはアプリのリポジトリをGitHubにpushします。それからは、Streamlit Cloud にアクセスし、アカウントを作成したらGitHubアカウントと連携させることができます。

Streamlit Cloudのダッシュボードで「New app」ボタンをクリックし、GitHubリポジトリ、ブランチ、メインのPythonファイル(dify_streamlit_app.py)を選択します。DifyのAPIキーは「Settings」の「Secrets」で、環境変数(APIキーなど)が追加できます!

Screenshot 2024-08-23 at 10.38.32.png

完成したチャットボットのデモ

アプリのURLにアクセスすると、チャットインターフェースが表示されます。チャットに書いたら、チャットボットが答えてくれますので、チャットボットが正常に動いていることが確認出来ます!

Screenshot 2024-08-23 at 9.13.53.png

以上、StreamlitでDifyのAPIを使用したチャットボットを作ってみました!

Streamlitの機能を活かしたカスタマイズを今後試していきたいです

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?