Azure AI Foundry に 無料版など独自設定したAzure AI Search を設定する手順

# 背景

RAGのお手軽検証環境として Azure AI FoundryのPlaygroundは本当に便利です。私もよく使っています。

- PlayGroundでの動作確認
- 複数のモデルの切り替え
- 複数のモデルの評価環境。MLOps含む

デフォルトのままですと、幾つかやりづらい点もあったりします。そのために、ここでは独自のAzure AI Searchを追加する手順をメモしておきます。

Azure AI Search のサービス レベルを選択する:

- Azure AI SearchのSKUの選択が柔軟ではない。デフォルト設定のStandardの能力ほど、利用しない。
- Azure AI Searchでは、Standardで作成すると、それ以下のBasicやFreeに**変更できない**。以上には出来る

https://learn.microsoft.com/ja-jp/azure/search/search-sku-tier

- Azure AI Foundryで作成する Azure AI SearchのIndexer (クローラー的なもの) が参照する先**データソース**のBlob Storageなどが、扱いづらい...ファイル追加などの際に不便


https://learn.microsoft.com/ja-jp/azure/search/search-data-sources-gallery

- 独自に作成したAzure AI SearchをAzure AI Foundryに追加する際に**アクセス権設定**が煩雑
- この手順書 (チュートリアル) はあるものの。SDKベース。Portalのみではない。

https://learn.microsoft.com/en-us/azure/ai-foundry/tutorials/copilot-sdk-create-resources?tabs=windows

# ポイント

こちらが全体像ですね。

ファイルはBlob Storageに置きます。一番簡単なので

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/78814bd2-6ed3-431e-8e33-692b46c40072.png)

- Azure OpenAI Service は別に
    - Azure AI Searchの Wizardでは、Azure AI Foundry　で Azure OpenAI ServiceのEmbedding Modelが使えません。Azure AI Foundryとは別で Azure OpenAI Service を作成します。
        - https://learn.microsoft.com/ja-jp/azure/search/search-get-started-portal-import-vectors?tabs=sample-data-storage%2Cmodel-aoai%2Cconnect-data-storage#supported-embedding-models
    - **Cohere-embed-v3-multilingual** については、敬愛する花ケ崎さん (@nohanaga) のBlog Postを参照してください😊
        - モデルカタログ で Cohere-embed-v3-multilingual をデプロイして Azure AI Search でベクトル検索する
        - https://qiita.com/nohanaga/items/fd04e2223b8a237cf335

- 権限設定は 1 度です
    - Azure AI Searchが、Azure Storage Accountを読めるように
        - Blob以外にファイルを置く場合は、そちらへの設定が必要ですね
    - Azure AI Foundryが、Azure AI SearchのIndex操作が出来るように
        - こちらはAzure AI Foundry 作成時に、既存の Azure AI Searchを選択すれば行う必要はありません。
        - もし、作成後に追加する場合は、手動で設定してください。

# 必要なもの

- Microsoft Azure の Subscription
    - お持ちでない方は、こちらからどうぞ!
    - https://azure.microsoft.com/ja-jp/pricing/free-services/
- RAG対象のデータ
    - なんでも。
    - 最初は5つ程度など**少量**で行うことをお勧めします
    - もし手持ちがなければ、敬愛する花ケ崎さん (@nohanaga) の鎌倉武将で。
    -https://qiita.com/nohanaga/items/f710cac82072b63bc73f#%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89


# 手順

やっていきますね。

**同じリソースグループに作成**します。

後で、**まとめて削除できるように**。

# 1. Azure Storage Account 作成

ご参考。

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-account-create?tabs=azure-portal

# 1.1. ファイルのアップロード

手元のファイルをBlob Storageにアップロードします。

少量であれば、Azure Portalのストレージ ブラウザーで十分です😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/d4c0e09e-5331-47e2-b5a5-24674e4cb5a0.png)


https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-portal#upload-a-block-blob

はい。楽勝ー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/40847b44-795a-43bd-a3e5-72814c00c332.png)

# 2. Azure OpenAI Service の作成

ベクトル化。つまり、Embedding 用です。Azure AI Search から参照させます。

text-embedding-3-small をデプロイします。

ご参考

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/create-resource?pivots=web-portal


Azure OpenAI Serviceでのモデルのデプロイは、Azure AI Foundry | Azure OpenAI Service の画面から行えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/c68d43c7-a58a-4a55-90f6-beb3d7041ad6.png)

