Azure AI 検索 のエンリッチメント パイプラインのカスタム Web API スキル

Note

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

カスタム操作を提供する Web API エンドポイントを呼び出して、カスタム Web API スキルを使用して AI エンリッチメントを拡張します。 組み込みのスキルと同様に、 カスタム Web API スキルには入力と出力があります。 入力に応じて、Web API はインデクサーの実行時に JSON ペイロードを受け取り、成功状態コードと共に JSON ペイロードを応答として返します。 応答には、カスタム スキルで指定された出力が含まれている必要があります。 その他の応答はエラーと見なされ、エンリッチメントは実行されません。 JSON ペイロードの構造については、このドキュメントの後半で説明します。

カスタム Web API スキルは、Azure OpenAI On Your Data 機能の実装でも使用されます。 Azure OpenAI がロールベースのアクセス用に構成されていて、ベクター インデックスの作成時に403 Forbiddenエラーが発生する場合は、Azure AI 検索にシステム割り当て ID があり、Azure OpenAI で信頼されたサービスとして実行されていることを確認します。

Note

インデクサーは、Web API から返された特定の標準 HTTP 状態コードに対して 2 回再試行します。 これらの HTTP 状態コードは次のとおりです。

  • 502 Bad Gateway
  • 503 Service Unavailable
  • 429 Too Many Requests

@odata.type

Microsoft.Skills.Custom.WebApiSkill

スキル パラメーター

パラメーターでは大文字と小文字が区別されます。

パラメーター名 説明
uri JSON ペイロードが送信される Web API の URI。 https URI スキームのみが許可されます。 GET を使用してスキルセットを取得すると、サービスは関数キーの公開を防ぐために、 ?code= クエリ パラメーター値を ?code=<redacted> として返します。 格納されている URI を変更せずにスキルを更新するには、 uri<unchanged> に設定します。
authResourceId (省略可能)設定時に、このスキルがコードをホストする関数またはアプリへの接続でシステム マネージド ID を使用する必要があることを示す文字列。 このプロパティは、api://<appId><appId>/.default、またはapi://<appId>/.defaultのいずれかの形式で、アプリケーション (クライアント) ID またはアプリの登録をMicrosoft Entra IDで受け取ります。 この値は、インデクサーによって取得された認証トークンのスコープを設定するために使用され、カスタム Web API スキル要求と共に関数またはアプリに送信されます。 このプロパティを設定するには、検索サービスがマネージド ID 用に構成されており、かつ Azure 関数アプリが Microsoft Entra サインイン用に構成されている必要があります。 このパラメーターを使用するには、 api-version=2023-10-01-preview 以降で API を呼び出します。 正しい値の選択に関するガイダンスについては、「authResourceId値を理解する」を参照してください。
authIdentity (省略可能) コードをホストする関数またはアプリに接続するために検索サービスによって使用されるユーザーマネージド ID。 システムまたはユーザーのマネージド ID を使用できます。 システム マネージド ID を使用するには、 authIdentity 空白のままにします。
httpMethod ペイロードの送信時に使用されるメソッドです。 許可されるメソッドは PUT または POST です
httpHeaders キーと値のペアのコレクション。ここで、キーはヘッダー名を表し、値はペイロードと共に Web API に送信されるヘッダー値を表します。 次のヘッダーは、このコレクションに含めることはできません: AcceptAccept-CharsetAccept-EncodingContent-LengthContent-TypeCookieHostTEUpgradeVia。 GET を使用してスキルセットを取得すると、ベアラー トークンや API キーなどの資格情報が公開されないように、サービスはすべてのヘッダー値の <redacted> を返します。 格納されているヘッダー値を変更せずにスキルを更新するには、各値を <unchanged> に設定します。 サービスは、元の格納された値を復元します。
timeout (省略可能) 指定した場合は、API 呼び出しを行う http クライアントのタイムアウト値を示します。 XSD "dayTimeDuration" 値 (ISO 8601 期間値の制限されたサブセット) として書式設定する必要があります。 たとえば、60 秒の場合は PT60S とします。 設定しなかった場合は、既定値の 30 秒が選択されます。 タイムアウトは、最大で 230 秒、最小で 1 秒に設定できます。
batchSize (省略可能) API 呼び出しごとに送信される "データ レコード" の数を示します (後の JSON ペイロードの構造を参照)。 設定しなかった場合は、既定値の 1000 が選択されます。 このパラメーターを使用して、インデックス作成のスループットと API の負荷の適切なトレードオフを実現します。
degreeOfParallelism (省略可能) 指定されている場合は、指定したエンドポイントに対してインデクサーが並列に行う呼び出しの数を示します。 エンドポイントが負荷を受けて失敗している場合は、この値を小さくすることができます。また、エンドポイントが負荷を処理できる場合は、大きくすることができます。 設定しない場合は、既定値の 5 が使用されます。 degreeOfParallelism には、最大値として 10、最小値として 1 を設定できます。

