AzureではじめるAI開発：RAG篇



生成AIのカスタマイズ手法について、特にRAGについて書いています。

## はじめに
前回記事で自己紹介やAIについて概要を書いています。併せてお読みください。

https://qiita.com/5ugimotoh/items/3222f9411cd1a12fb9ca

ここでは、生成AIを独自にカスタマイズする方法についてまとめています。また、Azureを用いたRAGについて実装の手順を示しています。

## 生成AIのカスタマイズについて
生成AIはデータを学習させることによって作られています。そして、ChatGPTやClaudeなど学習を経て公開された生成AIのことを「モデル」と呼んでいます。
ここでいうカスタマイズとは、すでにあるモデルを使いながら目的に合わせて調整する手法のことです。
紹介している手法は、プロンプトエンジニアリング、RAG (取得拡張生成)、ファインチューニングです。

なお、本記事はチャットベースのモデルについて書いています。

#### --1.プロンプトエンジニアリング--
AIが理解しやすいように文章を作成する手法です。
プロンプトとは、生成AIを用いたアプリケーション内で私たちが入力する文章のことです。AIが理解しやすいよう整理して文章を入力することで、間違った情報や抽象的な回答ではなく、正確で具体的な、役に立つ回答を出力させようという手法です。
用途を問わず、出力させたい回答の方向性が明確である場合に有用です。

モデル自体の性能や学習データは変えていないため、これから挙げる手法に比べると出力への影響力は小さいです。


#### --2.ファインチューニング--
モデルに専門性を持たせる手法です。
既存のモデルは、学習が完了した段階のデータしか持っておらず、学習していないデータについては出力することができません。目的に沿ったデータを追加で学習させて、専門性の高い回答を出力させようという手法です。
用途が決まっており、特定の作業に特化したモデルを利用したい場合に有用です。

モデルの性能自体を変えるため、学習用に整理された大量のデータが必要になります。その分、出力への影響力も大きくなります。

#### --3.RAG (取得拡張生成) --
回答の生成に「検索」を組み合わせる手法です。
入力されたプロンプトの分析にオリジナルなデータセットを参照させることで、AIの文章理解力を向上させます。追加した個別のデータ内の検索と生成プロセスを組み合わせることで、オリジナリティある回答を出力させようという手法です。
用途が決まっており、個別にデータを用いて回答を出力させたい場合に有用です。

追加するデータの内容に加え、その検索の性能が重要になります。出力への影響力は検索内容に影響されます。
## RAGの実装

:::note
注)RAGにあたってデータの追加とそのデータを用いた動作確認を行っています。その他の設定や検索機能の調整等については、ここでは考えないこととしています。
また、テーマと関連性が低いと判断した技術的な用語については説明していない場合もあります。
:::
Azure AI StudioでRAGの実装をするための手順を書いています。

Azure AI StudioはAIの開発プラットフォームであり、プログラミングや機械学習等に関する専門知識がなくても開発ができます。
ここではStudioで使えるAzure OpenAIサービス内のみでRAGを行います。

#### 実装準備

* **既存モデルの選定**：Azure OpenAIの開発モデルを利用することができます。一部RAGに使用できないモデルもあるので、あらかじめ確認した上で使えるようデプロイしておく必要があります

* **独自データの追加**：.md、.txt、.html、.pdf拡張子のファイルや、Microsoft Word、PowerPointで作成したファイル内に記述されている文章をデータとして追加できます（Excelは対象外）。ファイル内にある画像も参照の対象となりますが、テキストとして読み取られるクオリティについては画像次第であり性能が一定しません。この追加データが、プロンプト入力の際に補助データとして参照されます

* **検索手法の選定**：Azure AI Searchというサービスの検索機能を利用して、データを検索可能な要素に分割するチャンク化を行います。AIは、チャンク化したデータを基にして、関連するキーワードを取得してくることで回答を生成しています。検索方法にはいくつか選択肢がありますが、精度の高いセマンティック検索が推奨されています

#### 実装手順 

![スクリーンショット (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827807/089093fb-8787-1af7-0ad9-87308f6fee30.png)


* Azure OpenAIの**プレイグラウンド**から**チャット**を選択する
* **チャットのセットアップ**で**データを追加する**から**データソースの追加**を選択する

* **データソースを選択**する。ここではAzure AI Studioからファイルアップロードを行う**Upload files**を選択している

![スクリーンショット (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827807/cf1383bd-9247-217b-bf82-a52ad276cd13.png)


* 自身のサブスクリプション、あらかじめ作成したBlobストレージとAI searchのリソースを選択する。その後、データを格納する任意のインデックス名をつける
* **検索の種類**を選択する。ここでは推奨の**セマンティック検索**を選択している
* データの分割単位である**チャンクサイズ**を選択する。ここではデフォルトの値を選択している
* リソース接続のための認証を選択する。ここでは**API**を選択している
* 構成を確認して保存する
* データの追加が完了したら実際にプロンプト入力（クエリ入力）を行い、追加したデータに基づいて回答しているか確認する

#### 出力結果比較

ここでは例として、もんじゃで有名な地域「月島」の魅力について書かれたWordファイル3つを学習データとして用いています。ファイルの文章には、月島へのアクセス、具体的な名称を含む飲食店や観光名所、行事についてまとめられています。3つの内容には重複もありますが、全て同じテーマで書かれたものです。
なお、プロンプトは全く同じ文章、**「東京都中央区にある月島という地域の観光ガイドを作ってください」** と入力しています。

* **既存モデルの出力結果**

![スクリーンショット (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827807/84609a1d-9ee4-ce09-30de-f24236775824.png)

* **データを追加したモデルの出力結果**

![スクリーンショット (25).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827807/c47f3d9d-cd06-9681-67c6-882956d7ad9a.png)

データを追加したモデルのほうが、具体的な店名など詳しい情報が出力されていることがわかります。

## おわりに
生成AIをカスタマイズすることで、モデルの出力性能の向上に用いられることが分かりました。
また、RAGでは既存の学習データに加え自身の持っているデータを追加することで、そのデータに基づいて出力できることが分かりました。

次回はプログラミングを用いて、さらに拡張性の高いカスタマイズを実装したいと思います。

参考文献はMicrosoft learnから
[「大規模言語モデル (LLM) のカスタマイズの概要」](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/customizing-llms)
[「独自のデータを使用して Azure OpenAI モデルとチャットする」](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/use-your-data-quickstart?tabs=command-line%2Cpython-new&pivots=programming-language-studio)
[「Azure OpenAI Service を使用して生成 AI ソリューションを開発する」](https://learn.microsoft.com/ja-jp/training/paths/develop-ai-solutions-azure-openai/)
[「Azure OpenAI On Your Data」](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/use-your-data?tabs=ai-search%2Ccopilot#semantic-search)
より。