RAGを活用したチャットボットの知識拡張、回答の正確性と充実度を高める方法をDifyで学ぶ:「生成AI」×ノーコードツール「Dify」で学ぶ、チャットbot構築のいろは(4)
ノーコードでAIチャットbotを作成できるDifyの入門連載。第4回では、製品情報のドキュメントをナレッジベースに登録し、RAG(検索拡張生成)を活用してチャットbotに回答させる方法を解説します。
連載:「生成AI」×ノーコードツール「Dify」で学ぶ、チャットbot構築のいろは
本連載のサンプルデータとプロンプトをGitHubで公開しています。こちらからダウンロードしてみてください。
目次
はじめに
ノーコードでAI(人工知能)チャットbotを作成できるDifyの入門連載。前回までの連載で、Difyを使ったチャットbotの作成方法、Webサイトへの埋め込み方、プロンプト設計やテスト、ユーザーフィードバックを使った品質改善などを学んできました。本稿では、チャットbotがより豊富な情報源にアクセスできるようにすることで、回答の正確性と充実度を高める手法を解説します。
ナレッジベースとRAGの基本
生成AIはもともとの学習データに含まれない情報を答えられないだけでなく、誤情報をもっともらしく生成してしまうこともあります(ハルシネーション)。RAG(検索拡張生成、Retrieval-Augmented Generation)は、この問題を解決するための技術で、ユーザーからの質問に答える際にまず外部の知識ベース(ナレッジベース)から関連情報を検索し、その結果をコンテキストとして大規模言語モデル(LLM)に与えることで、より正確で最新の回答を生成します。
Difyのナレッジベースは、テキストファイルやWebサイトといった外部情報をRAGの検索対象として登録できる仕組みです。ナレッジベースを作成しておき、それをチャットbotやワークフローなどに接続することで、LLMがユーザーからの問い合わせに応じてそれらの情報を検索し、その情報を基に回答を生成できるようになります。
本連載でテーマにしているカスタマーサポートのチャットbotにおいては、前回までは製品情報などをプロンプトの一部として与えていましたが、ナレッジベースを利用することで、資料が膨大な場合や頻繁に更新される場合でも、チャットbotが最新の情報を参照して回答するということが実現できます。
資料となるテキストファイルの準備
Difyでは、以下の3種類のデータソースから情報を取得してナレッジベースを作成できます(図1)。
- テキストファイルからインポート
- Notionから同期
- Webサイトから同期
まずは最も基本的なデータソースであるテキストファイルからのインポートについて説明します。
図1にもある通り、PDFやテキストファイル、Markdown、HTML、Excel、Word、CSV、電子メールなど、さまざまな形式のデータをアップロードして利用できます。このため、企業の製品マニュアルやFAQなどのドキュメントをAIの知識として流用できる可能性があります。
ただし、ここで「テキストファイル」と表現されている通り、どのような形式であってもファイル内にテキストが含まれていることが前提になります。テキスト情報が含まれていないファイルを使用する場合は、事前にOCR(光学文字認識)などでテキスト情報を生成しておく必要があります。
また、後述のようにファイル形式やその内部形式によってもナレッジベースの品質が変わってくるので、一概にこれが最適と言えるものはなく、資料の事前処理も含めた試行錯誤が必要です。
今回準備するテキストファイルについて
さて、今回の対象商品「超新青オールインワン」は架空の製品のため、実際のドキュメントが存在しません。そこで、第3回までに設定した製品の基本情報を基に、以下のようなオリジナルの資料を作成しました。なお、本資料の内容は生成AIによって生成されたものであり、本稿では資料に記載された内容を保証しません。
- 製品説明書:製品の概要、特徴、使用方法、成分、注意事項、価格、販売チャネル、メーカー情報などを記載したドキュメントです。
- 有効成分一覧:製品の主成分について、一般的に知られている作用や留意点をまとめたものです。今回のテーマは化粧品で法規制があるため、科学的な説明はあくまで一般論にとどめ、効果・効能を保証しないようにしていますが、認可などが得られている場合はその部分を詳細に記載すればよいでしょう。
ファイル形式による差異を比較するため、製品説明書はPDF形式、有効成分一覧はExcel形式、Word形式、Markdown形式の3種類を用意しました。図2と図3にそれぞれのイメージを示します。
有効成分一覧のファイル形式の違いによる差異については、後ほど詳しく説明します。
ナレッジベースの作成とチャットbotアプリのコンテキスト設定
Difyではナレッジベースを使ったAIシステムを容易に構築できますが、構築途中で出てくる用語や概念などの事前知識が必要です。ここでは先にナレッジベースの作成手順とチャットbotアプリへの組み込み方を説明し、その後でRAGに必要となるチャンク化、インデックス方法、検索方法などの詳細な設定について解説します。
ナレッジベースの作成手順
まず「製品説明書」のナレッジベースを作成し、準備した資料をアップロードする手順を説明します。Difyのヘッダメニューで「ナレッジ」をクリックしてナレッジ画面を開き、「ナレッジベースを作成」をクリックします(図4)。
データソースには、「テキストファイルからインポート」「Notionから同期」「ウェブサイトから同期」が選択できます。ここでは「テキストファイルからインポート」を選択します。資料のファイルをドラッグアンドドロップで指定し、「次へ」をクリックします(図5)。
アップロードしたファイルのチャンク化とインデックス方法を設定します。詳細は後述しますが、基本的にはチャンクをプレビューしながら、分割方法やサイズを調整し、「チャンク設定」を行った後、「インデックス方法」や「埋め込みモデル」「検索設定」を設定します。設定したら「保存して処理」をクリックすることで、Difyが自動的にファイルを解析し、ナレッジベースとして登録します(図6)。
「ナレッジベースが作成されました」という画面でチェックマークが付いたら、ナレッジベースの作成は完了です(図7)。
ここで「ドキュメントに移動」をクリックして、作成したナレッジベースを開くとナレッジベース名や設定が変更できます。
Difyでは、1つのナレッジベースに対して、複数のドキュメントを登録できます。ただし、チャンク化はドキュメント単位で行われますが、それ以外の設定はナレッジベース全体に適用されるため、例えば埋め込みモデルを分けたい場合は、ナレッジベース自体を別に作成する必要があります。
チャットbotにナレッジベースを組み込む
ナレッジベースを作成したら、これを既存のチャットbotにひも付けます。ナレッジベースは複数のチャットbotやワークフローから参照できます。
Difyの「スタジオ」から第3回までに作成した「超新青オールインワン カスタマーサポート」アプリを開き、オーケストレーションの「コンテキスト」で「追加」をクリックします(図8)。
「参照する知識を選択」で追加した「製品説明書」を選択し、「追加」をクリックします。ナレッジベースは複数選択できます。これでチャットbotがナレッジベースを参照できるようになります(図9)。
では、プロンプトに設定してあった製品に関する情報を削除した上で、「デバッグとプレビュー画面」で製品情報に関する質問をしてみましょう(図10)。
図10のように、プロンプトに与えていない情報をナレッジベースから取得して回答できました。ナレッジベースの情報を参照した場合は「引用」という形で、どのドキュメントから情報を取得したかが表示されます(デバッグとプレビュー画面でのみ表示され、ユーザーに公開されるアプリでは表示されません)。
ナレッジベース作成時の設定
ナレッジベースの作成からチャットbotへの組み込みまでのイメージができたところで、次にナレッジベースの作成時に必要な設定について詳しく解説します。RAGを効果的に活用するためには、チャンク化やインデックス方法、検索方法などの理解と試行錯誤が必要になってきます。
データソースのチャンク化
ナレッジベースを作成する上で、最初のポイントはチャンク化です。「チャンク化」(Chunking)とは、入力したテキストを意味のある小さな単位に分割することです。これがRAGの検索対象となるため、分割方法によって検索性や回答精度が左右されます。
Difyでは「汎用(はんよう)」と「親子」の2方式が選べます。「汎用」は区切り文字(チャンク識別子)や最大チャンク長などを指定してチャンクに分割する一般的な手法です。「親子」は「汎用」を親チャンク(例えば「段落」)と子チャンク(「文」)のように階層構造で関連付けて管理する手法です。本稿では基本となる「汎用」を使用します。
チャンク化の最適な方法はデータの性質や目的によって異なり、現時点でのベストプラクティスは確立されていません。実際の運用では、設定を調整しながら最適な分割方法を探る必要があります。
・調整可能なチャンク化のパラメーター
Difyでチャンク化を行う際に調整可能なパラメーターは表1の通りです。これらの設定を調整することでチャンク化の挙動をある程度カスタマイズできます(図11)。
パラメーター | 内容 |
---|---|
チャンク識別子 | チャンク化の際に使用する区切り文字を正規表現で指定します。例えば、Markdownの段落のように空行を区切りとして扱いたい場合は「\n\n」を指定します。これにより、改行2つで区切られた部分が1つのチャンクとして扱われます。 |
最大チャンク長 | 1つのチャンクに含める最大文字数を指定します。これにより、長過ぎるチャンクが分割され、検索時のパフォーマンス向上が期待できます。デフォルトは1024文字です。 |
チャンクのオーバーラップ | チャンク間の重複部分を指定します。例えば、前のチャンクの最後の数行を次のチャンクに含めることで、文脈を保ったまま分割できます。これにより、情報の一貫性が向上します。デフォルトは50文字です。 |
連続するスペース、改行、タブを置換する | テキストの整形が行われ、検索時のノイズが減少します。ただ、筆者の試した範囲ではこのオプションがオフでも不要なスペースや改行は削除されていました。 |
すべてのURLとメールアドレスを削除する | プライバシー保護やセキュリティのために有効ですが、データにチャットbotが回答すべきURLやメールアドレスを含んでいる場合はオフにしておきましょう。 |
表1 調整可能なチャンク化のパラメーター |
パラメーターの詳細については、公式レファレンス(2. チャンクモードの指定 - Dify Docs)も参照してください。
・チャンク化された入力データの比較
前述の通り、RAGの検索にはこのチャンク化が重要になるため、今回は製品に使われている(という想定の)有効成分を記載したドキュメントを3つの形式(Excel形式、Word形式、Markdown形式)で用意し、Difyにアップロードしてチャンク化の挙動を比較しました(図12)。
これをDifyの標準設定でチャンク化したプレビュー結果は、図13のようになりました。
Excel形式の場合は、内部構造がXMLのため、チャンク化も構造化された情報を維持してチャンク化しようとした形跡が見られます。情報は行ごと(成分ごと)になっているため、チャンクの検索性はよさそうですが、"None"のような不要な文字列が混じってしまっているためこれはノイズになりそうです。
半面、Word形式は、文書に「表題」や「見出し」といった構造化情報を含んでいるにもかかわらず、連続した文字列だと見なされ、最大チャンク長の1024文字で分割されてしまいました。オーバーラップで指定した程度の長さの文字列が第2チャンクにも含まれていることが確認できます。チャンクは成分ごとに分割されていないため、成分ごとの検索性は低いと考えられます。
Markdown形式は、今回の例ではうまく成分ごとにチャンク化されており、検索にもコンテキストにも適した形になっていそうに見えます。
実際にこれら3つのナレッジベースをチャットbotで試しましたが、いずれの形式でも回答結果に大きな差は見られませんでした(図14)。今回の例では情報量(チャンク数)が少ないため、有意な差にはならなかった可能性がありますが、チャンク化の結果は、情報量が多い場合や複雑な構造を持つドキュメントでは大きな影響を与えることが予想されます。
【コラム】テキストファイルのチャンク化における前処理の重要性について
Excel形式については、一般的なビジネス文書でありがちなタイトルや日付入りのものを用意しましたが、これがチャンク化のノイズになったようです。試しに、最初の2行(タイトルや日付)を削除したところ、チャンク化の結果は図15のようになりました。
元のファイル(左)に比べ、表だけにしたファイル(右)はチャンクの内容が「"列見出し":"セルの値";」とうまく構造化されていることが確認できます。このような構造をとることができれば、単純なテキストの羅列よりLLMによる解釈が容易になり、回答精度も向上することが期待できます。
いずれにしても、既にあるデータをナレッジベースとして利用する場合は、その前処理が重要だということが確認できました。
インデックス方法と埋め込みモデル
チャンク化と同様に、「どのようなインデックスを作成してどう検索するか」についても、情報の検索性とLLMの回答の正確さを確保する上で重要です。図16はDifyのナレッジベースのインデックス方法の選択画面です。
Difyでは、インデックス方法を「高品質」と「エコノミー(経済的)」の2種類から選択できますが、「高品質」が推奨であり、RAGで一般的に利用される「ベクトル検索」がこちらに相当するので、ここでは「高品質」についてのみ説明します。
ベクトル検索は、チャンク化されたテキストを数値ベクトルに変換して保存し、ユーザーからの質問を数値ベクトルに変換したものと照合して関連するチャンクを検索します。これにより、単なるキーワード一致ではなく、意味的な類似性に基づいた検索が可能になります。ここでいう「ベクトル」や「数値ベクトル」とは、例えば [0.52,-0.12,0.33,0.89,-0.22] のような数値の配列のことで、意味的に似た文章や単語は似たような値に変換されます。つまり、文章の意味を数値で表現することで、コンピュータが理解しやすい形に変換するわけです。
この文章を数値ベクトルに変換するための手法が「埋め込み」(Embedding)であり、それを実際に行うのが「埋め込みモデル」(Embedding Model)です。「埋め込み」という単語は直感的ではないのですが、自然言語処理の文脈では昔から用いられてきた数学用語なので慣れることにしましょう。Difyでは、埋め込みモデルとしてOpenAIの「text-embedding-3-small」や「text-embedding-3-large」などが選択できます。
検索方法
次に、埋め込みによって数値ベクトルになったデータをどのように検索するかを「検索方法」で設定します。Difyでは、以下の3つの検索方法が選べます(図17)。
- ベクトル検索
- 全文検索
- ハイブリッド検索
「ベクトル検索」は前項で説明した通り、ユーザーが入力した質問も同じように「埋め込み」によって数値ベクトルに変換し、チャンクの数値ベクトルと比較することで関連する情報を取得します。意味的な類似性に基づくため、キーワードが完全一致しなくても関連する情報を取得できるのが特徴です。
「全文検索」は従来の検索エンジンと同様に、一致するキーワードが含まれるチャンクを優先的に取得します。正確な語句やフレーズを検索したい場合に有効です。
「ハイブリッド検索」はその名の通り、ベクトル検索と全文検索を同時に実行して、よりユーザーの質問と関連性の高い結果を返す方法です。どちらが優先されるかはウェイト(重み)設定で調整できます。
なお、ベクトル検索とハイブリッド検索では、Rerankモデルを指定できます。Rerankとは、RAGの検索結果の中から最も関連性の高いものを再評価して順位付けする手法です。DifyではJinaやCohereのRerankモデルを利用できます。Rerankを利用した方が検索結果の精度がより上がるため、回答品質も向上することが期待できますが、本稿では割愛します。詳細は公式レファレンス(Rerank - Dify Docs)を参照してください。
補足:外部Webサイトの情報をナレッジベースに変換する
Difyは手元にあるファイルだけでなく、外部のWebサイトからも情報を収集できます。とはいっても、実際にWebサイトを読み取るには、Jina ReaderやFirecrawlといった外部のツールを利用します。ここではJina Readerを使ってWebサイトをスクレイピングし、チャンク化する例を紹介します。
Jina Readerのアカウント登録とAPIキーの設定
Jina Readerの利用にはアカウント登録が必要です。公式サイトからアカウントを作成し、APIキーを取得してください(図18)。10万トークン分の無料枠があるため、試用するには十分でしょう。
Difyの「設定」を開き、「データソース」の「ウェブサイト(によるJina Reader)」を選択します(図19)。日本語はおかしいですが by Jina Readerの直訳でしょう。
JinaのAPIキーを入力して保存します(図20)。
「アクティブ」という表示に変われば、データソースとしてJina Readerが利用できるようになります(図21)。
Jina Readerを使ったWebサイトのスクレイピング
Webサイトからデータを取得してみます。ナレッジベースの作成画面で「ウェブサイトから同期」を選択し、URLを入力します。ここでは、前回記事のURLを入力してみました(図22)。
「実行」を押すと、Jina ReaderがWebサイトをスクレイピングし、その結果が右側に表示されます。きれいにMarkdown形式で記事を取得できていることが分かります(図23)。ただh2やh3などの見出し情報は省略されています。
次にデフォルトの設定でチャンク化してみると、段落ごとのチャンクになりました(図24)。Jina ReaderでMarkdownになっているため、チャンク化の部分は検討しやすそうです。
この後は、前述のナレッジベースの作成手順と同様に、インデックス方法や検索方法を設定してナレッジベースを作成します。
注意点
外部のWebサイトが、自身(自社)の管理外である場合は以下のような注意が必要です。
- 対象サイトの利用規約、プライバシーポリシーでスクレイピング、再利用が許容されているかどうか必ず確認する
- robots.txt(特にDisallow / noindex 指定)に反しない
- 会員限定、ログイン必須、課金コンテンツは取得しない(技術的に取得できても権利侵害リスクがある)
- 著作権表示、クレジットが必要な場合は記録しておく
- 個人情報、追跡パラメーター(?utm=など)付きURLは前処理で除去、匿名化する
- 高頻度クロールは負荷となるため、再同期が必要な場合は更新間隔を適切に設定する
まとめ
本稿では、プロンプトを簡潔にしたまま、カスタマーサポートチャットbotの回答知識を充実させる方法としてDifyのナレッジベース機能を紹介しました。
今回、製品説明や有効成分といった製品情報をナレッジベースとして与えるようにした一方、よくある質問(FAQ)はナレッジベースに登録しませんでした。これは前回紹介した「アノテーションリプライ(注釈返信)」がFAQとして活用できるためです。実際の(人間の)サポートセンターで使っているFAQリストを流用するなどの場合は、ナレッジベースに登録しておくのも有用かもしれませんが、この場合でもアノテーションリプライへの一括インポートを利用した方が簡便かつコストも削減できると考えられます。
本連載ではDifyのチャットbot関連の機能を利用して、可能な限り現実に近いカスタマーサポートのチャットbotを構築してきました。本連載の範囲では紹介しきれなかった機能や設定も多くあり、さらにワークフローを利用すればより高度なチャットbotを構築することもできます。興味のある人はぜひ試してみてください。
筆者紹介
WINGSプロジェクト 山田研二(ヤマダ ケンジ)
株式会社MSEN CTO(https://msen.jp/)。高校卒業後、大阪大学の研究所で働きながらプログラミングやWebデザインをはじめ、以後20年以上、Webサイト制作や業務システムの構築を手掛けている。フリーソフトも幾つか公開している。好きな言語はC#とTypeScript、趣味は旅行。
・GitHubアカウント(https://github.com/kenzauros)
WINGSプロジェクト
有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティー(代表山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手掛ける。2021年10月時点での登録メンバーは55人で、現在も執筆メンバーを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。
・サーバーサイド技術の学び舎 - WINGS(https://wings.msn.to/)
・RSS(https://wings.msn.to/contents/rss.php)
・X: @WingsPro_info(https://x.com/WingsPro_info)
・Facebook(https://www.facebook.com/WINGSProject)
Copyright © ITmedia, Inc. All Rights Reserved.