Azure AI Search エンリッチメント パイプラインにカスタム スキルを追加する

AI エンリッチメント パイプラインには、組み込みのスキルと、個人的に作成して公開するカスタム スキルの両方を含めることができます。 カスタム コードは、検索サービス (例: Azure 関数として) から外部で実行されますが、入力を受け取り、他のスキルと同様に出力をスキルセットに送信します。 データは、モデルがデプロイされている geo で処理されます。

カスタム スキルは一見複雑ですが、実装に関しては単純明快な場合があります。 パターン マッチングまたは分類モデルを提供する既存のパッケージがある場合、BLOB から抽出したコンテンツをこれらのモデルに渡して処理を委ねることができます。 AI エンリッチメントは Azure ベースであるため、モデルも Azure に存在する必要があります。 一般的なホスティング手法としては、Azure FunctionsContainers の使用があります。

カスタム スキルを構築する予定の場合は、この記事で、スキルをパイプラインに統合するために使用するインターフェイスについて説明しています。 主な要件となるのは、入力を受け取り、スキルセット内で全体として使用できる方法で出力する機能です。 そのためこの記事で重点を置いているのは、エンリッチメント パイプラインに必要な入力と出力の形式です。

カスタム スキルの利点

カスタム スキルを構築すると、コンテンツに固有の変換を挿入することができます。 たとえば、事業や財務の契約やドキュメントを区別するためのカスタム分類モデルを作成したり、関連コンテンツのオーディオ ファイルを細かく調べるために音声認識スキルを追加したりすることができます。 詳細な例については、「例: AI エンリッチメント用のカスタム スキルを作成する」を参照してください。

エンドポイントとタイムアウト間隔を設定する

カスタム スキルのインターフェイスは、カスタム Web API スキルを介して指定します。

"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"description": "This skill has a 230 second timeout",
"uri": "https://[your custom skill uri goes here]",
"authResourceId": "[for managed identity connections, your app's client ID goes here]",
"timeout": "PT230S",

URI は、関数またはアプリの HTTPS エンドポイントです。 URI を設定するときは、URI がセキュリティで保護されるようにします (HTTPS)。 コードが Azure 関数アプリでホストされている場合は、要求を承認するため、ヘッダー内に、または URI パラメーターとして、API キーを URI に含める必要があります。

代わりに、関数またはアプリで認証と承認に Azure マネージド ID と Azure ロールを使っている場合は、要求時にカスタム スキルに認証トークンを含めることができます。 この方法に対する要件を次に説明します。

エンドポイントへの接続は、既定では 30 秒の時間内に応答が返されないとタイムアウトになります (PT30S)。 インデックス作成パイプラインは同期的であり、その概算時間で応答が受信されなければ、インデックス作成によってタイムアウト エラーが生成されます。 この間隔は、timeout パラメーターを設定することで、最大値の 230 秒まで長くできます (PT230S)。

Web API の入力形式を指定する

Web API は、処理されるレコードの配列を受け取る必要があります。 各レコード内で、Web API への入力としてプロパティ バッグを指定します。

契約のテキストに記載されている最初の日付を識別する基本的なエンリッチャーを作成したいとします。 この例では、カスタム スキルで受け取るのは、契約テキストとしての単一の入力 "contractText" です。 スキルには、契約の日付である 1 つの出力もあります。 エンリッチャーをより興味深いものにするために、この「contractDate」をマルチパートの複合型形式で返します。

Web API は、入力レコードのバッチを受け取る準備ができている必要があります。 "values" 配列の各メンバーは、特定のレコードの入力を表します。 各レコードには、次の要素が必要です。

  • 特定のレコードの一意の識別子である "recordId" メンバー。 エンリッチャーが結果を返すとき、呼び出し元がレコード結果を入力とマッチさせることができるように、この "recordId" を提供する必要があります。

  • "data" メンバー。これは基本的に、各レコードの入力フィールドのバッグです。

結果の Web API 要求は次のようになります。

{
    "values": [
      {
        "recordId": "a1",
        "data":
           {
             "contractText": 
                "This is a contract that was issues on November 3, 2023 and that involves... "
           }
      },
      {
        "recordId": "b5",
        "data":
           {
             "contractText": 
                "In the City of Seattle, WA on February 5, 2018 there was a decision made..."
           }
      },
      {
        "recordId": "c3",
        "data":
           {
             "contractText": null
           }
      }
    ]
}

実際には、ここに示した 3 つだけでなく、数百、数千のレコードを指定してサービスが呼び出される可能性があります。

Web API の出力形式を指定する

出力の形式は、"recordId" が含まれるレコードのセットと、プロパティ バッグです。 この特定の例では出力が 1 つしかありませんが、複数のプロパティを出力することができます。 ベスト プラクティスとして、レコードを処理できない場合にエラー メッセージと警告メッセージを返すことを検討してください。

{
  "values": 
  [
      {
        "recordId": "b5",
        "data" : 
        {
            "contractDate":  { "day" : 5, "month": 2, "year" : 2018 }
        }
      },
      {
        "recordId": "a1",
        "data" : {
            "contractDate": { "day" : 3, "month": 11, "year" : 2023 }                    
        }
      },
      {
        "recordId": "c3",
        "data" : 
        {
        },
        "errors": [ { "message": "contractText field required "}   ],  
        "warnings": [ {"message": "Date not found" }  ]
      }
    ]
}

スキルセットにカスタム スキルを追加する

Web API エンリッチャーを作成すると、HTTP ヘッダーとパラメーターを要求の一部として記述できます。 次のスニペットは、要求パラメータとオプションの HTTP ヘッダーをスキルセット定義に含めることができる方法を示しています。 HTTP ヘッダーを設定することは、構成設定をコードに渡す必要がある場合に便利です。

{
    "skills": [
      {
        "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
        "name": "myCustomSkill",
        "description": "This skill calls an Azure function, which in turn calls TA sentiment",
        "uri": "https://indexer-e2e-webskill.azurewebsites.net/api/DateExtractor?language=en",
        "context": "/document",
        "httpHeaders": {
            "DateExtractor-Api-Key": "foo"
        },
        "inputs": [
          {
            "name": "contractText",
            "source": "/document/content"
          }
        ],
        "outputs": [
          {
            "name": "contractDate",
            "targetName": "date"
          }
        ]
      }
  ]
}

このビデオを観る

ビデオでの概要とデモについては、次のデモを視聴してください。

次のステップ

この記事では、カスタム スキルをスキルセットに統合するために必要なインターフェイス要件について説明しました。 以下のリンクで、引き続き、カスタム スキルとスキルセットの構成の詳細について確認してください。