【Build 2025 速報】Azure AI Search が Agentic retrieval を実装しマネージド Agentic RAG が可能に ほか

Microsoft Build 2025 で Azure AI Search が **Agentic retrieval 機能を実装**し、エージェントが独自の検索戦略を計画・実行することで回答の精度を向上させます。従来のシングルショット検索（RAG）と比較して、エージェント検索は複雑な質問に対する回答の関連性を最大 40% 向上させる効果も出ています。Agentic retrieval 機能は自動でクエリを変換し、並列検索を実行し、エージェント向けに調整された結果、参照情報、クエリアクティビティログを提供します。

また、ADLS Gen2 において**ドキュメントレベルのアクセス権限管理**に対応しました！

# Build 2025 Updates🎉
- **Agentic retrieval (プレビュー)**
複雑なユーザークエリをサブクエリに分解し、それらを並列実行することで、Azure AI Search でインデックス付けされたドキュメントからグラウンディングデータを抽出します。
- **ドキュメントレベルのアクセス制御（プレビュー）**
Azure Data Lake Storage (ADLS) Gen2 の BLOB からインデックス内の検索可能なドキュメントにドキュメントレベルの権限をフローできるように。クエリでは、選択したデータソースのユーザー ID に基づいて結果をフィルターできるように。
- **マルチベクターサポート（プレビュー）**
単一のドキュメントフィールド内で複数の子ベクトルをインデックス化します。複雑なコレクションのネストされたフィールドでベクトル型を使用できるように。
- **セマンティックランキングによるプロファイルのスコアリング（プレビュー）**
セマンティック ランカーでは、新しいフィールド `@search.rerankerBoostedScore` が追加され、スコアリングプロファイルが使用できるように。
- **Azure Logic Apps 統合（プレビュー）**
Azure Logic Apps ワークフローを使用してコンテンツを取得する自動インデックス作成パイプラインを作成できるように。
- **マルチモーダル検索（プレビュー）**
テキストと画像を含むドキュメントを取り込み、理解し、取得することで、テキストクエリで複雑な画像に埋め込まれた関連情報を検索するなど、様々なモダリティを組み合わせた検索が可能に。データのインポートとベクトル化ウィザードの機能も強化。
- **GenAI プロンプトスキル（プレビュー）**
ユーザーが指定したプロンプトを使用して、LLM に接続し、情報を取得する新しいスキルが追加
- **ドキュメントレイアウトスキル（プレビュー）**
画像検索エクスペリエンスを向上させる画像オフセットメタデータをサポート
- **インデックスの「説明」のサポート（プレビュー）**
「説明」は、エージェントが説明を読み取ってクエリを実行するか、別のインデックスに移動するかどうかを判断するエージェントソリューションで役立ちます。