デフォルトのままですと、検索エンジンでのIndex作成時に、一度に大量にAPI呼び出しをする可能性があります。
**1分あたりのトークン数レート制限**を少し多めにしておきます。この数字は、課金には影響しませんが、自分のSubscription全体での上限があるので、大きくし過ぎると、別のデプロイ時に、そちらは少ししか処理できない可能性があります。
並列実行の観点で、どうするか考えたいですね😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/848beb8e-08fa-4010-a4d1-9e18ce9e2b9a.png)


# 3. Azure AI Search の作成

さて。いよいよコアのSearchです。

ここではSKUを**無料**の**Free**にします。

- 無償版はコンピューター能力や機能に制限があります。ベクトル化を含むRAG検証で、大量のデータからの検索時などには適さない場合がある点は十二分に留意しましょう。
- **1つのSubscription**で、FreeのSKUは**1つだけ**作成できます。
- 無償版の Azure AI Searchから、Azure Storage アカウントへの認証は、**キー認証のみ**。ロールベースのアクセスはサポートしていない。

https://learn.microsoft.com/ja-jp/azure/search/search-sku-tier#tier-descriptions


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/0c31a1de-3984-4d53-b4cc-938adfaae7b4.png)


こちらを適時参照ください。

https://learn.microsoft.com/ja-jp/azure/search/search-get-started-portal-import-vectors?tabs=sample-data-storage%2Cmodel-aoai%2Cconnect-data-storage

## 3.1. Azure AI Search のアカウント作成

さて、ここから Azure AI Searchを使って、検索用のIndexを作成します。

まず、Entra IDにAzure AI Searchのアカウントを作成します。
デフォルトですと作成されていません。

Azure AI Searchの画面に移動します。

- [ID]に移動します
- [システム割り当て済み]が、オフになっています。「オン」にして[保存]を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/94bb6582-f8b7-409f-b337-eca134611861.png)

作成が終わると以下の画面の様にオブジェクト(プリンシパル)IDが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/8d5fad3c-983a-4384-a02a-0b5065463861.png)

- 無償版のSKUから、Azure Storageアカウントにアクセスするために、キー認証を有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/b0a03e35-1583-4128-aa71-eee7e49ceda0.png)


## 3.2. Azure AI SearchにAzure Storageアカウントのアクセス権を設定

Azure Storage Accountの画面に移動します。

- [アクセス制御]に移動します。
    - ここで、ユーザーや各種Azureのリソースなどのアクセス権設定を行います。この画面は、Subscriptionやリソースグループなど、Azureのリソースの各層で同じ操作で設定ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/f82c8b41-6a33-48e9-acba-78f68ee52535.png)

- [ロール]の検索用のテキストボックスを使って、**ストレージ BLOB データ閲覧者** を検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/810b4ed5-d6d1-4658-997e-36083f96cdf6.png)

- [メンバー]の画面でAzure AI Searchを検索します
- [マネージドID]を選択
- 画面右側に出てくる[マネージドIDの選択]の[マネージドID]で「Search Services」を選択します。
- 先ほど作成した Azure AI Search が見つかります。サービス名とアカウント名が同じになります。これを**選択**します。選択すると、下の[選択したメンバー]に移動します。
- [選択]ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/fb8b09ab-1abe-49b9-85da-e9a05292c66d.png)

- [レビューと割り当て]を押して、アクセス権を設定します。

## 3.2. インデックス作成

Azure AI SearchのPortal画面上から、Indexerの設定を行います。

こちらのドキュメントを適時参考にしてください。

クイックスタート: Azure portal を使用してテキストと画像をベクトル化する:

https://learn.microsoft.com/ja-jp/azure/search/search-get-started-portal-import-vectors?tabs=sample-data-storage%2Cmodel-aoai%2Cconnect-data-storage

- Azure Storage 作成時に**階層型名前空間**の設定が、オンなのかオフなのかで、Azure Blob Storage なのか、Azure Data Lake Storage Gen2なのかが変わります。注意してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/2ffe85e2-7e8c-490e-bab3-8b7220696d10.png)

Embedding (ベクトル化) のAPI設定で、先にデプロイしたAzure OpenAI ServiceのEmbeddingモデルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/08e6fa0b-fe1e-47a7-8e62-f148fc54aaa7.png)

今回は画像を扱いません。
その後はデフォルト設定のまま進めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/4914b038-76c3-4139-9ff5-b6d2b0983291.png)

数分待つと、Indexingが終了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/1e121434-f1bb-47cf-9c72-180234e85b6d.png)


インデックスのジョブが正しく終了したかを確認します。

Azure AI Searchの[インデックサー]の画面から、成功したドキュメントなどを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/de47ad7a-1a04-4f43-8994-437f878b3835.png)

大丈夫そうであれば、実際に検索を試してみましょう。

