はじめに
生成AIに独自の情報から回答させるRAGというものが流行っております。RAGを構築することで社内データから回答するチャットボットを構築可能です。この記事ではRAG構築に必要な検索システムの構築をAzure AI Searchといサービスを用いて行います。
目的
- RAGを構築するために必要なインデックス作成を行う。
- Azure AI Search を用いて独自のドキュメントからベクトル化したインデックス作成します。
- 参考:Azure AI Search でインデックスを作成する
- インデックスを作成することでAI Search内で検索可能なテキストを作成します。
環境
- Azure AI Search(検索エンジン)
- Azure OpenAI(ベクトル化)
- ストレージアカウントのBlob(データストア)
- 青空文庫(ドキュメント)
- Windows 10(クライアント端末)
今回は上記のサービスを使用します。
手順
インデックス化するドキュメントの用意

- 青空文庫にある「走れメロス」を使用します。
- 「走れメロス」のページに移動して「Ctrl + S」でHTMLファイルを任意の場所に保存します。
- 独自の資料がある方はそちらを使用しても大丈夫です。

- 資料用意できましたら、Azureのストレージアカウントの対象のコンテナに資料をアップロードします。
Azure AI Search のリソース作成

- セマンティック検索が使える「Basic」以上の価格レベルを選択します。
- 「スケール」「ネットワーク」はデフォルトで大丈夫です。
- 「確認および作成」「作成」を選択します。
セマンティック検索とは、検索エンジンにユーザーの検索意図・意味をくみ取って最適なコンテンツを提供する技術のことです。
参考:セマンティック検索とは?仕組みや意味、メリットについてわかりやすく徹底解説!
セマンティックランカーの有効化
セマンティック検索の結果をランク付けして、関連性の高い結果を返せるようにするセマンティックランカーを有効にします。
参考:セマンティック ランク付けを構成して検索結果でキャプションを返す
※Free プランは、1 か月あたり 1,000 件のクエリに制限されています。

- 作成した「AI Search」に移動します。
- 左のメニューから「セマンティックランカー」を選択します。
- 「Free」のプランを選択します。
ベクトル化したインデックスを作成する
GUIからベクトル化したインデックスを作成します。

- 作成した「AI Search」に移動します。
- 「データのインポートとベクター化」を選択します。

- 「データへの接続」の画面で対象のストレージアカウントとコンテナを選択します。
- 「次へ」を選択します。

- 「データのベクター化と強化」の画面に移動します。
- ドキュメントのベクトル化に使用するモデルを選択します。
- 申し訳ないですが、Azure OpenAI やモデルのデプロイ方法はここでは説明しないので自身で調べてください。
- 「セマンティックランカーを有効にする」を選択します。
- スケジュールは一旦「1度」を選択します。
- 「1時間に1回」等の頻度を選択可能でデータソースに追加されたドキュメントのインデックス化を行うことが可能です。
- 「次へ」を選択します。

- 「レビューと作成」の 画面に移動します。
- オブジェクトのプレフィックスを任意の値で設定します。
- 「作成」を選択します。
アナライザーを変更する
アナライザーについての説明は以下に任せます。
参考:Azure Cognitive Searchでの日本語向けAnalyzerの違い
ここで行うことのメモになります。
- デフォルトでアナライザーが「null」になっている。(おそらく英語のアナライザーが使われる)
- 検索精度向上のため、titleとchunkのアナライザーを「ja.lucene」に変更する
- 変更したら、インデクサーで「リセット→実行」でインデックス再度作成。

- AI Search に移動します。
- 左のメニューから「インデックス」を選択します。
- インデックスが作成されているので選択します。

- 作成されたインデックスを選択します。
- フィールドのタブに移動します。
- 「chunk」「title」のアナライザーが「標準」になっています。
- 標準は英語のアナライザーとなっており、こちらを日本語に対応したアナライザーに変更します。

- 「JSONの編集」を選択します。

- エディターの値をコピーしてメモ帳等に一時的に貼り付けます。
- 「キャンセル」を押して前の画面に戻ります。

- 「削除」を選択します。
- 先程コピーした値から新たなインデックスを作成するため、現在の値を削除します。

- 削除したら前の画面に戻ります。
- 戻らない場合は左のメニューから「インデックス」を選択します。
- 「インデックスの追加」>「インデックスの追加(JSON)」を選択します。

- エディターが出てくるので先程コピーした値を貼り付けます。
- 赤い部分はすべて消します。
- この画像では2-3行目はずべて削除します。

- 赤い部分を消します。
- この画像では100-104行目は全て消します。
- 赤い部分がすべてなくなれば大丈夫です。

- 「chunk」のアナライザーを変更します。
- 最初は「null」が入っていますが「ja.lucene」に変更します。
- 「ja」と入力すれば補完されます。

- 同様に「title」のアナライザーも変更します。
- 変更できたら「保存」を選択します。

- スキルセットの設定も日本語の精度を向上させるため変更します。
- 左のメニューから「スキルセット」を選択します。
- 対象のスキルセットを選択します。

- 「"#Microsoft.Skills.Text.SplitSkill"」の言語を「en」から「ja」に変更します。
- 「保存」を選択します。
インデックスを再度作成する
インデクサーを実行して、再度インデックスの作成を行います。

- 左のメニューから「インデクサー」を選択します。
- 対象のインデクサーを選択します。

- まず「リセット」します。
- リセット完了したら「実行」を選択します。
- 実行完了するとステイタスに「成功」が出てきます。
クエリしてみる
作成したインデックスに対してAzure Portal からクエリを実行できるので試しに行います。

- 左のメニューから「インデックス」を選択します。
- 対象のインデックスを選択します。

- 検索ボックスに調べたいことを入力します。
- 「検索」を選択します。
- 結果がJSONで出てきます。
検索結果の「@search.caption」の「text」か「highlights」をAOAIに渡して要約してもらうことでRAGを実装することが可能になります。
まとめ
- GUIベースで独自の知識を持った検索システム構築可能