Ajouter une compétence personnalisée à un pipeline d’enrichissement Recherche Azure AI

Un pipeline d’enrichissement d’IA peut inclure à la fois des compétences intégrées et des compétences personnalisées que vous créez et publiez personnellement. Votre code personnalisé s’exécute en externe à partir du service de recherche (par exemple, en tant que fonction Azure), mais accepte les entrées et envoie des sorties à l’ensemble de compétences comme n’importe quelle autre compétence. Vos données sont traitées dans l’emplacement géographique où votre modèle est déployé.

Si les compétences personnalisées peuvent paraître complexes, elles peuvent s’avérer simples du point de vue de l’implémentation. Si les packages dont vous disposez fournissent des critères spéciaux ou des modèles de classification, le contenu que vous extrayez des objets blob peut être transmis à ces modèles pour traitement. Comme l’enrichissement par IA est basé sur Azure, votre modèle doit aussi se trouver dans Azure. Certaines méthodologies d’hébergement courantes incluent l’utilisation d’Azure Functions ou de Containers.

Si vous créez une compétence personnalisée, cet article décrit l’interface que vous utilisez pour intégrer la compétence dans le pipeline. La principale exigence est la possibilité d’accepter des entrées et de générer des sorties de manières exploitables dans l’ensemble de compétences dans son ensemble. Cet article se concentre ainsi sur les formats d’entrée et de sortie que le pipeline d’enrichissement exige.

Avantages des compétences personnalisées

Construire une compétence personnalisée vous donne un moyen d’insérer des transformations uniques dans votre contenu. Par exemple, vous pouvez créer des modèles de classification personnalisés pour différencier des contrats et documents commerciaux et financiers, ou ajouter une compétence de reconnaissance vocale pour explorer plus profondément des fichiers audio afin d’en extraire du contenu pertinent. Pour un exemple pas à pas, voir Exemple : Création d’une compétence personnalisée pour l’enrichissement par IA.

Définir le point de terminaison et l’intervalle de délai d’expiration

L’interface pour une compétence personnalisée est spécifiée par le biais de la compétence de l’API web personnalisée.

"@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",

L’URI correspond au point de terminaison HTTPS de votre fonction ou application. Lors de la définition de l’URI, assurez-vous que l’URI est sécurisé (HTTPS). Si votre code est hébergé dans une application de fonction Azure, l’URI doit inclure une clé API dans l’en-tête ou en tant que paramètre d’URI pour autoriser la demande.

Si votre fonction ou application utilise plutôt des identités managées Azure et des rôles Azure pour l’authentification et l’autorisation, la compétence personnalisée peut inclure un jeton d’authentification sur la demande. Les points suivants décrivent les exigences inhérentes à cette approche :

Par défaut, la connexion au point de terminaison expire si une réponse n’est pas retournée dans une fenêtre de 30 secondes (PT30S). Le pipeline d'indexation est synchrone et l'indexation produit une erreur de délai d'expiration si aucune réponse n'est reçue dans ce délai d'exécution. Vous pouvez augmenter l’intervalle à une valeur maximale de 230 secondes en définissant le paramètre de délai d’expiration (PT230S).

Mettre en forme les entrées de l’API web

L’API web doit accepter un tableau d’enregistrements à traiter. Dans chaque enregistrement, fournissez un conteneur de propriétés en tant qu’entrée à votre API web.

Supposons que vous souhaitez créer un enrichisseur de base qui identifie la première date mentionnée dans le texte d’un contrat. Dans cet exemple, la compétence accepte une entrée unique, « contractText », en tant que texte du contrat. La compétence a également une sortie unique, qui est la date du contrat. Pour rendre l'enrichisseur plus intéressant, renvoyez ce "contractDate" sous la forme d'un type complexe en plusieurs parties.

Votre API web doit être prête à recevoir un lot d’enregistrements d’entrée. Chaque élément du tableau « valeurs » représente l’entrée d’un enregistrement particulier. Chaque enregistrement doit comporter les éléments suivants :

  • Un membre « recordId » qui est l’identificateur unique d’un enregistrement particulier. Lorsque votre enrichisseur retourne les résultats, il doit fournir ce « recordId » afin de permettre à l’appelant de faire correspondre les résultats de l’enregistrement à leur entrée.

  • Un membre « data » qui est essentiellement un jeu de champs d’entrée pour chaque enregistrement.

La requête d’API web résultante peut se présenter comme suit :

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

Dans la pratique, votre code peut être appelé avec des centaines ou des milliers d’enregistrements au lieu des trois affichés ici.

Mettre en forme les sorties de l’API web

Le format de la sortie est un ensemble d’enregistrements contenant un « recordId » et un jeu de propriétés. Cet exemple particulier ne génère qu’une seule sortie, mais vous pouvez générer plus d’une propriété. Il est recommandé de renvoyer des messages d’erreur et d’avertissement si un enregistrement n’a pas pu être traité.

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

Ajouter une compétence personnalisée à un ensemble de compétences

Lorsque vous créez un enrichisseur d’API web, vous pouvez décrire des en-têtes HTTP et des paramètres dans le cadre de la demande. L’extrait de code suivant montre comment des paramètres de requête et des en-têtes HTTP facultatifs peuvent être inclus dans la définition d’un ensemble de compétences. La définition d’un en-tête HTTP est utile si vous devez transmettre des paramètres de configuration à votre code.

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

Visionner la vidéo

Pour une présentation vidéo et une démonstration, regardez la démonstration suivante.

Étapes suivantes

Cet article a abordé les exigences d’interface nécessaires à l’intégration d’une compétence personnalisée dans un ensemble de compétences. Suivez ces liens pour en savoir plus sur les compétences personnalisées et la composition d’un ensemble de compétences.