[インデックス]から、作成したIndexを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/ccdd0a71-1571-4dbb-84c6-0e9c33e4ab54.png)

早速「文章」で検索をしてみます。
鎌倉武将に関連するものであれば、なんでもいいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/c6510d6c-02dd-4a30-a9ba-4eb29ff029c7.png)

:::note info
RAG 実施時の大事な点
- 本来は、ここで検索の精度の確認を行います。上位n件に何がヒットしているかを確認します
- デフォルトで取得できているデータ項目、フィールドに注目してください。
    - chunk に取得できたデータの内容が入っています。そうなんです、デフォルトで元ファイルを分割しています
    - title にファイル名が入っています。Indexerは、特定のフォルダー以下を検索していますからね。特定ということは**固定**のURLになるわけで。このtitleと合わせて、データソースになります
:::

# 4. Azure AI Foundry の作成

いよいよ Azure AI Foundry の作成を行います。

諸々関連リソースも作成されるため、 ai.azure.com から行うのがおススメです。

画面右上の [プロジェクトの作成] から行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/76939226-2a63-4cf0-8c78-f43c41eea765.png)

プロジェクトの作成画面です。ここでは、これまで作成してきたリソースと同じリソースグループに保存をしたいので[カスタマイズ]を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/9029a4f0-8bc7-4fe8-9cae-a40ddb8b4426.png)

実は、ここでは既存のリソースを全て選択します。新規に何かの作成を行いません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/9e5aed77-399b-4e32-ae4e-e45415540d3e.png)

いろんな関連リソースの作成状況を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/7d2685e0-5eaa-4c9f-b41e-0fd8a724ac5b.png)

3-5分くらいで出来ました!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/fc432c20-7b97-4bff-8728-49cfddcfb289.png)

## 4.1. Modelのデプロイ

Chat の PlayGround で利用するModelをデプロイします。

ここでは、GPT-4.1 を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/e7d4da1e-f726-4b90-932f-ec3754f45c96.png)

## 4.2. Index の追加

Azure AI Foundryの画面の左側のメニューからIndexの追加画面に移動します。

- [データとインデックス] - [インデックス]
    - [新しいインデックス]


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/be3fbbab-8d60-461f-a357-1a778d1a8bb6.png)

ベクトルインデックスを作成するから[Azure AI 検索]を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/9814374c-423a-42d9-a591-7e1cabd030e6.png)

外部インデックスの画面で、先に作成した Azure AI Service と Index を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/a58a90b4-4c0f-434e-8db5-023ce6f34097.png)

ストアがベクトルで保存されています。そのため、[検索設定の設定]画面で、Azure OpenAI ServiceのEmbeddingモデルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/fe1326cc-ae21-452f-9520-22ee19f7bb7d.png)

ベクターインデックスの画面です。
ちょっと混乱しますね。先にIndexは作成済みなんですがね..

ベクターインデックス名は、適時変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/3f4e2a0f-cfb2-4a79-9d65-9c78f60407d1.png)

作成できました!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/e75da7ea-36ac-4790-9df9-f2481968c4ef.png)

# 5. Azure AI Foundry の PlayGround で動作確認

これで PlayGround の画面で、インデックスが参照できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/7bc2adde-9632-4802-af09-58527fa60d8b.png)

先に Azure AI Search で作成したインデックスではなく、Azure AI Foundryで作成したインデックスですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/8692c687-11df-4faf-8f9d-e599fc6c0ef2.png)


PlayGournd では、デフォルトの**出力トークン数**が**800**と大変少ないです!
ここは、max にしておきましょう😊


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/2fded874-c2d3-4eb1-89b1-88757519c89f.png)

Prompt:

```cmd
源頼朝が行ったことについて要点をリストアップしてください。
```

相当適当です...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/fb69766a-c93f-4994-8b8f-3ff42f198efc.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/7b265a1f-e996-4647-9115-aeb68ca2ea47.png)

動作の確認ができるかと思います。
チャンクしたファイルが見えますね。

# まとめ

こちらが今回作成したリソースたちです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/586b4dd3-06b7-4879-939e-abd3399630b4.png)

特に気になる Azure AI Search のIndexは、1つだけですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/02cfcff1-f0f6-440b-85a2-ef42150390e4.png)

Azure AI FoundryのPlayGroundから見えているIndexについては、参照されているBlobに格納されているファイルを見てみても。事前作成したIndexへのリンクが見えているのみです。

数日放置してみましたが、特に課金もされず、モニター上も確認ができず、でした。

この辺りは追加の調査が必要とは思いますが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/8c7bc53b-f9e5-4bc6-aa4c-1768e287f035.png)

これで、初期のRAGの挙動など、楽しんでください!!!!