authResourceId値を理解する

カスタム Web API スキルがマネージド ID 認証を使用する場合、Azure AI 検索はMicrosoft Entraアクセス トークンを取得し、カスタム スキル エンドポイントに送信します。 authResourceId プロパティは、トークンが要求される対象ユーザーまたはアプリケーション ID URI とも呼ばれるリソース識別子を指定します。 この値は、トークンの検証中にターゲット アプリケーションが想定する値と一致する必要があります。 それ以外の場合、認証は 401 Unauthorized 応答で失敗します。

authResourceId値は、カスタム スキルをホストしているアプリケーションを識別します。 検索サービスまたはインデクサーの URL ではありません。

次の表は、一般的な形式を示しています。

ターゲット アプリケーション authResourceId
保護された Web アプリケーションMicrosoft Entraする api://<application-client-id>
カスタム アプリケーション ID URI で構成されたアプリケーション カスタム アプリケーション ID URI (例: api://contoso-customskill
Azureによって保護される関数Microsoft Entra ID 関数アプリのアプリ登録用に構成されたアプリケーション ID URI (例: api://contoso-funcapp

このプロパティは、 .default スコープ サフィックスの付いた形式と使用しない形式を受け入れます。 アプリケーション ID URI を直接照合するには、 api://<appId> を使用します。 .default サフィックス (api://<appId>/.default など) を含める場合、アクセス トークンのaud要求には、サフィックスのない基本アプリケーション ID URI が含まれます。

Azure関数のMicrosoft Entra認証を構成し、authResourceIdを設定する手順については、「検索サービスのマネージド ID を使用してAzure関数アプリに接続する」を参照してください。

例: Microsoft Entra IDによって保護された関数Azure

この例では、Azure AI 検索authResourceIdで指定された対象ユーザーのアクセス トークンを取得し、カスタム スキル エンドポイントを呼び出すときにトークンを含めます。

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "uri": "https://contoso-function.azurewebsites.net/api/enrich",
  "authResourceId": "api://contoso-customskill"
}

スキルの入力

このスキルには定義済みの入力がありません。 入力は、任意の既存のフィールド、またはカスタム スキルに渡す エンリッチメント ツリー内の任意のノード です。

スキルの出力

このスキルには定義済みの出力がありません。 スキルの出力を検索インデックスのフィールドに送信する必要がある場合は、必ずインデクサーで出力フィールド マッピングを定義してください。

サンプル定義

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "description": "A custom skill that can identify positions of different phrases in the source text",
  "uri": "https://contoso.count-things.com",
  "batchSize": 4,
  "context": "/document",
  "inputs": [
    {
      "name": "text",
      "source": "/document/content"
    },
    {
      "name": "language",
      "source": "/document/languageCode"
    },
    {
      "name": "phraseList",
      "source": "/document/keyphrases"
    }
  ],
  "outputs": [
    {
      "name": "hitPositions"
    }
  ]
}

Note

GET を使用してスキルセットを取得すると、サービスはすべての<redacted>値のhttpHeadersを返し、?code=<redacted>内の任意の?code=クエリ パラメーターのuriを返します。 どちらの値でも、Search Service 共同作成者ロールを保持しているが、外部サービスに対するロールを持たない呼び出し元に資格情報が公開されるのを防ぎます。 格納されている値を変更せずにスキルを更新するには、影響を受けるフィールドごとに <unchanged> 渡します。

