Compétence API web personnalisée dans un pipeline d’enrichissement de Recherche Azure AI

Remarque

Recherche Azure AI est disponible via le portail Azure, les API REST et les SDK Azure. Il sous-tend également Foundry IQ, la couche de connaissances managée qui transforme le contenu d’entreprise en bases de connaissances réutilisables et prenant en charge les autorisations pour les agents dans le portail Microsoft Foundry.

Utilisez la compétence API web personnalisée pour étendre l’enrichissement par IA en appelant un point de terminaison d’API web qui fournit des opérations personnalisées. Comme les compétences intégrées, une compétence API web personnalisée a des entrées et des sorties. Selon les entrées, votre API Web reçoit une charge utile JSON lorsque l’indexeur s’exécute et retourne une charge utile JSON en tant que réponse, ainsi qu’un code d’état de réussite. La réponse doit inclure les sorties spécifiées par votre compétence personnalisée. Toute autre réponse est considérée comme une erreur et aucun enrichissement n’est effectué. La structure de la charge utile JSON est décrite plus loin dans ce document.

La compétence API web personnalisée est également utilisée dans l’implémentation de la fonctionnalité OpenAI Azure OpenAI sur vos données. Si Azure OpenAI est configuré pour l’accès en fonction du rôle et que vous obtenez 403 Forbidden des erreurs lors de la création de l’index vectoriel, vérifiez que Recherche Azure AI a une identité affectée par le système et s’exécute en tant que service approuvé sur Azure OpenAI.

Remarque

L’indexeur réessaie deux fois pour certains codes d’état HTTP standard retournés par l’API web. Ces codes d’état HTTP sont les suivants :

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

@odata.type

Microsoft.Skills.Custom.WebApiSkill

Paramètres de compétence

Les paramètres respectent la casse.