# Agentic retrieval (プレビュー)
すでに [Azure OpenAI Developers セミナー 2025](https://youtu.be/jHW6zcIzm7g?feature=shared&t=6016) で紹介した通り、Azure AI Search には Advanced RAG 機能がマネージドで実装されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/251f6141-4b27-413c-aa25-cab8963d1321.png)
<sup>Ignite 2024 Updates</sup>

今回の Build 2025 でさらに Agentic RAG に相当する機能が実装され、AI エージェントがチャット履歴を含む複雑なクエリーを分解し、クエリー計画を策定、必要に応じて並列でクエリを実行し、結果を統合します。

![AR_metrics_pipeline_Build25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/a2ecd7d0-58cb-4998-8696-083cc030521f.png)


## 利用条件
- セマンティック ランカーを提供するリージョンの Azure AI Search (Basic レベル以上)
- エージェント検索のインデックス基準を満たす検索インデックス。インデックスには `semantic` 設定に `defaultConfiguration` が必要。
- 対応モデル:
`gpt-4o`, `gpt-4o-mini`, `gpt-4.1`, `gpt-4.1-nano`, `gpt-4.1-mini`
- Python SDK: `pip install azure-search-documents==11.6.0b12`


## KnowledgeAgent の作成
検索インデックスに対して Azure OpenAI に展開した LLM をラップする検索エージェントを作成します。LLM は、エージェント型検索パイプラインにクエリを送信するために使用されます。

```python
from azure.search.documents.indexes.models import KnowledgeAgent, KnowledgeAgentAzureOpenAIModel, KnowledgeAgentTargetIndex, KnowledgeAgentRequestLimits, AzureOpenAIVectorizerParameters

agent = KnowledgeAgent(
    name=agent_name,
    models=[
        KnowledgeAgentAzureOpenAIModel(
            azure_open_ai_parameters=AzureOpenAIVectorizerParameters(
                resource_url=azure_openai_endpoint,
                deployment_name=azure_openai_gpt_deployment,
                model_name=azure_openai_gpt_model
            )
        )
    ],
    target_indexes=[
        KnowledgeAgentTargetIndex(
            index_name=index_name,
            default_reranker_threshold=2.5
        )
    ],
)

index_client.create_or_update_agent(agent)
print(f"Knowledge agent '{agent_name}' created or updated successfully")
```

## KnowledgeAgent の取得
```python
agent = index_client.get_agent(agent_name)
print(f"Knowledge agent '{agent_name}' retrieved successfully")
```

## KnowledgeAgent の一覧
```python
agent = index_client.list_agents()
for agent in agent:
    print(f"Knowledge agent '{agent.name}' ")
```

## 会話履歴を含むメッセージの作成
AI アプリ側の情報。
```python
instructions = """
日本の戦国時代の歴史の質問に回答できる中学校歴史教師エージェント。中学生にもわかるように説明してください。
ソースはJSON形式で、回答内に引用する必要があるref_idを含んでいます。
回答が分からない場合は「分かりません」と回答してください。
"""

messages = [
    {
        "role": "system",
        "content": instructions
    }
]
```

## Agentic retrieval を使用して結果を取得
検索インデックスから関連する情報を抽出するために検索パイプラインを実行します。検索リクエストに含まれるメッセージとパラメーターに基づいて、LLM は次のように処理します：

1. 会話履歴全体を分析し、根本的な情報ニーズを特定
1. 複合ユーザークエリを焦点を絞ったサブクエリに分解
1. 各サブクエリをインデックス内のテキストフィールドとベクトル埋め込みに対して同時に実行
    <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/e5b5c814-d593-4aca-a5e5-1d9a9fb1e613.png">
1. セマンティックランカーを使用して、すべてのサブクエリの結果を再ランク付け
    <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/dcd8d012-c4fe-4600-aa34-c739fe6c21ec.png">
    
1. 結果を単一の文字列に統合

```python
from azure.search.documents.agent import KnowledgeAgentRetrievalClient
from azure.search.documents.agent.models import KnowledgeAgentRetrievalRequest, KnowledgeAgentMessage, KnowledgeAgentMessageTextContent, KnowledgeAgentIndexParams

agent_client = KnowledgeAgentRetrievalClient(endpoint=endpoint, agent_name=agent_name, credential=credential)

messages.append({
    "role": "user",
    "content": """
なぜ源頼朝は鎌倉幕府を開いたのか、とか、北条氏は鎌倉幕府でどんな役割を果たした？
あと源さねともはどんな人物で実朝の政策で特に重要なのは何か
   """
})

retrieval_result = agent_client.knowledge_retrieval.retrieve(
    retrieval_request=KnowledgeAgentRetrievalRequest(
        messages=[KnowledgeAgentMessage(role=msg["role"], content=[KnowledgeAgentMessageTextContent(text=msg["content"])]) for msg in messages if msg["role"] != "system"],
        target_index_params=[KnowledgeAgentIndexParams(index_name=index_name, reranker_threshold=2.5)]
    )
)
messages.append({
    "role": "assistant",
    "content": retrieval_result.response[0].content[0].text
})
```

## レスポンスの取得
レスポンスは辞書型の配列を単一の文字列に変換した形で得られます。これは後段プロセスでそのまま LLM に投入しやすくするため。構造化するには `json.loads()` すれば良い。

```python
import textwrap
print("Response")
print(textwrap.fill(retrieval_result.response[0].content[0].text, width=120))
```

>Response
[{"ref_id":0,"title":"源頼朝-
29.txt","content":"頼朝の開いた武家政権は制度化され、次第に朝廷から政治の実権を奪い、後に幕府と名付けられ、王政復古(1868年)まで足掛け約680年間にわたって続くこととなる、..."},
>{"ref_id":1,"title":"大江広元-
1.txt","content":"建久10年（1199年）正月に頼朝が死去し、源頼家が2代将軍になると義盛は宿老として十三人の合議制に列した...

## 検索アクティビティの取得
アクティビティログを返します。LLMの入力トークン数と出力トークン数、サブクエリテキスト、クエリごとのヒット数、適用されたフィルター、実行タイミングなどが含まれます

```python
import json
print("Activity")
print(json.dumps([a.as_dict() for a in retrieval_result.activity], indent=2, ensure_ascii=False))
```

```json
[
  {
    "id": 0,
    "type": "ModelQueryPlanning",
    "input_tokens": 1277,
    "output_tokens": 622
  },
  {
    "id": 1,
    "type": "AzureSearchQuery",
    "target_index": "busho-ada-embedding-v3",
    "query": {
      "search": "なぜ源頼朝は鎌倉幕府を開いたのか"
    },
    "query_time": "2025-05-19T21:51:07.934Z",
    "count": 8,
    "elapsed_ms": 162
  },
  {
    "id": 2,
    "type": "AzureSearchQuery",
    "target_index": "busho-ada-embedding-v3",
    "query": {
      "search": "北条氏は鎌倉幕府でどんな役割を果たしたか"
    },
    "query_time": "2025-05-19T21:51:08.064Z",
    "count": 14,
    "elapsed_ms": 111
  },
  {
    "id": 3,
    "type": "AzureSearchQuery",
    "target_index": "busho-ada-embedding-v3",
    "query": {
      "search": "源実朝はどんな人物で実朝の政策で特に重要なのは何か"
    },
    "query_time": "2025-05-19T21:51:08.169Z",
    "count": 0,
    "elapsed_ms": 105
  },
  {
    "id": 4,
    "type": "AzureSearchSemanticRanker",
    "input_tokens": 94255
  }
]
```

Query Planner によってユーザーからの複雑なクエリーが分割され、スペルも修正されていることがわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/73582ab3-4849-4910-89c7-979ca547622f.png)

クエリプランニングに異なるモデルを用いた回答の関連性データ。左：各モデルが複数のサブクエリを含むプランをどれくらいの割合で生成するか、右：各モデルが生成するサブクエリの平均数。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/74613409-e218-47b6-b864-42fe82be1cff.png)

複雑なクエリ（Complex Query）ではどのモデルも高い割合で複数のサブクエリに分割する傾向がある。`gpt-4o-mini` や `gpt-4.1` は特に複雑なクエリでのサブクエリ展開力が高い。


## 検索結果の取得
```python
print("Results")
print(json.dumps([r.as_dict() for r in retrieval_result.references], indent=2, ensure_ascii=False))
```

```json
[
  {
    "type": "AzureSearchDoc",
    "id": "6",
    "activity_source": 1,
    "doc_key": "5rqQ6aC85pydLTMwLnR4dA=="
  },
  {
    "type": "AzureSearchDoc",
    "id": "4",
    "activity_source": 1,
    "doc_key": "5rqQ6aC85pydLTIxLnR4dA=="
  },
...
```

## 結果をLLMで要約
あとは自分で得られた結果を最終回答として LLM に送信します。

```python
response = client.responses.create(
    model=answer_model,
    input=messages
)

wrapped = textwrap.fill(response.output_text, width=100)
print(wrapped)
```

## エージェント検索用のインデックスを定義
エージェントは以下の要素も使用してクエリを作成するため、Agentic retrieval のためのインデックス設計が今後必要となります。

- `scoringProfile` `defaultScoringProfile` : 関連性を高めるため
- `synonymMaps`: 専門用語や業界用語
- `analyzers`: 言語のルールやパターン（空白の保持や特殊文字など）

https://learn.microsoft.com/en-us/azure/search/search-agentic-retrieval-how-to-index

### 公式サンプルコード
https://github.com/Azure-Samples/azure-search-python-samples/blob/main/Quickstart-Agentic-Retrieval/quickstart-agentic-retrieval.ipynb


# ドキュメントレベルのアクセス制御（プレビュー）
これまで、Azure AI Search はフィルターによるセキュリティトリミングによってドキュメントをユーザーごとに出し分けるというアプローチを提供してきました。そのため、Microsoft Entra ID との連携部分は独自に開発する必要がありました。今回のアップデートで POSIX ライクな ACL 権限をネイティブ サポートしたことにより、Microsoft Entra ID を通じて ADLS Gen2 アクセス制御モデルは Azure ロールベース アクセス制御 (Azure RBAC) と POSIX ライクなアクセス制御リスト (ACL) の両方がサポートされます。最新のプレビュー API を使用する Azure AI Search では、これらの権限を検索インデックスとクエリに反映できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/29528c70-9eeb-4fe7-9419-1645919360d8.png)

## インデックス作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/2874253f-6129-4a94-9fca-7afe85c6df1c.png)

## ドキュメントアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/d3056c2b-fd2e-498e-8e5b-10a46f1ff73c.png)

## クエリー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/c46bb876-4d2b-4c24-97ac-288eeadf727f.png)






### ACL サンプルコード
https://github.com/Azure-Samples/azure-search-python-samples/blob/main/Quickstart-Document-Permissions-Pull-API/document-permissions-pull-api.ipynb

https://learn.microsoft.com/en-us/azure/search/search-document-level-access-overview


## Microsoft Purview 情報保護の秘密度ラベル Private Preview 開始

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/a1f5a6d3-6e1a-4d5f-a1c4-da3ace2aee5c.png)

