💬

[Dify] 4. Dify で作ったフローを API として呼び出して Stremlit で 簡単チャットボットアプリを作る

に公開

執筆日

2025/08/01

概要

今更Dify第4弾です。簡単 Web チャットボットアプリを作っちゃおうの回。最低限のマルチターン会話の実装であればびっくりするくらい簡単です。

前提条件

  • 執筆時 Dify Version latest 1.7.1
  • 前回の第3弾まで(Dify立ち上げ・ナレッジベース作成・フロー作成)まで完了している
  • python環境
ライブラリインストール
pip install requests streamlit

API公開

公開したいスタジオを開いて、[更新を公開]を押すとその下の4項目がアクティブになり、APIが使用可能になります。フローを更新したら更新するのを忘れないようにしましょう。

ちなみに本当にチャットボットだけ使えればいい場合は、アクティブになった各項目からURLを使いたい人に渡したり、社内のページにサイトを埋め込んだりできます。その場合はよくあるLLMチャットボットのこんな画面が使えます。探索ページで開く場合はDify上での実行になるため、Difyに招待したユーザーだけが使えます。

[API リファレンス]を開くとこんな感じでAPIの使い方一覧が表示され、チャットボット作成に必要なAPI機能がまとまっているのを確認できます。複数スタジオを公開した場合でもAPIエンドポイントは同じで、シークレットキーによってどのスタジオを使うか管理するようになっています(スタジオ切替の実装も楽でありがたい)

一番右上の[APIキー]ボタンを押し、新しいシークレットキーを作成を押すことでAPIキーが作成できます。

エンドポイントとAPIキーが準備できたら次はStreamlitの立ち上げです。

Streamlitでチャットボットを立ち上げる

ここまで来て初めてコーディングです。今回はチャット履歴選択とかよくある機能も省いてマルチターン会話が出来るところだけの最低限サンプルを作りました。コメント含めてもたったの80行です。ストリーミング処理をしなければさらに簡単にできますが、そこだけはちょっとつまづく可能性がありそうなポイントなので盛り込んでいます。

コードサンプル app.py

DIFY_API_KEY = "<作成したAPI KEY>"の部分だけ変更すれば動くようにできています。

app.py
import uuid
import json

import streamlit as st
import requests

DIFY_API_URL = "http://localhost/v1/{endpoint}"
DIFY_API_KEY = "<作成したAPI KEY>"

# --- セッション状態の初期化 ---
if "messages" not in st.session_state:
    st.session_state.messages = []
if "conversation_id" not in st.session_state:
    st.session_state.conversation_id = ""
if "user_id" not in st.session_state:
    st.session_state.user_id = str(uuid.uuid4())

# --- ヘッダー ---
st.title("LLMチャットボット")

# --- チャット履歴の表示 ---
for msg in st.session_state.messages:
    with st.chat_message(msg["role"]):
        st.markdown(msg["content"])

# --- ユーザー入力の受付 ---
user_input = st.chat_input("メッセージを入力してください")
# --- ユーザー入力に対してチャット処理 ---
if user_input:
    # ユーザーの入力を履歴に追加
    st.session_state.messages.append({"role": "user", "content": user_input})
    with st.chat_message("user"):
        st.markdown(user_input)
    # Dify へリクエスト送信
    try:
        headers = {
            "Authorization": f"Bearer {DIFY_API_KEY}",
            "Content-Type": "application/json"
        }
        payload = {
            "inputs": {},
            "query": user_input,
            "response_mode": "streaming",
            "conversation_id": st.session_state.conversation_id,
            "user": st.session_state.user_id,
            "files": []
        }
        # --- ストリーミング応答の表示 ---
        with st.chat_message("assistant"):
            message_placeholder = st.empty()
            full_response = ""
            with requests.post(DIFY_API_URL.format(endpoint="chat-messages"), headers=headers, json=payload, stream=True) as response:
                if response.status_code != 200:
                    st.error(f"Difyリクエストでエラーが発生しました: {response.text}")
                else:
                    for line in response.iter_lines():
                        if line:
                            try:
                                chunk = line.decode("utf-8")
                                if not chunk.startswith("data:"):
                                    continue
                                if chunk.startswith("data: "):
                                    chunk = chunk.removeprefix("data: ").strip()
                                if chunk == "[DONE]":
                                    break
                                data = json.loads(chunk)
                                delta = data.get("answer", "")
                                full_response += delta
                                message_placeholder.markdown(full_response + "▌")
                            except Exception as e:
                                st.error(f"デコードエラー: {e}")
            message_placeholder.markdown(full_response)

        # 会話ID保存
        st.session_state.conversation_id = response.headers.get("X-Conversation-Id", st.session_state.conversation_id)
        # 履歴保存
        st.session_state.messages.append({"role": "assistant", "content": full_response})
    except Exception as e:
        answer = f"エラーが発生しました: {e}"

以下を実行してアプリを立ち上げます。

streamlit起動
streamlit run app.py

こんな感じで、簡単にチャットボットが立ち上げられます。HWSではSLMのファインチューニングを案件で経験しているエンジニアもいます!(突然の宣伝)

忘れてましたが、Streamlit用に最終回答の文字列をちょっといじっています。フローの回答部分でいじってもいいですし、pythonコード側でいじってもいいですね。

おわり

今回はPOSTでhttp://localhost/v1/chat-messagesだけを使った最低限アプリですが、チャットボットの要件に合わせて様々な機能を追加するためのAPIも各種ちゃんと揃えられています。例えばGETで同じエンドポイント(にユーザーidと会話履歴idをクエリパラメータに追加)を呼び出せば履歴取得が出来ます。自分で一から実装しようと思うと結構大変な機能が大体揃っているのはローコードツールの魅力です。詳しくはAPIリファレンスで確認してください(よくあるチャットボット機能が17種類あります。2025年8月現在)
また、Streamlitを使えばさらに細かい要件にも簡単に答えられる実装が可能です(例えばst.selectboxを使ってスタジオを切り替えることで別のフローのチャットボットと会話するとか)。

ヘッドウォータース

Discussion