Nom du paramètre Description
uri URI de l’API web à laquelle la charge utile JSON est envoyée. Seul le schéma d’URI https est autorisé. Lorsque vous récupérez l’ensemble de compétences avec GET, le service retourne la valeur du ?code= paramètre de requête pour ?code=<redacted> empêcher l’exposition des clés de fonction. Pour mettre à jour la compétence sans modifier l’URI stocké, définissez sur uri<unchanged>.
authResourceId (Facultatif) Chaîne qui, lorsqu’elle est définie, indique que cette compétence doit utiliser une identité managée système sur la connexion à la fonction ou à l’application hébergeant le code. Cette propriété accepte un ID d'application (client) ou l'inscription d'une application dans Microsoft Entra ID dans l'un de ces formats : api://<appId>, <appId>/.defaultou api://<appId>/.default. Cette valeur permet d’étendre le jeton d’authentification récupéré par l’indexeur et est envoyé avec la demande de compétence API Web personnalisée à la fonction ou à l’application. La définition de cette propriété nécessite que votre service de recherche soit configuré pour une identité managée et que votre application de fonction Azure soit configurée pour une connexion Microsoft Entra. Pour utiliser ce paramètre, appelez l’API avec api-version=2023-10-01-preview ou une version ultérieure. Pour obtenir des conseils sur le choix de la valeur correcte, consultez Comprendre la authResourceId valeur.
authIdentity (Facultatif) Une identité managée par l’utilisateur utilisée par le service de recherche pour la connexion à la fonction ou à l’application qui héberge le code. Vous pouvez utiliser une identité managée par le système ou l’utilisateur. Pour utiliser une identité managée système, laissez authIdentity vide.
httpMethod Méthode à utiliser pour envoyer la charge utile. Les méthodes autorisées sont PUT ou POST
httpHeaders Collection de paires clé-valeur où les clés représentent les noms d’en-tête et les valeurs représentent les valeurs d’en-tête envoyées à votre API web avec la charge utile. Les en-têtes suivants sont interdits dans cette collection : Accept, Accept-Charset, Accept-Encoding, Content-Length, Content-Type, Cookie, Host, TE, Upgrade, Via. Lorsque vous récupérez l’ensemble de compétences avec GET, le service retourne <redacted> toutes les valeurs d’en-tête pour empêcher l’exposition des informations d’identification telles que les jetons du porteur et les clés API. Pour mettre à jour la compétence sans modifier les valeurs d’en-tête stockées, définissez chaque valeur <unchanged>sur . Le service restaure la valeur stockée d’origine.
timeout (Facultatif) Si spécifié, indique le délai d’expiration pour le client http qui effectue l’appel d’API. Il doit être formaté en tant que valeur « dayTimeDuration » XSD (un sous-ensemble limité d'une valeur de durée ISO 8601 ). Par exemple, PT60S pour 60 secondes. S’il n’est pas défini, une valeur par défaut de 30 secondes est choisie. Le délai d’expiration peut être défini sur 230 secondes maximum et 1 seconde minimum.
batchSize (Facultatif) Indique le nombre « d’enregistrements de données » (voir la structure de charge utile JSON ci-dessous) envoyés par appel d’API. S’il n’est pas défini, une valeur par défaut de 1000 est choisie. Utilisez ce paramètre pour obtenir un compromis approprié entre le débit d’indexation et la charge sur votre API.
degreeOfParallelism (Facultatif) Lorsqu’il est spécifié, indique le nombre d’appels que l’indexeur effectue en parallèle au point de terminaison que vous fournissez. Vous pouvez réduire cette valeur si votre point de terminaison échoue en raison de la pression ou l’augmenter s’il peut gérer la charge. S’il n’est pas défini, une valeur par défaut de 5 secondes est utilisée. Le degreeOfParallelism peut avoir une valeur maximale de 10 et un minimum de 1.

Comprendre la authResourceId valeur

Lorsqu’une compétence API web personnalisée utilise l’authentification d’identité managée, Recherche Azure AI obtient un jeton d’accès Microsoft Entra et l’envoie au point de terminaison de compétence personnalisé. La authResourceId propriété spécifie l’identificateur de ressource, également appelé audience ou URI d’ID d’application, pour lequel le jeton est demandé. La valeur doit correspondre à ce que l’application cible attend lors de la validation du jeton. Sinon, l’authentification échoue avec une 401 Unauthorized réponse.

La authResourceId valeur identifie l’application qui héberge votre compétence personnalisée. Il ne s’agit pas de l’URL de votre service de recherche ou de votre indexeur.

Le tableau suivant présente les formats courants :

Application cible authResourceId valeur
application web protégée Microsoft Entra api://<application-client-id>
Application configurée avec un URI d’ID d’application personnalisé URI d’ID d’application personnalisé, tel que api://contoso-customskill
fonction Azure protégée par Microsoft Entra ID URI d’ID d’application configuré pour l’inscription d’application de l’application de fonction, par exemple api://contoso-funcapp

La propriété accepte les formats avec et sans le suffixe d’étendue .default . Permet api://<appId> de faire correspondre directement l’URI d’ID d’application. Si vous incluez un .default suffixe, par api://<appId>/.defaultexemple, la revendication du jeton d’accès contient l’URI d’ID d’application de aud base sans le suffixe.

Pour savoir comment configurer Microsoft Entra’authentification pour une fonction Azure et définirauthResourceId, consultez Utiliser une identité managée de service de recherche pour se connecter à une application de fonction Azure.

Exemple : fonction Azure protégée par Microsoft Entra ID

Dans cet exemple, Recherche Azure AI acquiert un jeton d’accès pour l’audience spécifiée authResourceId et inclut le jeton lors de l’appel du point de terminaison de compétence personnalisé.

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

Données de compétences

Cette compétence n’a pas d’entrées prédéfinies. Les entrées sont n’importe quel champ existant ou n’importe quel nœud de l’arborescence d’enrichissement que vous souhaitez transmettre à votre compétence personnalisée.

Résultats des compétences

Cette compétence n’a pas de sortie prédéfinie. Veillez à définir un mappage de champ de sortie dans l’indexeur si la sortie de la compétence doit être envoyée à un champ de l’index de recherche.

Exemple de définition

{
  "@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"
    }
  ]
}