### Microsoft Purview Sensitivity Labels Preview Request
http://aka.ms/aisearch-senslabels





# マルチベクターサポート（プレビュー）
Azure AI Search のマルチベクトルフィールドサポート機能により、単一のドキュメントフィールド内で複数の子ベクトルをインデックス化できます。これまで、`Collection(Edm.Single)`ベクトル型は最上位フィールドでのみ使用できました。マルチベクターフィールドのサポート導入により、複雑なコレクションのネストされたフィールドでもベクター型を使用できるようになり、複数のベクターを単一のドキュメントに関連付けることが可能になります。

1つのドキュメントには、すべての複合コレクションフィールドを合わせて最大100個のベクターを含めることができます。ベクターフィールドは1レベルまでしかネストできません。

```json
 {
      "name": "descriptionEmbedding",
      "type": "Collection(Edm.Single)",
      "dimensions": 3,
      "searchable": true,
      "retrievable": true,
      "vectorSearchProfile": "hnsw"
    },
    {
      "name": "scenes",
      "type": "Collection(Edm.ComplexType)",
      "fields": [
        {
          "name": "embedding",
          "type": "Collection(Edm.Single)",
          "dimensions": 3,
          "searchable": true,
          "retrievable": true,
          "vectorSearchProfile": "hnsw"
        },
```

