メモ
現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、Microsoft Azure プレビューの追加使用条件に関するページをご覧ください。
テキスト データのチャンキング戦略は、RAG 応答とパフォーマンスを最適化する上で重要な役割を果たします。 現在プレビュー段階にある新しいドキュメント レイアウト スキルを使用すると、ドキュメント構造に基づくコンテンツのチャンク化、見出しの取り込み、段落や文などのセマンティック的な一貫性に基づくコンテンツ本文のチャンク化を行うことができます。 チャンクは個別に処理されます。 LLM は複数のチャンクで動作するため、それらのチャンクの品質が高く、セマンティック的に一貫性がある場合は、クエリの全体的な関連性が向上します。
ドキュメント レイアウト スキルは、Document Intelligence 内でレイアウト モデルを呼び出します。 このモデルは、Markdown 構文 (見出しとコンテンツ) を使用して JSON のコンテンツ構造を明確にし、見出しのフィールドと、Azure AI Search の検索インデックスに格納されたコンテンツを持ちます。 ドキュメント レイアウト スキルから生成される検索可能なコンテンツはプレーンテキストですが、垂直統合を適用して、画像を含む、ソース ドキュメント内の任意のフィールドの埋め込みを生成できます。
この記事では、次のことについて説明します:
- ドキュメント レイアウト スキルを使用してドキュメント構造を認識する
- テキスト分割スキルを使用して、各 Markdown セクションにチャンク サイズを制限する
- 各チャンクの埋め込みを生成する
- インデックス プロジェクションを使用して、埋め込みを検索インデックス内のフィールドにマップする
この記事では、例示のために、Azure Blob Storage にアップロードされたサンプル医療保険 PDF を使用し、データのインポートとベクトル化ウィザードを使用してインデックスを作成します。
前提条件
出力を受け入れるインデックスを含むインデクサーベースのインデックス作成パイプライン。 インデックスには、見出しとコンテンツを受け取るためのフィールドが必要です。
一対多のインデックス作成用のインデックス プロジェクション。
分割したいテキスト コンテンツを持つ、サポートされているデータ ソース。
次の 2 つのスキルを持つスキルセット:
段落の境界に基づいてドキュメントを分割するドキュメント レイアウト スキル。 このスキルにはリージョンの要件があります。 Azure AI マルチサービス リソースは、AI エンリッチメントを使用した Azure AI Search と同じリージョンに存在する必要があります。
ベクター埋め込みを生成する Azure OpenAI Embedding スキル。 このスキル にはリージョンの要件はありません 。
データ ファイルを準備する
生の入力はサポートされているデータ ソース内にある必要があり、ファイルはドキュメント レイアウト スキルがサポートする形式である必要があります。
サポートされているファイル形式は、PDF、JPEG、JPG、PNG、BMP、TIFF、DOCX、XLSX、PPTX、HTML です。
サポートされるインデクサーは、サポートされているファイル形式を処理できる任意のインデクサーです。 これらのインデックスには、BLOB インデクサー、OneLake インデクサー、ファイル インデクサーが含まれます。
この機能のポータル エクスペリエンスでサポートされているリージョンは、米国東部、西ヨーロッパ、米国中北部です。 スキルセットをプログラムで設定する場合は、Azure AI Search の AI エンリッチメント機能も提供する任意のドキュメント インテリジェンス リージョンを使用できます。 詳細については、「リージョン別の利用可能な製品」を参照してください。
Azure portal、REST API、または Azure SDK パッケージを使って、データ ソースを作成できます。
ヒント
正常性プラン PDF サンプル ファイルをサポートされているデータ ソースにアップロードして、独自の検索サービスでドキュメント レイアウト スキルと構造対応のチャンキングを試します。 データのインポートとベクター化ウィザードは、このスキルを試す際にコードを使わない簡単なアプローチです。 構造体対応のチャンキングを使うには、既定の解析モードを必ず選んでください。 それ以外の場合は、 Markdown 解析モード が使用されます。
一対多のインデックス作成用のインデックスを作成する
チャンクを中心に設計された 1 つの検索ドキュメントのペイロードの例を次に示します。 チャンクを操作するときは常に、チャンク フィールドと、チャンクの発生元を識別する親フィールドが必要です。 この例では、親フィールドは text_parent_id です。 子フィールドは、Markdown セクションのベクトルおよび非ベクトル チャンクです。
ドキュメント レイアウト スキルは、見出しとコンテンツを出力します。 この例では、スキルによって検出されたとおり、header_1
から header_3
にドキュメントの見出しが格納されます。 段落などのその他のコンテンツは、chunk
に格納されます。 text_vector
フィールドは、チャンク フィールド コンテンツのベクトル表現です。
Azure portal、REST API、または Azure SDK の データのインポートとベクター化ウィザード を使用して、 インデックスを作成できます。 次のインデックスは、ウィザードが既定で作成するものによく似ています。 画像のベクトル化を追加すると、フィールドが増える可能性があります。
ウィザードを使用していない場合は、スキルセットを作成するかインデクサーを実行する前に、検索サービスにインデックスが存在している必要があります。
{
"name": "my_consolidated_index",
"fields": [
{
"name": "chunk_id",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": true,
"facetable": false,
"key": true,
"analyzer": "keyword"
},
{
"name": "text_parent_id",
"type": "Edm.String",
"searchable": false,
"filterable": true,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false
},
{
"name": "chunk",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false
},
{
"name": "title",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false
},
{
"name": "header_1",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false
},
{
"name": "header_2",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false
},
{
"name": "header_3",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false
},
{
"name": "text_vector",
"type": "Collection(Edm.Single)",
"searchable": true,
"filterable": false,
"retrievable": true,
"stored": true,
"sortable": false,
"facetable": false,
"key": false,
"dimensions": 1536,
"stored": false,
"vectorSearchProfile": "profile"
}
],
"vectorSearch": {
"profiles": [
{
"name": "profile",
"algorithm": "algorithm"
}
],
"algorithms": [
{
"name": "algorithm",
"kind": "hnsw"
}
]
}
}
構造対応のチャンキングとベクトル化のためのスキル セットを定義する
ドキュメント レイアウト スキルはプレビュー段階であるため、このステップでは Create Skillset 2024-11-01-preview REST API を使う必要があります。 Azure Portal を使用することもできます。
このセクションでは、個々のマークダウン セクション、チャンク、およびそれらの同等のベクトルを検索インデックス内のフィールドとして投影するスキルセット定義の例を示します。 ドキュメント レイアウト スキルを使用して、見出しを検出し、ソース ドキュメント内のセマンティック的に一貫性のある段落と文に基づいてコンテンツ フィールドを設定します。 テキスト分割スキルを使用して、Markdown コンテンツをチャンクに分割します。 Azure OpenAI Embedding スキルを使用して、チャンクやその他の埋め込みを行うフィールドをベクトル化します。
スキルだけでなく、スキルセットには indexProjections
と cognitiveServices
が含まれています。
indexProjections
は、チャンク化されたドキュメントを含むインデックスに使用されます。 プロジェクションでは、親子コンテンツを検索インデックスのフィールドにマップして一対多のインデックスを作成する方法を指定します。 詳細については、インデックス プロジェクションの定義に関する記事を参照してください。cognitiveServices
は、課金目的で Azure AI サービスのマルチサービス アカウントをアタッチします (ドキュメント レイアウト スキルは Standard 価格で利用できます)。
POST {endpoint}/skillsets?api-version=2024-11-01-preview
{
"name": "my_skillset",
"description": "A skillset for structure-aware chunking and vectorization with an index projection around markdown section",
"skills": [
{
"@odata.type": "#Microsoft.Skills.Util.DocumentIntelligenceLayoutSkill",
"name": "my_document_intelligence_layout_skill",
"context": "/document",
"outputMode": "oneToMany",
"inputs": [
{
"name": "file_data",
"source": "/document/file_data"
}
],
"outputs": [
{
"name": "markdown_document",
"targetName": "markdownDocument"
}
],
"markdownHeaderDepth": "h3"
},
{
"@odata.type": "#Microsoft.Skills.Text.SplitSkill",
"name": "my_markdown_section_split_skill",
"description": "A skill that splits text into chunks",
"context": "/document/markdownDocument/*",
"inputs": [
{
"name": "text",
"source": "/document/markdownDocument/*/content",
"inputs": []
}
],
"outputs": [
{
"name": "textItems",
"targetName": "pages"
}
],
"defaultLanguageCode": "en",
"textSplitMode": "pages",
"maximumPageLength": 2000,
"pageOverlapLength": 500,
"unit": "characters"
},
{
"@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill",
"name": "my_azure_openai_embedding_skill",
"context": "/document/markdownDocument/*/pages/*",
"inputs": [
{
"name": "text",
"source": "/document/markdownDocument/*/pages/*",
"inputs": []
}
],
"outputs": [
{
"name": "embedding",
"targetName": "text_vector"
}
],
"resourceUri": "https://<subdomain>.openai.azure.com",
"deploymentId": "text-embedding-3-small",
"apiKey": "<Azure OpenAI api key>",
"modelName": "text-embedding-3-small"
}
],
"cognitiveServices": {
"@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey",
"key": "<Cognitive Services api key>"
},
"indexProjections": {
"selectors": [
{
"targetIndexName": "my_consolidated_index",
"parentKeyFieldName": "text_parent_id",
"sourceContext": "/document/markdownDocument/*/pages/*",
"mappings": [
{
"name": "text_vector",
"source": "/document/markdownDocument/*/pages/*/text_vector"
},
{
"name": "chunk",
"source": "/document/markdownDocument/*/pages/*"
},
{
"name": "title",
"source": "/document/title"
},
{
"name": "header_1",
"source": "/document/markdownDocument/*/sections/h1"
},
{
"name": "header_2",
"source": "/document/markdownDocument/*/sections/h2"
},
{
"name": "header_3",
"source": "/document/markdownDocument/*/sections/h3"
}
]
}
],
"parameters": {
"projectionMode": "skipIndexingParentDocuments"
}
}
}
インデクサーを構成して実行する
データ ソース、インデックス、スキルセットを作成したら、インデクサーを作成して実行する準備ができました。 この手順では、パイプラインを実行します。
ドキュメント レイアウト スキルを使う場合は、インデクサーの定義で次のパラメーターを設定してください。
allowSkillsetToReadFileData
パラメーターはtrue
に設定する必要があります。parsingMode
パラメーターはdefault
に設定する必要があります。
outputFieldMappings
はソース フィールドから検索フィールドへの関連付けを処理するので、このシナリオでは indexProjections
を設定する必要はありません。 インデックス プロジェクションでは、ドキュメント レイアウト スキルのフィールドの関連付けと、インポートおよびベクトル化されたデータ ワークロードの分割スキルによる通常のチャンキングも処理されます。 出力フィールド マッピングは、変換や、他の場合に適用される関数を使用した複雑なデータ マッピングに依然として必要です。 ただし、ドキュメントあたり n チャンクの場合、インデックス プロジェクションはこの機能をネイティブに処理します。
インデクサー作成要求の例を次に示します。
POST {endpoint}/indexers?api-version=2024-11-01-preview
{
"name": "my_indexer",
"dataSourceName": "my_blob_datasource",
"targetIndexName": "my_consolidated_index",
"skillsetName": "my_skillset",
"parameters": {
"batchSize": 1,
"configuration": {
"dataToExtract": "contentAndMetadata",
"parsingMode": "default",
"allowSkillsetToReadFileData": true
}
},
"fieldMappings": [
{
"sourceFieldName": "metadata_storage_path",
"targetFieldName": "title"
}
],
"outputFieldMappings": []
}
検索サービスに要求を送信すると、インデクサーが実行されます。
検証結果
処理の完了後に検索インデックスに対してクエリを実行して、ソリューションをテストできます。
結果を確認するには、インデックスに対してクエリを実行します。 検索クライアントとしての Search エクスプローラーまたは HTTP 要求を送信する任意のツールを使用します。 次のクエリは、Markdown セクションの非ベクトル コンテンツとそのベクトルの出力を含むフィールドを選択します。
Search エクスプローラーでは、JSON のみをコピーし、クエリを実行するために JSON ビューに貼り付けることができます。
POST /indexes/[index name]/docs/search?api-version=[api-version]
{
"search": "copay for in-network providers",
"count": true,
"searchMode": "all",
"vectorQueries": [
{
"kind": "text",
"text": "*",
"fields": "text_vector,image_vector"
}
],
"queryType": "semantic",
"semanticConfiguration": "healthplan-doc-layout-test-semantic-configuration",
"captions": "extractive",
"answers": "extractive|count-3",
"queryLanguage": "en-us",
"select": "header_1, header_2, header_3"
}
医療保険の PDF を使用してこのスキルをテストした場合、サンプル クエリに対する検索エクスプローラーの結果は、次のスクリーンショット内の結果のようになります。
クエリはテキストとベクトルに対するハイブリッド クエリであるため、
@search.rerankerScore
が表示され、結果はそのスコアによってランク付けされます。searchMode=all
は、"すべての" クエリ用語が一致を考慮する必要があることを意味します (既定値は any)。クエリではセマンティック ランク付けが使用されるため、
captions
が表示されます (answers
も含まれますが、スクリーンショットには表示されていません)。 結果は、セマンティック的にクエリ入力と最も関連性の高いもので、セマンティック ランカーによって決定されます。select
ステートメント (スクリーンショットには示されていません) は、ドキュメント レイアウト スキルが検出して設定するヘッダー フィールドを指定します。 select 句にさらにフィールドを追加して、チャンク、タイトル、またはその他の人間が判読できるフィールドの内容を調べることができます。