Remarque

Lorsque vous récupérez un ensemble de compétences à l’aide de GET, le service retourne <redacted> toutes les valeurs et httpHeaders pour n’importe ?code=<redacted> quel ?code= paramètre de requête dans le uri. Les deux valeurs empêchent l’exposition des informations d’identification aux appelants qui détiennent le rôle Contributeur du service de recherche, mais aucun rôle sur le service externe. Pour mettre à jour la compétence sans modifier ces valeurs stockées, passez <unchanged> pour chaque champ affecté.

L’exemple suivant montre une réponse GET pour une compétence qui utilise l’authentification basée sur l’en-tête et un URI de fonction Azure :

{
  "@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>"
  }
}

Pour mettre à jour cette compétence sans modifier les valeurs existantes, utilisez <unchanged>:

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

Exemple de structure JSON d’entrée

Cette structure JSON représente la charge utile que vous envoyez à votre API web. Elle suit toujours ces contraintes :

  • L’entité de niveau supérieur est appelée values et est un tableau d’objets. Le nombre de ces objets est au maximum le batchSize.

  • Chaque objet dans le tableau values a :

    • Propriété recordId qui est une chaîne unique , utilisée pour identifier cet enregistrement.

    • Propriété data qui est un objet JSON. Les champs de la propriété data correspondent aux « noms » spécifiés dans la section inputs de la définition de compétence. Les valeurs de ces champs proviennent de source ces champs (qui peuvent provenir d’un champ dans le document ou potentiellement d’une autre compétence).

{
    "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": []
           }
      }
    ]
}

Exemple de structure JSON de sortie

« output » correspond à la réponse renvoyée par votre API web. L’API web doit retourner uniquement une charge utile JSON (vérifiée en examinant l’en-tête de réponse Content-Type) et doit satisfaire les contraintes suivantes :

  • Il doit y avoir une entité de niveau supérieur appelée values qui doit être un tableau d’objets.

  • Le nombre d’objets dans le tableau doit être le même que le nombre d’objets envoyés à l’API web.

  • Chaque objet doit avoir :

    • Une propriété recordId.

    • Une propriété data, qui est un objet dans lequel les champs sont des enrichissements correspondant aux « noms » dans output et dont la valeur est considérée comme l’enrichissement.

    • Une propriété errors, tableau listant toutes les erreurs rencontrées et qui est ajouté à l’historique d’exécution de l’indexeur. Cette propriété est obligatoire, mais peut avoir une valeur null.

    • Une propriété warnings, tableau listant tous les avertissements rencontrés et qui est ajouté à l’historique d’exécution de l’indexeur. Cette propriété est obligatoire, mais peut avoir une valeur null.

  • L’ordre des objets dans les values indiquées dans la demande ou la réponse n’a pas d’importance. Toutefois, comme le recordId est utilisé pour la corrélation, tous les enregistrements dans la réponse contenant un recordId absent de la demande d’origine envoyée à l’API web sont ignorés.

{
    "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"
              }
            ]
        },
    ]
}

Cas d’erreur

En plus de l’indisponibilité de votre API web ou de l’envoi de codes d’état non réussis, considérez les cas suivants en tant qu’erreurs :

  • Si l’API Web retourne un code d’état de réussite, mais que la réponse indique qu’elle n’est pas valide, la réponse n’est pas application/jsonvalide et aucun enrichissement n’est effectué.

  • Si le tableau de réponses values contient des enregistrements non valides (par exemple, manquants ou dupliqués recordId), les enregistrements non valides ne sont pas enrichis. Lorsque vous développez des compétences personnalisées, respectez le contrat de compétences de l’API web. Vous pouvez vous référer à cet exemple fourni dans le dépôt Power Skill qui suit le contrat prévu.

Dans les cas où l’API Web n’est pas disponible ou retourne une erreur HTTP, l’historique d’exécution de l’indexeur inclut une erreur conviviale avec des détails disponibles sur l’erreur HTTP.

