2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ユーザーとの週次レビューで磨き上げたDify×RAGのUX改善プラクティス5選

2
Last updated at Posted at 2025-12-26

はじめに

当社では、社内業務をサポートする RAG チャットボットの構築を Dify で検証しています。

当初は「ユーザーの質問にどれだけ正確に答えられるか」ばかりに目が行きがちでした。しかし、ユーザー部署との週次定例レビューを重ねる中で、次のような「ユーザー体験(UX)」に関するフィードバックが多く寄せられました。

  • 「何を入力すればいいか分からない」
  • 「回答が遅く、待ち時間が不安」
  • 「履歴が見返しづらい」

本記事では、ユーザーとの週次定例で生の声から学んだ「Difyチャットフローにおけるユーザー体験向上のプラクティス」を5つ共有します。

※本記事は Dify v1.9.2 (OSS版) 時点の情報です。

1. 単純な質問分類は「開始ノード」で処理する

課題:最初の回答が遅い

当初、ユーザーが入力したテキストを質問分類ノードに渡し、そこから「A部署の質問か?」「B部署の質問か?」などを判断して分岐させていました。以下のような例です。

質問分類の例

出典: Dify Legacy Docs1

しかし、この流れだと質問分類や回答生成などで複数の LLM(大規模言語モデル)が実行されるため、初動のレスポンスが遅くなります。可能な限り、LLM の実行回数は減らしたいところです。

解決策:開始ノードのフォームを活用する

ユーザーにとって自明な項目は LLM に推論させるのではなく、開始ノードの入力フィールドで選んでもらう設計にしました。

開始ノードの入力フィールド例:

開始ノードの入力フィールド

入力フィールドは以下のようにオプションやデフォルト値を設定できます。必須にしておくことで、ユーザーが選択しないと次に進めないようにできます。

入力フィールドの定義

メリット:

  1. 高速化: 最初の分類推論をスキップでき、即座にメイン処理へ移れます。
  2. 質問精度向上: ユーザーに質問の種類を意識させることで、質問文が洗練されます。

注意点:項目は直感的にして増やしすぎない

開始ノードの入力フィールドは便利ですが、説明文を直接付与できません。項目が多いとユーザーが離脱しやすくなるため、「直感的に選べる項目(部署名など)」に絞るのが鉄則です。

ユーザー側で分類しにくい項目については、質問分類ノードで巻き取るのがよいと思われます。

2. 会話の開始時に「ユーザーのアクション」を明示する

課題:最初の入力に悩む

最初のチャット画面で「何か入力してください」とだけ書かれていると、ユーザーは「どういう形式で聞けばいいの?」と迷ってしまいます。特に入力ルール(項目の選択など)がある場合はなおさらです。

解決策:オープナーで「最初にやること」を案内する

「機能」→「会話の開始」をONにし、初期メッセージ(オープナー)を設定しました。ここで挨拶だけでなく、具体的なユーザーのアクションを促します。

初期メッセージ例:

オープナー

これによりユーザーの迷いが減り、プラクティス1で設置したフォームの入力も促せます。
また、オープナーには「開始質問」ボタンを設置する機能もあります。

開始質問ボタン例:

開始質問ボタン

うまく質問を表現できれば分かりやすい UI ですが、このボタンを頻繁に使われてしまうと会話履歴の可読性で問題が発生します。現状、私が担当していたアプリでは開始質問ボタンを設置していません。詳細は次のセクションで説明します。

3. 会話履歴を「目次」として機能させる

課題:会話履歴が「定型文」で埋め尽くされる

ユーザーの入力を定型文によって誘導すると、会話履歴が同じタイトルで埋め尽くされてしまう問題が発生しました。当初、先ほどの開始質問ボタンを使って照会分類を促していました。その後、ラリー形式で具体的な質問を入力してもらう流れです。

チャット

このようなやりとりの場合、サイドバーの会話履歴が「A業務」のように同じタイトルが並んでしまいます。以下のイメージです。

履歴

これでは、後から「どの会話に続きの質問をするべきか」が分かりづらくなってしまいます。

解決策:最初のプロンプトで「本質」を入力させる

Dify では、ユーザーの初回入力文が会話履歴のタイトル生成に使われます。

そのため、分類関連は前述の入力フィールドを活用し、「XXシステムのパスワードポリシーを教えて」など具体的な悩みを入力してもらうフローとしました。
これにより、サイドバーが自然と過去の質問一覧として機能するようになります。

過去の質問一覧(履歴)例:

過去の質問一覧例

繰り返しになりますが、入力フィールドの UI は説明文を直接付与できません。入力フィールドを使わずに、リレー形式で質問を誘導する方がユーザー体験としてよい場合もあると思います。UX を考慮しつつ、適切なフローを設計することが重要ですね。

4. 中間レスポンスで「体感待ち時間」を減らす

課題:画面が止まると不安になる

RAG(検索拡張生成)はナレッジ検索→ LLM で回答生成というプロセスを経るため、どうしても処理に数秒~数十秒程度かかります。チャットボットからの回答がないまま待たされると、ユーザーは「フリーズした?」と不安になります。

