REST を使用してナレッジ ストアを作成する

注

Azure AI 検索は、Azure ポータル、REST API、およびAzure SDKから使用できます。 また、Foundry IQ は、エンタープライズ コンテンツを、Microsoft Foundry ポータルのエージェントの再利用可能なアクセス許可に対応したナレッジ ベースに変換するマネージド ナレッジ レイヤーです。

注

Knowledge ストアは、Azure AI 検索スキルセットの出力を含むセカンダリストレージとして、Azure Storageに存在します。 これらは、 エージェントの取得 ワークフローで使用されるナレッジ ソースやナレッジ ベースとは別です。

Azure AI 検索では、knowledge ストアは、検索以外のシナリオで使用されるスキルによって生成されたコンテンツのリポジトリです。 インデクサーとスキルセットを使用してナレッジ ストアを作成し、出力を格納するAzure Storageを指定します。 ナレッジ ストアが設定されたら、Storage Explorer や Power BI などのツールを使用してコンテンツを探索します。

この記事では、REST API を使用して、ナレッジ ストアにホテル宿泊の一連の顧客レビューを取り込み、エンリッチし、探索します。 ナレッジ ストアは、ソースから取得された元のテキスト コンテンツと AI によって生成されたコンテンツ (センチメント スコア、キー フレーズ抽出、言語検出、および非英語圏の顧客によるコメントのテキスト翻訳が含まれている) を含んでいます。

初期データ セットを使用できるようにするために、ホテルのレビューは最初にAzure Blob Storageにインポートされます。 後処理では、結果はナレッジ ストアとして Azure Table Storageに保存されます。

ヒント

この記事では、REST を使用して各手順について詳しく説明します。 コマンドを実行するだけの場合は> REST ファイル

前提条件

この例のスキルセットでは、エンリッチメントに Foundry Tools を使用します。 ワークロードが非常に小さいため、Foundry Tools は舞台裏で利用され、毎日最大20件のトランザクションに対して無料で処理を行います。 ワークロードが小さいということは、Microsoft Foundry リソースの作成またはアタッチをスキップできることを意味します。

Azure Storageにデータをアップロードして接続文字列を取得する

  1. download HotelReviews_data.csv。 この CSV には、1 つのホテルに関する 19 個のお客様のフィードバックが含まれています (ソースは Kaggle.com)。

  2. Azure portalで、storage アカウントを見つけ、Storage Browser を使用して、hotel-reviews という名前の BLOB コンテナーを作成します。

  3. ページの上部にある [ アップロード ] を選択して、前の手順からダウンロードした HotelReviews_data.csv ファイルを読み込みます。

    アップロードされたファイルと左側のナビゲーション ウィンドウを含むStorage ブラウザーのスクリーンショット

  4. 左側で Access Keys を選択し、Show Keys を選択し、key1 または key2 の接続文字列をコピーします。 完全なaccess 接続文字列の形式は次のとおりです。

"knowledgeStore": {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<YOUR-ACCOUNT-NAME>;AccountKey=<YOUR-ACCOUNT-KEY>;EndpointSuffix=core.windows.net;"
}

注

接続文字列で機密データを提供しない場合は、「マネージド ID を使用した接続を参照してください。

キーと URL をコピーする

この例では、REST 呼び出しには search service エンドポイントが必要であり、すべての要求で API キーを使用します。 これらの値は、Azure portalから取得できます。

  1. Azure portal で、Search サービスに移動します。

  2. [ 概要 ] ページで、エンドポイントの URL をコピーします。 エンドポイントの例は、https://mydemo.search.windows.net のようになります。

  3. >] で、管理者キーをコピーします。 管理者キーは、オブジェクトの追加、変更、削除で使用します。 2 つの交換可能な管理者キーがあります。 どちらかをコピーします。

    Azure ポータルの URL および API キーのスクリーンショット。