次の例は、ヘッダーベースの認証とAzure関数 URI を使用するスキルの GET 応答を示しています。

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "uri": "https://contoso.example.org/api?code=<redacted>",
  "httpMethod": "POST",
  "name": "myCustomSkill",
  "httpHeaders": {
    "Authorization": "<redacted>",
    "Ocp-Apim-Subscription-Key": "<redacted>"
  }
}

既存の値を変更せずにこのスキルを更新するには、 <unchanged>を使用します。

{
  "uri": "<unchanged>",
  "httpHeaders": {
    "Authorization": "<unchanged>",
    "Ocp-Apim-Subscription-Key": "<unchanged>"
  }
}

入力の JSON 構造体のサンプル

この JSON 構造体は、Web API に送信するペイロードを表します。 これは、常に次の制約に従います。

  • 最上位レベルのエンティティは values と呼ばれ、オブジェクトの配列です。 これらのオブジェクトの数は、最大でも batchSizeです。

  • values 配列内の各オブジェクトには、次のものが含まれています。

    • レコードを識別するために使用されるrecordIdの文字列であるプロパティ。

    • JSON オブジェクトである data プロパティ。 data プロパティのフィールドは、スキル定義の inputs セクションで指定されている "名前" に対応します。 これらのフィールドの値は、それらのフィールドの source から取得されます (ドキュメント内のフィールドから、または別のスキルから取得される可能性があります)。

{
    "values": [
      {
        "recordId": "0",
        "data":
           {
             "text": "Este es un contrato en Inglés",
             "language": "es",
             "phraseList": ["Este", "Inglés"]
           }
      },
      {
        "recordId": "1",
        "data":
           {
             "text": "Hello world",
             "language": "en",
             "phraseList": ["Hi"]
           }
      },
      {
        "recordId": "2",
        "data":
           {
             "text": "Hello world, Hi world",
             "language": "en",
             "phraseList": ["world"]
           }
      },
      {
        "recordId": "3",
        "data":
           {
             "text": "Test",
             "language": "es",
             "phraseList": []
           }
      }
    ]
}

出力の JSON 構造体のサンプル

"出力" は、Web API から返された応答に対応します。 Web API は JSON ペイロードのみを返す必要があります (Content-Type 応答ヘッダーを参照することで確認されます)。また、次の制約を満たす必要があります。

  • オブジェクトの配列である values と呼ばれる最上位レベルのエンティティが存在する必要があります。

  • 配列内のオブジェクトの数は、Web API に送信されるオブジェクトの数と同じになっている必要があります。

  • 各オブジェクトには次のプロパティが必要です。

    • recordId プロパティ。

    • data プロパティ。このオブジェクトでは、フィールドは output 内の "名前" に一致するエンリッチメントであり、その値はエンリッチメントと見なされます。

    • インデクサーの実行履歴に追加される発生したすべてのエラーがリストされている配列である errors プロパティ。 このプロパティは必須ですが、null 値にすることもできます。

    • インデクサーの実行履歴に追加される発生したすべての警告がリストされている配列である warnings プロパティ。 このプロパティは必須ですが、null 値にすることもできます。

  • 要求または応答の values 内のオブジェクトの順序は重要ではありません。 ただし、recordId は相関関係に使用されるため、Web API への元の要求の一部ではなかった、recordId が含まれている応答内のレコードはすべて破棄されます。

{
    "values": [
        {
            "recordId": "3",
            "data": {
            },
            "errors": [
              {
                "message" : "'phraseList' should not be null or empty"
              }
            ],
            "warnings": null
        },
        {
            "recordId": "2",
            "data": {
                "hitPositions": [6, 16]
            },
            "errors": null,
            "warnings": null
        },
        {
            "recordId": "0",
            "data": {
                "hitPositions": [0, 23]
            },
            "errors": null,
            "warnings": null
        },
        {
            "recordId": "1",
            "data": {
                "hitPositions": []
            },
            "errors": null,
            "warnings": [
              {
                "message": "No occurrences of 'Hi' were found in the input text"
              }
            ]
        },
    ]
}

エラー ケース