https://learn.microsoft.com/en-us/azure/search/vector-search-multi-vector-fields


# セマンティックランキングによるプロファイルのスコアリング（プレビュー）
Azure AI Search で、スコアリング プロファイルとセマンティック ランカーの統合が可能になりました。セマンティック ランカーに新しいフィールド `@search.rerankerBoostedScore` が追加され、スコアリングプロファイルを再ランキング レベルで直接適用できるようになり、ブーストが考慮されるようになります。

```json
{
  "value": [
    {
      "@search.score": 0.63,
      "@search.rerankerScore": 2.98,
      "@search.rerankerBoostedScore": 7.68,
      "content": "boosted content 2"
    },
```

https://learn.microsoft.com/en-us/azure/search/semantic-how-to-enable-scoring-profiles

# Azure Logic Apps 統合（プレビュー）
Azure AI Search でデータのインポートとベクター化ウィザードを使用してワークフローを作成し、Azure Logic Apps で他のワークフローと並行して管理できます。ウィザードは、AI Search でインデックスを作成するためにソースからコンテンツを取得（取り込み）するワークフロー テンプレートに従って動作します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/dc9ee314-29f5-4008-b9dc-fd39154398db.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/d2a6717b-3ab4-4e52-abf7-985081bddac5.png)



# マルチモーダル検索（プレビュー）
Azure AI Search は、Azure ポータルのガイド付きエクスペリエンスを通じて、マルチモーダル パイプラインの構築を簡素化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/28dca97c-3601-4d68-a4aa-4bafcec9b533.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/2cb3b8dc-c498-4e80-9c00-db6080d5d86c.png)

