Azure AI 検索スキルセットのコンテキストプロパティとソース プロパティを使用してエンリッチメントされたノードへのパスを参照する
スキルセットの実行中、エンジンは、認識されたエンティティや翻訳されたテキストなど、各エンリッチメントをキャプチャするインメモリ エンリッチメント ツリー を構築します。 この記事では、出力をダウンストリーム スキルに渡したり、検索インデックス フィールドの出力フィールド マッピングを指定したりできるように、エンリッチメント ツリー内のエンリッチメント ノードを参照する方法について説明します。
この記事では、例を使用してさまざまなシナリオを説明します。 完全な構文については、「スキル コンテキストと入力注釈言語」を参照してください。
バックグラウンドの概念
構文を調べる前に、この記事の後の方で説明する例をよく理解できるように、いくつかの重要な概念を再確認しておきましょう。
用語 | 説明 |
---|---|
"エンリッチされたドキュメント" | エンリッチされたドキュメントとは、スキルの出力をその作成時に収集するメモリ構造であり、ドキュメントに関連したあらゆるエンリッチメントを保持します。 エンリッチされたドキュメントのことは、ツリーとして考えてください。 一般に、ツリーはルート ドキュメント レベルで開始され、新しいエンリッチメントはそれぞれ前のエンリッチメントから子として作成されます。 |
"node" | エンリッチされたドキュメント内では、OCR スキルの "text" や "layoutText" などのノード ("注釈" とも呼ばれます) がスキルによって作成され、設定されます。 エンリッチメントされたドキュメントには、エンリッチメントと元のソース フィールド値またはソースからコピーされたメタデータの両方が設定されます。 |
"コンテキスト" | エンリッチメントのスコープ。これは、ドキュメント全体、ドキュメントの一部、または画像を操作している場合は、ドキュメントから抽出された画像になります。 既定では、エンリッチメント コンテキストは "/document" レベルであり、データ ソースに含まれる個々のドキュメントがスコープになります。 スキルを実行すると、そのスキルの出力は、定義されたコンテキストのプロパティになります。 |
さまざまなシナリオのパス
パスは、スキルセットの "context" と "source" プロパティ、およびインデクサーの出力フィールド マッピングに指定されます。
このスクリーンショットの例は、Azure Cosmos DB コレクション内の項目のパスを示しています。
context
パスは/document/HotelId
です。これは、コレクションが/HotelId
フィールドによって複数のドキュメントに分割されているためです。source
パスは/document/Description
です。これは、スキルが翻訳スキルであり、このスキルで翻訳するフィールドが各ドキュメント内のDescription
フィールドであるためです。
すべてのパスは /document
から始まります。 エンリッチされたドキュメントは、インデクサー実行の "ドキュメント解析" ステージ (つまり、インデクサーがドキュメントを開くか、データ ソースから行を読み取るとき) に作成されます。 最初、エンリッチされたドキュメント内の唯一のノードはルート ノード (/document
) であり、他のすべてのエンリッチメントはこのノードから発生します。
次の一覧に、いくつかの一般的な例を示します。
/document
はルート ノードであり、Azure Storage 内の BLOB 全体、または SQL テーブル内の行を示します。/document/{key}
は、Azure Cosmos DB コレクション内のドキュメントまたは項目の構文です。ここで、{key}
は実際のキーです。たとえば、前の例では/document/HotelId
です。/document/content
は、JSON BLOB の "content" プロパティを指定します。/document/{field}
は、特定のフィールドに対して実行される操作の構文です。たとえば、前の例で示した/document/Description
フィールドの翻訳などです。/document/pages/*
または/document/sentences/*
は、大きなドキュメントを処理のために小さなチャンクに分割する場合、context になります。 "context" が/document/pages/*
の場合、スキルはドキュメント内の各ページに対して 1 回実行されます。 複数のページまたは文がある可能性があるので、それらをすべてキャッチするために/*
を追加します。/document/normalized_images/*
は、ドキュメントに画像が含まれている場合、ドキュメント解析中に作成されます。 画像へのすべてのパスは、normalized_images で開始されます。 多くの場合、ドキュメントには複数の画像が埋め込まれているので、/*
を追加します。
この記事の残りの例は、Azure BLOB インデクサーによってドキュメント解析フェーズの一部として自動的に生成される "content" フィールドに基づいています。 BLOB コンテナーのドキュメントを参照するときは、"/document/content"
などの書式を使用します。ここで、"content" フィールドは "document" の一部です。
例 1: 単純な注釈参照
Azure Blob Storage に、エンティティ認識を使用して抽出する人名への参照を含む、さまざまなファイルがあるとします。 以下のスキル定義では、"/document/content"
はドキュメント全体のテキスト表現であり、"people" は人物として識別されるエンティティのフル ネームの抽出です。
既定のコンテキストは "/document"
であるため、人の一覧は "/document/people"
として参照できるようになりました。 この特定のケースでは、"/document/people"
は注釈であり、インデックス内のフィールドにマップすることも、同じスキルセット内の別のスキルで使用することもできます。
{
"@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
"categories": [ "Person"],
"defaultLanguageCode": "en",
"inputs": [
{
"name": "text",
"source": "/document/content"
}
],
"outputs": [
{
"name": "persons",
"targetName": "people"
}
]
}
例 2: ドキュメント内の配列の参照
この例は、前の例を基に構築されており、同じドキュメントに対して複数回エンリッチメント ステップを呼び出す方法を示しています。 前の例では、1 つのドキュメントから 10 人の名前を持つ文字列の配列が生成されたものとします。 妥当な次のステップは、フル ネームから姓を抽出する 2 回目のエンリッチメントでしょう。 10 個の名前があるため、このステップをこのドキュメントで 10 回、各人に対して 1 回ずつ呼び出します。
適切な反復回数の呼び出しを行うには、コンテキストを "/document/people/*"
に設定します。ここで、アスタリスク ("*"
) は、エンリッチされたドキュメントのすべてのノードを "/document/people"
の子孫として表します。 このスキルはスキル配列で一度だけ定義されますが、すべてのメンバーが処理されるまで、ドキュメント内の各メンバーに対して呼び出されます。
{
"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"description": "Fictitious skill that gets the last name from a full name",
"uri": "http://names.azurewebsites.net/api/GetLastName",
"context" : "/document/people/*",
"defaultLanguageCode": "en",
"inputs": [
{
"name": "fullname",
"source": "/document/people/*"
}
],
"outputs": [
{
"name": "lastname",
"targetName": "last"
}
]
}
注釈が文字列の配列またはコレクションである場合、配列全体ではなく特定のメンバーをターゲットにしたい場合もあります。 上の例では、コンテキストによって表されている各ノードの下に、"last"
という名前の注釈を生成しています。 この一連の注釈を参照する場合は、"/document/people/*/last"
という構文を使用することができます。 特定の注釈を参照する場合は、明示的なインデックス "/document/people/1/last
" を使用すると、ドキュメント内で特定された最初の人の姓を参照することができます。 この構文では、配列が "0 でインデックスされた" ことに注意してください。
例 3: 配列内のメンバーの参照
場合によっては、特定の種類のすべての注釈をグループ化して、特定のスキルに渡す必要があります。 例 2 で抽出されたすべての姓の中から最も一般的な姓を特定する、架空のカスタム スキルを考えてみましょう。 カスタム スキルに姓だけを提供するには、コンテキストを "/document"
、入力を "/document/people/*/lastname"
と指定します。
"/document/people/*/lastname"
のカーディナリティがドキュメントのカーディナリティよりも大きいことに注意してください。 このドキュメントには 1 つのドキュメント ノードしかありませんが、10 個の lastname ノードが存在する場合があります。 その場合、システムはドキュメント内のすべての要素を含む "/document/people/*/lastname"
の配列を自動的に作成します。
{
"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"description": "Fictitious skill that gets the most common string from an array of strings",
"uri": "http://names.azurewebsites.net/api/MostCommonString",
"context" : "/document",
"inputs": [
{
"name": "strings",
"source": "/document/people/*/lastname"
}
],
"outputs": [
{
"name": "mostcommon",
"targetName": "common-lastname"
}
]
}
注釈パスのトラブルシューティングに関するヒント
スキル入力の指定に問題がある場合は、次のヒントを参考にしてください。
データに対してデータのインポート ウィザードを実行して、ウィザードによって生成されるスキルセット定義とフィールド マッピングを確認します。
スキルセットに対してデバッグ セッションを開始して、エンリッチされたドキュメントの構造を表示します。 スキル定義のパスやその他の部分を編集した後、スキルを実行して変更を検証できます。