有効な API キーは、要求を送信するアプリケーションとそれを処理する検索サービスとの間に、要求ごとに信頼を確立します。

インデックスを作成する

作成インデックス (REST)はsearch serviceに検索インデックスを作成します。 検索インデックスはナレッジ ストアとは無関係ですが、これはインデクサーに必要です。 検索インデックスにはナレッジ ストアと同じコンテンツが含まれており、これは、クエリ要求を送信して調べることができます。

  1. Visual Studio Code で新しいテキスト ファイルを開きます。

  2. 事前に収集した検索エンドポイントと API キーに変数を設定します。

    @baseUrl = PUT-YOUR-SEARCH-SERVICE-URL-HERE
    @apiKey = PUT-YOUR-ADMIN-API-KEY-HERE
     @storageConnectionString = PUT-YOUR-STORAGE-CONNECTION-STRING-HERE
    @blobContainer = PUT-YOUR-CONTAINER-NAME-HERE (hotel-reviews)
    
  3. .rest ファイル拡張子でファイルを保存します。

  4. 次の例を貼り付けて、インデックス要求を作成します。

    ### Create a new index
    POST {{baseUrl}}/indexes?api-version=2026-04-01  HTTP/1.1
        Content-Type: application/json
        api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-idx",  
            "fields": [
                { "name": "name", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_date", "type": "Edm.DateTimeOffset", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_rating", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_text", "type": "Edm.String", "filterable": false,  "sortable": false, "facetable": false },
                { "name": "reviews_title", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "reviews_username", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "AzureSearch_DocumentKey", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false, "key": true },
                { "name": "language", "type": "Edm.String", "filterable": true, "sortable": false, "facetable": true },
                { "name": "translated_text", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
                { "name": "sentiment", "type": "Collection(Edm.String)", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
                { "name": "keyphrases", "type": "Collection(Edm.String)", "filterable": true, "sortable": false, "facetable": true }
            ]
        }
    
  5. [要求の送信] をクリックします。 HTTP/1.1 201 Created 応答が返され、その応答本文にはインデックス スキーマの JSON 表現が含まれているはずです。

データ ソースを作成する

データ ソースの作成はAzure AI 検索にデータ ソース接続を作成します。

  1. 次の例を貼り付けて、データ ソースを作成します。

    ### Create a data source
    POST {{baseUrl}}/datasources?api-version=2026-04-01  HTTP/1.1
      Content-Type: application/json
      api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-ds",
            "description": null,
            "type": "azureblob",
            "subtype": null,
            "credentials": {
                "connectionString": "{{storageConnectionString}}"
            },
            "container": {
                "name": "{{blobContainer}}",
                "query": null
            },
            "dataChangeDetectionPolicy": null,
            "dataDeletionDetectionPolicy": null
        }
    
  2. [要求の送信] をクリックします。

スキルセットを作成する

スキルセットにより、エンリッチメント (スキル) とナレッジ ストアが定義されます。 スキルセットの作成はsearch serviceにオブジェクトを作成します。

  1. 次の例を貼り付けて、スキルセットを作成します。

    ### Create a skillset
    POST {{baseUrl}}/skillsets?api-version=2026-04-01  HTTP/1.1
        Content-Type: application/json
        api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-ss",
            "description": "Skillset to detect language, translate text, extract key phrases, and score sentiment",
            "skills": [ 
                {
                    "@odata.type": "#Microsoft.Skills.Text.SplitSkill", 
                    "context": "/document/reviews_text", "textSplitMode": "pages", "maximumPageLength": 5000,
                    "inputs": [ 
                        { "name": "text", "source": "/document/reviews_text" }
                    ],
                    "outputs": [
                        { "name": "textItems", "targetName": "pages" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.V3.SentimentSkill",
                    "context": "/document/reviews_text/pages/*",
                    "inputs": [
                        { "name": "text", "source": "/document/reviews_text/pages/*" },
                        { "name": "languageCode", "source": "/document/language" }
                    ],
                    "outputs": [
                        { "name": "sentiment", "targetName": "sentiment" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill",
                    "context": "/document",
                    "inputs": [
                        { "name": "text", "source": "/document/reviews_text" }
                    ],
                    "outputs": [
                        { "name": "languageCode", "targetName": "language" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.TranslationSkill",
                    "context": "/document/reviews_text/pages/*",
                    "defaultFromLanguageCode": null,
                    "defaultToLanguageCode": "en",
                    "inputs": [
                        { "name": "text", "source": "/document/reviews_text/pages/*" }
                    ],
                    "outputs": [
                        { "name": "translatedText", "targetName": "translated_text" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill",
                    "context": "/document/reviews_text/pages/*",
                    "inputs": [
                        { "name": "text",  "source": "/document/reviews_text/pages/*" },
                        { "name": "languageCode",  "source": "/document/language" }
                    ],
                    "outputs": [
                        { "name": "keyPhrases" , "targetName": "keyphrases" }
                    ]
                },
                {
                    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
                    "context": "/document",
                    "inputs": [
                        { "name": "name",  "source": "/document/name" },
                        { "name": "reviews_date",  "source": "/document/reviews_date" },
                        { "name": "reviews_rating",  "source": "/document/reviews_rating" },
                        { "name": "reviews_text",  "source": "/document/reviews_text" },
                        { "name": "reviews_title",  "source": "/document/reviews_title" },
                        { "name": "reviews_username",  "source": "/document/reviews_username" },
                        { "name": "AzureSearch_DocumentKey",  "source": "/document/AzureSearch_DocumentKey" },
                        {
                        "name": "pages",
                        "sourceContext": "/document/reviews_text/pages/*",
                        "inputs": [
                            {
                            "name": "languageCode",
                            "source": "/document/language"
                            },
                            {
                            "name": "translatedText",
                            "source": "/document/reviews_text/pages/*/translated_text"
                            },
                            { 
                            "name": "sentiment",
                            "source": "/document/reviews_text/pages/*/sentiment"
                            },
                            {
                            "name": "keyPhrases",
                            "source": "/document/reviews_text/pages/*/keyphrases/*"
                            },
                            {
                            "name": "Page",
                            "source": "/document/reviews_text/pages/*"
                            }
                        ]
                        }
                    ],
                    "outputs": [
                        { "name": "output" , "targetName": "tableprojection" }
                    ]
                }
            ],
            "knowledgeStore": {
                "storageConnectionString": "{{storageConnectionString}}",
                "projections": [
                    {
                        "tables": [
                            { "tableName": "hotelReviews1Document", "generatedKeyName": "Documentid", "source": "/document/tableprojection" },
                            { "tableName": "hotelReviews2Pages", "generatedKeyName": "Pagesid", "source": "/document/tableprojection/pages/*" },
                            { "tableName": "hotelReviews3KeyPhrases", "generatedKeyName": "KeyPhrasesid", "source": "/document/tableprojection/pages/*/keyPhrases/*" }
                        ],
                        "objects": []
                    },
                    {
                        "tables": [
                            { 
                                "tableName": "hotelReviews4InlineProjectionDocument", "generatedKeyName": "Documentid", "sourceContext": "/document",
                                "inputs": [
                                    { "name": "name", "source": "/document/name"},
                                    { "name": "reviews_date", "source": "/document/reviews_date"},
                                    { "name": "reviews_rating", "source": "/document/reviews_rating"},
                                    { "name": "reviews_username", "source": "/document/reviews_username"},
                                    { "name": "reviews_title", "source": "/document/reviews_title"},
                                    { "name": "reviews_text", "source": "/document/reviews_text"},
                                    { "name": "AzureSearch_DocumentKey", "source": "/document/AzureSearch_DocumentKey" }
                                ]
                            },
                            { 
                                "tableName": "hotelReviews5InlineProjectionPages", "generatedKeyName": "Pagesid", "sourceContext": "/document/reviews_text/pages/*",
                                "inputs": [
                                    { "name": "Sentiment", "source": "/document/reviews_text/pages/*/sentiment"},
                                    { "name": "LanguageCode", "source": "/document/language"},
                                    { "name": "Keyphrases", "source": "/document/reviews_text/pages/*/keyphrases"},
                                    { "name": "TranslatedText", "source": "/document/reviews_text/pages/*/translated_text"},
                                    { "name": "Page", "source": "/document/reviews_text/pages/*" }
                                ]
                            },
                            { 
                                "tableName": "hotelReviews6InlineProjectionKeyPhrases", "generatedKeyName": "kpidv2", "sourceContext": "/document/reviews_text/pages/*/keyphrases/*",
                                "inputs": [
                                    { "name": "Keyphrases", "source": "/document/reviews_text/pages/*/keyphrases/*" }
                                ]
                            }
                        ],
                        "objects": []
                    }
                ]
            }
        }
    

重要なポイント:

  • Shaper スキルは、ナレッジ ストアの定義にとって重要です。 ナレッジ ストアのテーブルにデータがどのように流れるかを指定します。 入力は、格納するエンリッチされたドキュメントの部分です。 出力は、ノードを 1 つの構造に統合したものです。

  • プロジェクションでは、ナレッジ ストア内のテーブル、オブジェクト、BLOB を指定します。 テーブル プロジェクションでは、tableName、generatedKeyName、source、またはinputsを使用したsourceContextを指定します。 sourceプロパティとsourceContext プロパティは、格納するエンリッチメントされたコンテンツを識別します。

インデクサーの作成

[インデクサーの作成]: インデクサーを作成して実行します。 インデクサーの実行は、まず、ドキュメントを解読し、テキストと画像を抽出し、スキルセットを初期化して開始します。 インデクサーは、作成した他のオブジェクト (データ ソース、インデックス、スキルセット) をチェックします。

  1. 次の例を貼り付けて、インデクサーを作成します。

    ### Create indexer
    POST {{baseUrl}}/indexers?api-version=2026-04-01  HTTP/1.1
        Content-Type: application/json
        api-key: {{apiKey}}
    
        {
            "name": "hotel-reviews-kstore-idxr",
            "dataSourceName": "hotel-reviews-kstore-ds",
            "skillsetName": "hotel-reviews-kstore-ss",
            "targetIndexName": "hotel-reviews-kstore-idx",
            "parameters": {
                "configuration": {
                    "dataToExtract": "contentAndMetadata",
                    "parsingMode": "delimitedText",
                    "firstLineContainsHeaders": true,
                    "delimitedTextDelimiter": ","
        }
    },
    "fieldMappings": [
        {
            "sourceFieldName": "AzureSearch_DocumentKey",
            "targetFieldName": "AzureSearch_DocumentKey",
            "mappingFunction": { "name": "base64Encode" }
        }
    ],
    "outputFieldMappings": [
        { "sourceFieldName": "/document/reviews_text/pages/*/keyphrases/*", "targetFieldName": "keyphrases" },
        { "sourceFieldName": "/document/language", "targetFieldName": "language" },
        { "sourceFieldName": "/document/reviews_text/pages/*/sentiment", "targetFieldName": "sentiment" }
        ]
    }
    
  2. [要求の送信] を選択して、インデクサーを実行します。 この手順は、完了するまでに数分かかります。

重要なポイント:

  • parameters/configuration オブジェクトでは、インデクサーがデータを取り込む方法を制御します。 ここでは、入力データは、ヘッダー行とコンマ区切り値がある単一の CSV ファイルに含まれています。

  • AzureSearch_DocumentKey のフィールド マッピングでは、BLOB インデクサーによって生成されたドキュメントごとに一意の識別子が作成されます (メタデータstorageパスに基づいて)。

  • 出力フィールド マッピングでは、エンリッチされたフィールドが、検索インデックス内のフィールドにマップされる方法を指定します。 出力フィールド マッピングは、ナレッジ ストアでは使用されません (ナレッジ ストアでは、物理的なデータ構造を表すためにシェイプとプロジェクションが使用されます)。

状態の確認

インデクサーの状態を確認して、スキルセットが正常に完了したことを確認します。

### Get Indexer Status (wait several minutes for the indexer to complete)
GET {{baseUrl}}/indexers/hotel-reviews-kstore-idxr/status?api-version=2026-04-01  HTTP/1.1
  Content-Type: application/json
  api-key: {{apiKey}}

要求は 200 OKを返します。 インデックスのクエリを実行する前に、 lastResult.status が success されるまで待ちます。

インデックスにクエリを実行してコンテンツを検査します。 インデックスを使用していない場合でも、この手順は、スキルセットが想定される出力を生成したことを確認するのに便利な方法です。

### Query the index (indexer status must be "success" before querying the index)
POST {{baseUrl}}/indexes/hotel-reviews-kstore-idx/docs/search?api-version=2026-04-01  HTTP/1.1
  Content-Type: application/json
  api-key: {{apiKey}}
  
  {
    "search": "*",
    "select": "reviews_title, reviews_username, language, translated_text, sentiment",
    "count": true
  }

要求は 200 OK を返し、選択したエンリッチされたフィールドが含まれます。

Azure portalでテーブルを確認する

Azure portalで、Azure Storage アカウントに切り替え、Storage Browser を使用して新しいテーブルを表示します。 スキルセットに定義されているプロジェクションごとに 1 つずつ、6 つのテーブルが表示されます。

各テーブルは、クエリ内のテーブルをクロスリンクするために必要な ID を使用して生成されます。 テーブルを開いたときに、これらのフィールドの下までスクロールして、パイプラインによって追加されたコンテンツ フィールドを表示します。

Storage Browser のナレッジ ストア テーブルのスクリーンショット

このチュートリアルでは、ナレッジ ストアは、データの整形と構造化のさまざまな方法を示すさまざまなテーブルで構成されています。 テーブル 1 から 3 は、Shaper スキルからの出力を使用して列と行を決定します。 テーブル 4 から 6 は、プロジェクション自体に埋め込まれたインライン 整形命令から作成されます。 どちらの方法を使用しても、同じ結果を得られます。

テーブル 説明
hotelReviews1Document CSV から引き継がれたフィールド (reviews_date や reviews_text など) が含まれます。
hotelReviews2Pages スキルセットによって作成された、エンリッチされたフィールド (センチメント スコアや翻訳されたテキストなど) が含まれます。
hotelReviews3KeyPhrases キー フレーズのみの長い一覧が含まれます。
hotelReviews4InlineProjectionDocument 最初のテーブルの代わりに、Shaper スキルではなくインライン整形を使用して、プロジェクションのデータを整形します。
hotelReviews5InlineProjectionPages 2 番目のテーブルの代わりに、インラインシェイピングを使用します。
hotelReviews6InlineProjectionKeyPhrases 3 番目のテーブルの代わりに、インライン整形を使用します。

クリーンアップ

独自のサブスクリプションで作業している場合は、projectの最後に、作成したリソースがまだ必要かどうかを特定することをお勧めします。 リソースを稼働させ続けるとお金がかかります。 リソースを個別に削除するか、リソース グループを削除してリソースのセット全体を削除することができます。

左側のナビゲーション ウィンドウの すべてのリソース または Resource グループ リンクを使用して、Azure portalでリソースを検索および管理できます。

次のステップ

Foundry Tools を使用してデータを強化し、結果をナレッジ ストアに投影したので、Storage Explorerまたはその他のアプリを使用して、強化されたデータ セットを探索できます。

Storage Explorer を使用して開始する