また、マルチモーダル RAG 機能に特化した Chat with Your Data サンプルを公開しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/d74b6723-7203-4d24-accb-27bee86b213c.png)

https://github.com/Azure-Samples/azure-ai-search-multimodal-sample

ちなみに、**例のサンプルコード**も Agentic retrieval に[対応](https://github.com/Azure-Samples/azure-search-openai-demo/pull/2537)しました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/67ba1f88-9ddc-432f-bdc8-0e2b7ee5faf7.png)

https://github.com/Azure-Samples/azure-search-openai-demo


https://learn.microsoft.com/en-us/azure/search/multimodal-search-overview

# GenAI プロンプトスキル（プレビュー）
GenAI （Generative AI）プロンプトスキルは、Azure AI Foundry または Azure OpenAI Service にデプロイされた LLM に対してチャット完了リクエストを実行します。テキストのみ、画像、またはテキストと画像を組み合わせた入力から、画像の言語化、要約、変換、エンリッチメント、または構造化データの抽出を行います。

```json
{
  "@odata.type": "#Microsoft.Skills.Custom.ChatCompletionSkill",
  "name": "Image Describer",
  "context": "/document/normalized_images/*",
  "inputs": [
    { "name": "image", "source": "/document/normalized_images/*/data" },
    { "name": "imageDetail", "source": "=high" },
    { "name": "systemMessage", "source": "='You are a useful AI assistant.'" },
    { "name": "userMessage", "source": "='Describe this image:'" }
  ],
  "outputs": [ { "name": "response" } ],
  "uri": "https://demo.openai.azure.com/openai/deployments/gpt-4o/chat/completions",
  "authIdentity": "11111111-2222-3333-4444-555555555555",
  "responseFormat": { "type": "text" }
}
```

https://learn.microsoft.com/en-us/azure/search/cognitive-search-skill-genai-prompt

# ドキュメントレイアウトスキル（プレビュー）
ドキュメントレイアウトスキルは、ドキュメントを分析し、関心領域とその相互関係を抽出して、ドキュメントの構文表現を Markdown 形式またはテキスト形式で生成します。このスキルは、[Azure AI Document Intelligence](https://azure.microsoft.com/ja-jp/products/ai-services/ai-document-intelligence)で提供されるドキュメントインテリジェンスレイアウトモデルを使用します。

https://learn.microsoft.com/en-us/azure/search/cognitive-search-skill-document-intelligence-layout

# Azure AI Foundry Agent Service Updates
https://qiita.com/nohanaga/items/7c4d29cc10da29ecae9f

# 参考
https://news.microsoft.com/build-2025-book-of-news/ja/

https://techcommunity.microsoft.com/blog/azure-ai-services-blog/introducing-agentic-retrieval-in-azure-ai-search/4414677