Considérations relatives à la sécurité pour l’authentification d’identité managée

Lorsque vous utilisez l’authentification d’identité managée avec une compétence d’API web personnalisée, Recherche Azure AI obtient un jeton d’accès Microsoft Entra pour l’application identifiée authResourceId et inclut ce jeton dans les requêtes envoyées au point de terminaison spécifié par uri. Le point de terminaison référencé par uri est généralement votre Azure Function, Azure App Service, Gestion des API Azure point de terminaison ou une autre application protégée par Microsoft Entra. Vous êtes responsable de la configuration et de la maintenance de la relation entre le point de terminaison et l’application identifiée par authResourceId.

Quelle que soit la méthode d’authentification, les entrées de compétence personnalisées peuvent contenir des valeurs provenant de documents ou de valeurs fournis par le client dérivées de ces documents. Traitez toutes les entrées de compétence personnalisées comme non approuvées. Recherche Azure AI transfère les entrées configurées dans l’ensemble de compétences à votre point de terminaison sans interpréter, valider ou limiter leur contenu pour votre implémentation personnalisée.

Validez et limitez les valeurs dérivées du document dans votre compétence personnalisée avant de les utiliser dans des requêtes sortantes ou d’autres opérations sensibles à la sécurité. Utilisez la validation d’entrée, les listes d’autorisation de destination, l’URL et la validation du nom d’hôte, les restrictions de protocole et l’accès réseau avec privilèges minimum qui autorisent uniquement les destinations et les ports dont la compétence a besoin. Pour plus d’informations, consultez Stratégies d’architecture pour la mise en réseau et la connectivité.

Pour faciliter la maintenance d’un déploiement sécurisé, suivez les pratiques suivantes :

  • Configurez la uri propriété pour qu’elle pointe uniquement vers des points de terminaison approuvés destinés à recevoir des demandes de Recherche Azure AI.
  • Configurez authResourceId pour identifier l’application Microsoft Entra attendue pour recevoir et valider le jeton d’accès.
  • Vérifiez que l’application recevant des demandes valide les revendications de jeton standard, notamment l’audience (), l’émetteur (aud), le locataire (isstid) et les rôles ou autorisations d’application requis avant de traiter les demandes.
  • Appliquez le principe du privilège minimum lors de l’octroi d’autorisations à l’identité managée Recherche Azure AI.
  • Passez régulièrement en revue les définitions de compétences d’API web personnalisées, les inscriptions d’applications Microsoft Entra et les attributions de rôles d’application et les autorisations accordées à Recherche Azure AI identités managées. Passez en revue les modifications de configuration par le biais de vos processus de gestion des modifications et de révision de sécurité établis.
  • Passez régulièrement en revue les configurations de point de terminaison pour Azure Functions, App Services, API et passerelles d’API.
  • Surveillez les journaux de connexion d’application, les événements d’authentification et les journaux d’accès aux API pour une activité inattendue ou non autorisée.
  • Supprimez les points de terminaison inutilisés, les autorisations, les inscriptions d’applications et les attributions de rôles qui ne sont plus nécessaires.

Restreindre l’accès à la configuration de l’ensemble de compétences

Les utilisateurs qui peuvent créer, modifier ou exécuter des ensembles de compétences peuvent contrôler à la fois le point de terminaison de destination et la configuration d’authentification utilisée par une compétence d’API web personnalisée. Limitez ces autorisations aux administrateurs approuvés et suivez vos processus de gestion des modifications et de révision de sécurité standard lors de la configuration des compétences personnalisées avec l’identité managée.

Important

La authResourceId valeur identifie l’application destinataire prévue pour le jeton d’accès. Vérifiez que le point de terminaison spécifié est uri le point de terminaison qui est censé recevoir et valider des jetons pour cette application. Une configuration incorrecte peut entraîner des échecs d’authentification ou des demandes envoyées à un point de terminaison inattendu.

Voir aussi