Web API が使用できないか、成功していない状態コードを送信するだけでなく、次の場合をエラーと見なします。

  • Web API が成功状態コードを返すが、応答が application/jsonされていないことを示す場合、応答は無効であり、エンリッチメントは実行されません。

  • 応答 values 配列に無効なレコードが含まれている場合 (たとえば、 recordIdが見つからないか重複しています)、無効なレコードはエンリッチされません。 カスタム スキルを開発するときは、Web API スキル コントラクトに従います。 予測されるコントラクトに従う Power Skills リポジトリで提供されているこの例を参照できます。

Web API が使用できない場合や HTTP エラーが返された場合、インデクサーの実行履歴には、HTTP エラーに関する使用可能な詳細を含むわかりやすいエラーが含まれます。

マネージド ID 認証のセキュリティに関する考慮事項

カスタム Web API スキルでマネージド ID 認証を使用する場合、Azure AI 検索は、authResourceIdによって識別されたアプリケーションのMicrosoft Entra アクセス トークンを取得し、uriによって指定されたエンドポイントに送信された要求にそのトークンを含めます。 uriによって参照されるエンドポイントは、通常、Azure関数、Azure App Service、Azure API Management エンドポイント、または別のMicrosoft Entraで保護されたアプリケーションです。 エンドポイントと、 authResourceIdによって識別されるアプリケーションの間の関係を構成し、維持する責任があります。

認証方法に関係なく、カスタム スキルの入力には、顧客が指定したドキュメントからの値や、それらのドキュメントから派生した値を含めることができます。 すべてのカスタム スキル入力を信頼されていないものとして扱います。 Azure AI 検索は、カスタム実装のコンテンツを解釈、検証、または制約することなく、スキルセットで構成された入力をエンドポイントに転送します。

送信要求やその他のセキュリティに依存する操作で使用する前に、カスタム スキルのドキュメント派生値を検証して制約します。 入力検証、宛先許可リスト、URL とホスト名の検証、プロトコルの制限、スキルで必要な宛先とポートのみを許可する最小特権ネットワーク アクセスを使用します。 詳細については、「 ネットワークと接続のアーキテクチャ戦略」を参照してください。

セキュリティで保護されたデプロイを維持するには、次のプラクティスに従います。

  • Azure AI 検索からの要求を受信することを目的とした信頼されたエンドポイントのみを指すように、uri プロパティを構成します。
  • アクセス トークンの受信と検証が必要なMicrosoft Entra アプリケーションを識別するようにauthResourceIdを構成します。
  • 要求を受け取るアプリケーションで、要求を処理する前に、対象ユーザー (aud)、発行者 (iss)、テナント (tid)、必要なアプリケーション ロールまたはアクセス許可を含む標準トークン要求が検証されていることを確認します。
  • Azure AI 検索マネージド ID にアクセス許可を付与する場合は、最小限の特権の原則を適用します。
  • カスタム Web API スキル定義、Microsoft Entraアプリケーションの登録、およびマネージド ID に付与されたアプリ ロールの割り当てとアクセス許可Azure AI 検索定期的に確認します。 確立された変更管理プロセスとセキュリティ レビュー プロセスを通じて、構成の変更を確認します。
  • Azure Functions、App Services、API、API ゲートウェイのエンドポイント構成を定期的に確認します。
  • アプリケーションのサインイン ログ、認証イベント、および API アクセス ログで、予期しないアクティビティまたは未承認のアクティビティを監視します。
  • 不要になった未使用のエンドポイント、アクセス許可、アプリケーションの登録、ロールの割り当てを削除します。

スキルセット構成へのアクセスを制限する

スキルセットを作成、変更、または実行できるユーザーは、カスタム Web API スキルで使用される宛先エンドポイントと認証構成の両方を制御できます。 これらのアクセス許可を信頼された管理者に制限し、マネージド ID が有効なカスタム スキルを構成するときに、標準の変更管理およびセキュリティ レビュー プロセスに従います。

Important

authResourceId値は、アクセス トークンの目的の受信者アプリケーションを識別します。 uriで指定されたエンドポイントが、そのアプリケーションのトークンを受信して検証することが期待されるエンドポイントであることを確認します。 構成が正しくないと、認証エラーや要求が意図しないエンドポイントに送信される可能性があります。

こちらも参照ください