解決策:検索前に「回答ノード」を挟む

LLM 処理やナレッジ検索に入る直前で、固定のメッセージを表示する「回答ノード」を配置しました。

中間レスポンス

画像は抜粋ですが、上記を通知した後にナレッジ検索→回答生成を実行しています。これだけでユーザーは「処理中であること」を理解でき、ストレスが軽減されます。

5. 毎回ナレッジ検索しない

ここからは、さらにユーザー体験を高めるための、少し踏み込んだ実験的なアプローチです。

課題:毎回ナレッジ検索が走り、無駄が多い

当初のフローでは「簡単にして」「もっと詳しく教えて」といったLLM 回答の聞き直しに対しても、毎回ナレッジ検索が走っていました。これはトークン消費・時間の無駄です。場合によっては、検索結果が変わって回答がブレる原因にもなります。

解決策:質問分類ノードによる「会話継続判定」を入れる

ユーザーの入力が「新規の質問」か「直前の会話の続き」か判定する質問分類ノードを配置しました。初回の質問ではナレッジ検索を実行しますが、2回目以降の場合は「会話継続判定」の質問分類を実行します。

会話継続判定フロー

試行錯誤中ですが、「高度な設定」で指定しているプロンプトのサンプルを掲載します。

判定ロジック(抜粋)
## STEP 1: 会話継続の優先判定(最優先)
まず、ユーザーが「前回の文脈」に依存しているかをチェックします。
たとえ専門用語が含まれていても、以下の気配があれば【会話継続】とみなします。

1. **明示的な言及**: 「先ほどの回答は」「〜とのことですが」
2. **暗黙の言及**: 「もっと詳しく」「理由は?」(主語がない要求)
3. **異議・訂正**: 「そういう意味ではなく」「違います」

**🚨 重要ルール**: STEP 1に該当する場合、後述のキーワードが含まれていても会話継続を優先します。

## STEP 2: 新規照会の判定(STEP 1非該当の場合)
文脈への依存が見られない場合のみ、キーワードマッチングを行います。

1. **業務キーワード**: 申請書名、システム用語、部署名など
2. **形式**: 「~について教えて」「~の方法は」などの独立した質問

---
(※実際のプロンプトでは、ここに誤判定を防ぐための大量の具体例(Few-Shot)を記述して精度を担保しています)
判定プロンプトのサンプル全量
高度な設定プロンプト例
# 命令
照会内容が「前回の会話の継続」かどうかを判定し、適切に処理してください。

## STEP 1: 会話継続の優先判定(最優先でチェック)

### ✅ 以下に該当する場合は【即座に】会話継続と判定

#### A. 明示的な前回回答への言及パターン
-**先ほどの回答**を...」「**前の説明**を...」「**さっきの内容**について」
-**今の説明**を...」「**その回答**を...」「**それを**〜してください」
-**〜とのことですが**」「**〜と言われましたが**」「**〜という回答でしたが**#### B. 暗黙の前回回答への言及パターン(主語なしの要求)
- 「もっと詳しく教えてください」
- 「簡単に説明してください」
- 「わかりやすく教えてください」
- 「初心者向けに優しく説明してください」
- 「具体例を教えてください」
- 「理由を教えてください」
- 「それで合っていますか?」
- 「本当ですか?」

#### C. 前回回答への異議・訂正
- 「そういう意味ではなく」
- 「違います、私が聞きたいのは」
- 「そうではなくて」

**🚨 重要**: 上記A・B・Cのいずれかに該当したら、**特定のキーワード(様式名や専門用語)が含まれていても会話継続**と判定してください。

**判定理由**: 前回回答への言及がある場合、それは前回の文脈を継続する質問であり、新規照会ではありません。

---

## 🟡 STEP 2: 新規照会の判定(STEP 1で該当なしの場合のみ)

### ❌ 以下に該当する場合は新規照会

1. **具体的な帳票・様式名が含まれる**
   - (例:経費精算書、交通費申請、稟議書A、Form-Z など)
2. **具体的な論点・項目名が含まれる**
   - (例:ログインID、エラーコード、VPN接続、再起動、予算コード、発注番号)
   - (例:プロジェクトX、年末調整、源泉徴収、仕訳データ)
3. **「〜すべきですか」「〜でよいですか」「〜はどうですか」という疑問形で、具体的な事項を尋ねている**
4. **「〜について教えてください」「〜の方法は」という情報要求**
5. **新しい状況・前提条件の説明がある**

---

## 📋 判定フローチャート(必ずこの順序で判定)

    ```
    STEP 1: 🔴 会話継続の優先判定
    ├─ 明示的な前回回答への言及あり?
    │  (「先ほど」「今の」「さっき」「〜とのことですが」など)
    │  → YES → 【判定】会話継続 ✅ 【判定終了】
    │
    ├─ 暗黙の前回回答への言及あり?
    │  (「もっと詳しく」「簡単に」「初心者向けに」など、主語なしの要求)
    │  → YES → 【判定】会話継続 ✅ 【判定終了】
    │
    ├─ 前回回答への異議・訂正?
    │  (「そういう意味ではなく」「違います」など)
    │  → YES → 【判定】会話継続 ✅ 【判定終了】
    │
    └─ すべてNO → STEP 2へ

    STEP 2: 🟡 新規照会の判定
    ├─ 様式名・帳票名が含まれる? → YES → 【判定】新規照会 ✅
    ├─ 論点・項目名が含まれる? → YES → 【判定】新規照会 ✅
    ├─ 「〜すべきですか」形式? → YES → 【判定】新規照会 ✅
    ├─ 「〜について教えて」形式? → YES → 【判定】新規照会 ✅
    └─ 新しい状況説明あり? → YES → 【判定】新規照会 ✅
    ```

