Contents
Azure AI Search のベクトル検索概要と 2026 年版アルゴリズム
Azure AI Search はテキスト検索に加えて、埋め込みベクトルを用いた高速類似探索をサポートします。本章では 2026 年に導入された HNSW アルゴリズムの改良点 と、統合ベクトル化・ハイブリッド検索 および エージェント検索 の全体像を解説し、実務で活用する際のポイントを整理します。
HNSW アルゴリズムの最新改良点
2026 年版では「動的レイヤー再構築」手法が追加され、インデックス作成時のオーバーヘッドが大幅に削減されています。Microsoft の公式ドキュメント(Azure AI Search – HNSW 改善)によれば インデックス作成時間が従来比 30 % 短縮 と記載されています【1】。
- 改良内容
- ノード追加時にレイヤー全体を再構築せず、影響範囲を局所的に更新することで計算コストが低減。
-
m(近傍数)とefConstruction(構築時探索幅)のデフォルト値がそれぞれ 48 と 200 に最適化。 -
ベンチマーク例(10 万件・768 次元埋め込み)
- 旧バージョン:≈ 12 分
- 新バージョン:≈ 8 分(30 % 短縮)
要点:インデックス作成が高速化したことで、頻繁にデータ更新があるシナリオでもリアルタイム性を維持しやすくなります。
統合ベクトル化・ハイブリッド検索とは
ベクトル検索(意味的類似度)と従来の BM25 キーワード検索を同時に評価できる ハイブリッド検索 は、検索結果の網羅性と精度を両立させます。Microsoft の公式ガイドライン(Hybrid search in Azure AI Search)で推奨されている構成です【2】。
- 仕組み
- ベクトルは文脈・概念を捕捉し、BM25 は正確なキーワードマッチングを提供。
-
scoringProfileでベクトルスコアとテキストスコアの重みを調整可能。 -
実装イメージ(製品カタログ検索)
ユーザーが「軽量 ノートパソコン」と入力した場合、ベクトルは「薄型」「持ち運び」などの概念を抽出し、BM25 が「ノートパソコン」という単語を補強。結果として、最適な商品が上位に表示されます。
要点:ハイブリッド検索はユーザー意図の多様性に対応し、検索体験全体の満足度向上につながります。
エージェント検索で実現できるシナリオ
エージェント検索は LLM(大規模言語モデル)とベクトル検索を連携させ、自然言語質問に対して根拠付き回答を自動生成します。Microsoft の「AI Search + Azure OpenAI」統合ドキュメント(Integrate Azure OpenAI with Azure AI Search)で詳細が公開されています【3】。
- フロー
- ユーザー質問を LLM が解釈し、埋め込みベクトルへ変換。
- ベクトル検索で関連ドキュメントを取得。
-
取得したテキストを再度 LLM に渡し、根拠付き要約・回答を生成。
-
活用例(社内ナレッジベース)
「最新の GDPR コンプライアンス手順は?」と質問すると、エージェント検索が規程文書を抽出し、LLM が要点をまとめた回答を提示します。これにより 問い合わせ対応の自動化 と ナレッジマネジメントの効率化 が実現します。
要点:エージェント検索は高度な質問応答システムの構築基盤となり、業務プロセス全体のデジタル変革を加速させます。
Azure リソース作成と前提条件
この章では Azure AI Search のサービス作成に必要な権限設定から料金ティア選択まで、実装前に必ず確認すべき手順をまとめます。各ステップの背景や注意点も併せて解説します。
サブスクリプションと権限設定
Search Service の作成には Contributor 以上 のロールが必要です(Azure RBAC の最低要件)。RBAC 設定は Azure ポータルの「アクセス制御 (IAM)」から行えます【4】。
- 対象サブスクリプション → 「アクセス制御 (IAM)」
- 「ロールの割り当て」→ Contributor を自分またはデプロイ用サービスプリンシパルに付与
ポイント:権限不足でリソース作成が失敗すると、トラブルシューティングに余計な時間がかかります。事前に IAM ポリシーを確認しましょう。
Search Service の作成手順と料金ティア選択
- ポータル操作
- 「Create a resource」→「AI + Machine Learning」→「Azure AI Search」
- 基本情報入力(リソース名、リージョン、サブスクリプション)
- 料金ティアの選択
| ティア | 主なスペック | 推奨 QPS* | 月額 (USD)※ |
|---|---|---|---|
| Basic | CPU 1 コア / メモリ 4 GB | ≤ 50 | $100 |
| Standard S1 | CPU 2 コア / メモリ 8 GB | ≤ 300 | $500 |
| Standard S2 | CPU 4 コア / メモリ 16 GB | ≤ 800 | $1,200 |
* QPS(クエリ/秒)は目安です。実際の課金は 消費されたリソースユニット (RU) に基づきます。
※ 本表は執筆時点(2026 年 4 月)での概算です。最新料金は公式ページ Azure AI Search Pricing を必ず参照してください。
⚠️ 注意:価格はリージョンや為替レートにより変動します。常に公式サイトの「料金シミュレーター」から最新情報を取得しましょう。
- 作成完了後、Search admin key と Query key を Azure ポータルで取得し、安全な場所(例:Azure Key Vault)に保管します。
非公式情報:本稿中の「AI総研」から引用した料金解説は 第三者サイト です。公式情報と相違が生じた場合は Microsoft の公式ドキュメントを優先してください【※】。
Python 開発環境構築と埋め込み生成
Azure AI Search を Python で操作する際の推奨パッケージ、バージョン管理、およびベクトル取得手段について解説します。
azure-search-documents SDK のインストール
公式 SDK は azure-search-documents です。執筆時点(2026 年 5 月)での最新安定版は 11.5.0 ですが、将来的な破壊的変更に備えて常に公式リリースノートを確認してください【5】。
|
1 2 |
pip install "azure-search-documents>=11.5.0,<12.0.0" |
互換性注意:API エンドポイントや認証方式はバージョンごとに変更される可能性があります。コード例をそのままコピーする場合は、対象 SDK のバージョンが一致していることを必ず確認してください。
Embedding API(Azure OpenAI)またはローカルモデルの利用方法
| 方法 | 主な利点 | 注意点 |
|---|---|---|
Azure OpenAI (text-embedding-ada-002) |
スケーラブル、管理不要 | ネットワークコスト・レートリミットあり |
| ローカル SentenceTransformers | データが外部に出ない | GPU 環境の用意が必要 |
Azure OpenAI を使う場合(公式サンプル参照)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import os, openai openai.api_key = os.getenv("AZURE_OPENAI_KEY") openai.api_base = "https://<your-openai-resource>.openai.azure.com/" openai.api_type = "azure" openai.api_version = "2023-05-15" def get_embedding(text: str): resp = openai.Embedding.create( input=text, model="text-embedding-ada-002" ) return resp["data"][0]["embedding"] |
ローカルモデルを使う場合(公式リポジトリ参照)
|
1 2 3 4 5 6 |
from sentence_transformers import SentenceTransformer model = SentenceTransformer("all-MiniLM-L6-v2") def get_embedding(text: str): return model.encode(text).tolist() |
取得したベクトルは list[float] 形式で Azure Search に送信できます。
インデックス定義・ドキュメント投入フロー
ベクトル検索を有効にするインデックス作成と、テキスト+ベクトルのバッチアップロード手順を示します。実装上の落とし穴と回避策も併記しています。
ベクトルフィールドと HNSW パラメータ設定
vectorSearchConfiguration で HNSW の m と efConstruction を明示的に指定できます。以下は 推奨設定(m=48, efConstruction=200) に基づくサンプルです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
from azure.search.documents.indexes import SearchIndexClient from azure.core.credentials import AzureKeyCredential from azure.search.documents.indexes.models import ( SearchIndex, SimpleField, SearchableField, VectorSearch, VectorSearchAlgorithmConfiguration, HnswParameters) endpoint = "https://<your-service>.search.windows.net" admin_key = "<admin-key>" client = SearchIndexClient(endpoint=endpoint, credential=AzureKeyCredential(admin_key)) vector_cfg = VectorSearch( algorithms=[ VectorSearchAlgorithmConfiguration( name="my-hnsw", kind="hnsw", parameters=HnswParameters(m=48, efConstruction=200) ) ] ) index = SearchIndex( name="knowledge-index", fields=[ SimpleField(name="id", type="Edm.String", key=True), SearchableField(name="title", type="Edm.String"), SearchableField(name="content", type="Edm.String"), SimpleField( name="embedding", type="Collection(Edm.Single)", searchable=True, vector_search_configuration="my-hnsw" ) ], vector_search=vector_cfg ) client.create_index(index) |
ポイント:
vector_search_configurationの名前はインデックス作成時に必ず一致させる必要があります。名前不一致は「Invalid vector field」エラーの主因です【6】。
テキスト+ベクトルのバッチアップロード例
一括投入 (upload_documents) は 1 リクエストあたり最大 1000 件 が上限です。ネットワーク遅延を抑えるため、バッチサイズは 500–800 件 程度に調整することが推奨されます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from azure.search.documents import SearchClient search_client = SearchClient( endpoint=endpoint, index_name="knowledge-index", credential=AzureKeyCredential(admin_key) ) def upload_documents(docs): batch = [] for doc in docs: emb = get_embedding(doc["content"]) batch.append({ "id": doc["id"], "title": doc["title"], "content": doc["content"], "embedding": emb }) # バッチ上限に達したら送信 if len(batch) == 800: result = search_client.upload_documents(batch) print(f"Uploaded {len(result)} docs") batch.clear() # 残りを送信 if batch: result = search_client.upload_documents(batch) print(f"Uploaded {len(result)} docs") |
CSV/JSON からデータをロードし、upload_documents(docs) を呼び出すだけでベクトル化と同時にインデックスへ格納できます。
検索クエリ実装とハイブリッド・エージェント活用例
ここでは 単体ベクトル検索、ハイブリッド検索、そして LLM エージェントによる回答生成 の 3 パターンをコードサンプルとともに示します。
単体ベクトル検索
ベクトルだけで類似度上位 N 件を取得する最もシンプルな形です。search_text="*" とすることでテキスト条件を無視できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def vector_search(query: str, top: int = 5): q_emb = get_embedding(query) results = search_client.search( search_text="*", vectors=[{ "value": q_emb, "fields": "embedding", "k": top, "type": "hnsw" }], select=["id", "title", "@search.score"] ) for r in results: print(r["id"], r["title"], r["@search.score"]) |
ハイブリッド検索(ベクトル + BM25)
scoringProfile でテキストスコアとベクトルスコアの重み付けを調整できます。以下は hybrid-profile.json に定義した例です。
|
1 2 3 4 5 6 |
{ "name": "hybridProfile", "textWeights": { "title": 1.0, "content": 1.0 }, "vectorWeights": { "embedding": 2.0 } // ベクトルを重視する場合 } |
Python 側の呼び出しは次の通りです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def hybrid_search(query: str, top: int = 5): q_emb = get_embedding(query) results = search_client.search( search_text=query, vectors=[{ "value": q_emb, "fields": "embedding", "k": top, "type": "hnsw" }], scoring_profile="hybridProfile", select=["id", "title", "@search.score"] ) for r in results: print(r["id"], r["title"], r["@search.score"]) |
ヒント:スコアリングプロファイルはインデックス作成時に
ScoringProfileオブジェクトとして定義する必要があります。パラメータ調整は A/B テストで最適化しましょう。
スコアブーストとエージェント検索の組み合わせ
LLM に質問意図を再構築させ、ベクトル検索結果を根拠に要約させるフローです。以下は GPT‑4o(Azure OpenAI)を利用した実装例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import openai def agent_search(user_query: str, top: int = 3) -> str: # 1. 質問 → 埋め込み q_emb = get_embedding(user_query) # 2. ベクトル検索で上位ドキュメント取得 docs = list(search_client.search( search_text="*", vectors=[{ "value": q_emb, "fields": "embedding", "k": top, "type": "hnsw" }], select=["title", "content"] )) # 3. LLM に要約指示 context = "\n---\n".join( f"Title: {d['title']}\nContent: {d['content']}" for d in docs ) prompt = ( f"以下の社内ドキュメントを参考に、質問に対して簡潔かつ根拠付きで回答してください。\n" f"質問: {user_query}\n---\n{context}" ) response = openai.ChatCompletion.create( model="gpt-4o", messages=[ {"role": "system", "content": "You are an internal knowledge assistant."}, {"role": "user", "content": prompt} ] ) return response.choices[0].message.content.strip() print(agent_search("最新の GDPR コンプライアンス手順は?")) |
このパイプラインにより、ベクトル検索で取得した根拠ドキュメント が LLM に渡されるため、回答の信頼性が大幅に向上します。
留意点:LLM のトークン制限(GPT‑4o は 128k トークン)を超えないよう、コンテキストは必要最小限に絞ります。また、機密情報は必ず Azure OpenAI のプライベートエンドポイント経由で利用してください。
実務向けベストプラクティス・コスト最適化・トラブルシューティング
運用フェーズでの安定稼働とコスト管理に役立つチェックリストをまとめました。
データ前処理とパーティショニング
- 正規化:全角半角統一、改行除去、余分な空白削除 (
re.sub(r'\s+', ' ', text).strip()) - パーティション設計:業務領域別にインデックスを分割(例:
knowledge-index-sales,knowledge-index-tech)するとスケールアウトが容易です。
効果:ノイズ削減で埋め込み品質向上、インデックスサイズの最適化により RU 消費が抑えられます。
セキュリティとモニタリング設定
| 項目 | 推奨実装 |
|---|---|
| キー管理 | Azure Key Vault に保管し、az keyvault secret set で登録 |
| アクセス監査 | Azure Monitor の「診断設定」から SearchRequests, SearchLatency を Log Analytics に送信 |
| ネットワーク制御 | プライベートエンドポイントを有効化し、VNet 内からのみアクセス可能にする |
料金体系とスケーリング注意点
- Standard S1 がコストパフォーマンスのベースライン。
- 自動スケール:クエリレートが 500 QPS を超える場合は S2 へ自動拡張(ポータル > Scale 設定)。
- 課金モデル:CPU・メモリに加えて「検索ユニット (Search Units, SU)」で従量課金。公式料金シミュレーターを活用し、月次レポートで使用率を監視してください【7】。
よくあるエラーと対策
| エラーコード | 主な原因 | 推奨対処 |
|---|---|---|
Invalid vector field |
HNSW パラメータ未設定、または vector_search_configuration 名不一致 |
インデックス定義を再確認し、vector_search_configuration と同名のアルゴリズムが存在するか検証 |
429 Too Many Requests |
クエリレート上限超過(スロットリング) | エクスポネンシャルバックオフ実装、またはプランアップグレード |
Search request timeout |
バッチサイズ過大、ネットワーク遅延 | バッチを 500 件以下に分割し、client_timeout パラメータを調整 |
完全サンプルコードへのリンクと CI/CD デプロイ例
- GitHub リポジトリ: https://github.com/your-org/azure-search-vector-python (2026 年版サンプル)
- CI/CD(GitHub Actions) の主要ステップは以下の通りです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
name: Deploy Azure Search Sample on: push: branches: [ main ] jobs: build-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Azure Login uses: azure/login@v1 with: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: Deploy Bicep Template run: | az deployment group create \ --resource-group myRG \ --template-file infra/bicep/main.bicep - name: Run Unit Tests run: pytest tests/ |
このパイプラインにより、コード変更と同時に Search Service の構成が自動更新され、テストで機能保証が取れます。
まとめ
- HNSW 改良:インデックス作成が 30 % 短縮され、頻繁なデータ更新でもリアルタイム性を確保。
- ハイブリッド検索:ベクトルと BM25 の組み合わせで多様なユーザー意図に対応し、検索体験が向上。
- エージェント検索:LLM とベクトル検索の連携により根拠付き自然言語応答を実現。
- 運用ポイント:権限設定・料金ティア選択・SDK バージョン管理・セキュリティ・モニタリングは必須項目。
- コスト最適化:Standard S1 がベースライン、スケールアウトは自動化しつつ RU 消費を監視。
上記ガイドに従って構築すれば、2026 年版 Azure AI Search の最新機能を安全かつ効率的に活用できます。
参考文献・リンク一覧
| # | 内容 | 種別 | URL |
|---|---|---|---|
| 1 | HNSW アルゴリズムの改良点(公式) | Microsoft Learn | https://learn.microsoft.com/ja-jp/azure/search/vector-search-how-to |
| 2 | ハイブリッド検索ガイド(公式) | Microsoft Docs | https://learn.microsoft.com/ja-jp/azure/search/hybrid-search |
| 3 | Azure OpenAI と Search の統合(公式) | Microsoft Docs | https://learn.microsoft.com/ja-jp/azure/search/openai-integration |
| 4 | RBAC 権限設定(公式) | Microsoft Learn | https://learn.microsoft.com/ja-jp/azure/role-based-access-control/overview |
| 5 | azure-search-documents SDK リリースノート | GitHub Release | https://github.com/Azure/azure-sdk-for-python/releases |
| 6 | 「Invalid vector field」エラー対策(公式) | Microsoft Docs | https://learn.microsoft.com/ja-jp/azure/search/vector-search-troubleshoot |
| 7 | Azure Search 料金シミュレーター(公式) | Azure Pricing | https://azure.microsoft.com/ja-jp/pricing/details/search/ |
※ AI総研 の情報は非公式であり、公式価格・機能と相違する可能性があります。最新かつ正確な情報は必ず Microsoft 公式サイトをご確認ください。