---

## 🎯 具体例による判定トレーニング

### ✅ 会話継続の例(STEP 1で判定終了)

1. **「備考欄に詳細を記載とのことですが、必須ですか?」**
   → 理由: 「〜とのことですが」で前回回答に言及 → **会話継続**
   → 注: 「備考欄」という論点名があっても、前回言及が優先

2. **「初心者向けに優しく説明してください」**
   → 理由: 主語なしの暗黙の前回回答への言及 → **会話継続**
   → 注: 前回の内容を「初心者向けに」言い換える要求

3. **「もっと詳しく教えてください」**
   → 理由: 主語なしの暗黙の前回回答への言及 → **会話継続**

4. **「先ほどの説明で合っていますか?」**
   → 理由: 「先ほどの説明」で明示的言及 → **会話継続**

5. **「それで合っていますか?」**
   → 理由: 「それ」で前回回答を指す → **会話継続**

6. **「今の説明の○○部分がよく分かりませんでした」**
   → 理由: 「今の説明」で明示的言及 → **会話継続**

7. **「そういう意味ではなく」**
   → 理由: 前回回答への異議 → **会話継続**

---

### ❌ 新規照会の例(STEP 1該当なし → STEP 2で判定)

1. **「ログインIDとパスワードの有効期限は同じにすべきですか?」**
   → STEP 1: 前回言及なし
   → STEP 2: 「ログインID」「パスワード」「有効期限」という論点あり → **新規照会**

2. **「経費精算書で3ヶ月以内の申請なら領収書添付は不要ですよね?」**
   → STEP 1: 前回言及なし
   → STEP 2: 「経費精算書」「領収書」という論点あり → **新規照会**

3. **「VPN接続の方法はどうすればよいですか?」**
   → STEP 1: 前回言及なし
   → STEP 2: 「VPN接続」という論点あり → **新規照会**

4. **「OSがMacのユーザーはどう対応しますか?」**
   → STEP 1: 前回言及なし
   → STEP 2: 新しい状況説明あり → **新規照会**

---

## ⚠️ 最重要ポイント

### 判定の優先順位
1. **最優先**: 前回回答への言及があるか?(明示的 or 暗黙的)
2. **次点**: 論点名・様式名が含まれるか?

### なぜこの順序か
- 「備考欄に詳細を記載とのことですが、必須ですか?」のような質問は:
  - ✅ 前回回答に言及している(「〜とのことですが」)
  - ✅ 前回の内容への追加確認
  - → 論点名(備考欄)があっても**会話継続が優先**

- 「初心者向けに優しく説明してください」のような質問は:
  - ✅ 前回回答の言い換え要求(暗黙の言及)
  - → 前回の内容を別の形式で説明する要求 = **会話継続**

---

## 判定ルール(厳密に従ってください)

1. **前回回答への言及あり(明示的 or 暗黙的)** → 会話継続
2. **前回回答への異議・訂正** → 会話継続
3. **上記1・2に該当しない + 様式名が含まれる** → 新規照会
4. **上記1・2に該当しない + 論点・項目名が含まれる** → 新規照会
5. **上記1・2に該当しない + 独立した質問形式** → 新規照会

---

# 照会内容
{{#sys.query#}}

上記により、ナレッジ検索の回数を減らしてユーザーの文脈を踏まえたスムーズな対話を実現できました。

なお、本アプローチは判定ロジックの精度に依存します。誤判定がユーザー体験を損なっていないかをモニタリングしながら、段階的に導入することをおすすめします。上記プロンプトをご参考になられる場合は、適宜修正してください。

まとめ

Dify でのアプリ開発で「動くもの」を作るのは簡単ですが、「使われるもの」にするには UX への配慮が不可欠です。本記事では以下5つのプラクティスを紹介しました。

  1. 単純な質問分類は「開始ノード」で処理する
  2. オープナーで「ユーザーのアクション」を促す
  3. 会話履歴を「目次」として機能させる
  4. 中間レスポンスで「体感待ち時間」を減らす
  5. 「無駄なナレッジ検索」を省く

これらのプラクティスを取り入れることで UX が改善され、ユーザーとの定例では RAG の精度に関する本質的な議論へ集中できるようになりました。(精度改善や保守性に関する Dify のプラクティスについては、機会があれば別記事で紹介します。)

本記事が、これから Dify で業務アプリを作る方の参考になれば幸いです。

参考資料

  1. 日本語版の画像を掲載するため、Legacy 版から引用しています。最新の仕様はDify Docsをご参照ください。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?