Hinzufügen eines benutzerdefinierten Skills zu einer Azure KI-Suche-Anreicherungspipeline

Eine KI-Anreicherungspipeline kann sowohl integrierte Skills als auch benutzerdefinierte Skills umfassen, die Sie selbst erstellen und veröffentlichen. Ihr benutzerdefinierter Code wird extern für den Suchdienst ausgeführt (z. B. als Azure-Funktion), akzeptiert jedoch Eingaben und sendet Ausgaben an das Skillset wie jeder andere Skill.

Benutzerdefinierte Skills können komplex klingen, sind aber im Hinblick auf die Implementierung einfach und unkompliziert sein. Wenn Sie vorhandene Pakete besitzen, die Musterabgleichs- oder Klassifizierungsmodelle bereitstellen, kann der Inhalt, den Sie aus Blobs extrahieren, zur Verarbeitung an diese Modelle übergeben werden. Da die KI-Anreicherung Azure-basiert ist, sollte sich Ihr Modell ebenfalls in Azure befinden. Einige gängige Hostingmethoden umfassen unter anderem die Verwendung von Azure Functions oder Containern.

Wenn Sie einen benutzerdefinierten Skill erstellen, wird in diesem Artikel die Schnittstelle beschrieben, mit der Sie den Skill in die Pipeline integrieren können. Die primäre Anforderung lautet, Eingaben zu akzeptieren und Ergebnisse in einer Art und Weise auszugeben, dass sie innerhalb des Skillsets als Ganzes verarbeitet werden können. Daher liegt der Schwerpunkt dieses Artikels auf den Eingabe- und Ausgabeformaten, die die Anreicherungspipeline benötigt.

Vorteile von benutzerdefinierten Skills

Das Erstellen eines benutzerdefinierten Skills gibt Ihnen die Möglichkeit, Transformationen einzufügen, die für Ihren Inhalt eindeutig sind. Ein benutzerdefinierter Skill wird unabhängig ausgeführt, wobei jeder gewünschte Anreicherungsschritt angewendet wird. Sie können beispielsweise benutzerdefinierte Klassifizierungsmodelle erstellen, um zwischen Geschäfts- und Finanzverträgen und -dokumenten zu unterscheiden, oder einen Skill für die Spracherkennung hinzufügen, um Audiodateien nach relevanten Inhalten zu durchsuchen. Ein Beispiel mit Schrittanleitung finden Sie unter Beispiel: Erstellen eines benutzerdefinierten Skills zur KI-Anreicherung.

Festlegen des Endpunkts und des Timeoutintervalls

Die Schnittstelle für einen benutzerdefinierten Skill wird über den Skill für benutzerdefinierte Web-APIs festgelegt.

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

Der URI ist der HTTPS-Endpunkt Ihrer Funktion oder App. Stellen Sie beim Festlegen des URI sicher, dass der URI sicher ist (HTTPS). Wenn Ihr Code in einer Azure-Funktions-App gehostet wird, sollte der URI zum Autorisieren der Anforderung einen API-Schlüssel im Header enthalten oder als URI-Parameter verwendet werden.

Wenn Ihre Funktion oder App stattdessen verwaltete Azure-Identitäten und Azure-Rollen für die Authentifizierung und Autorisierung verwendet, kann der benutzerdefinierte Skill ein Authentifizierungstoken in der Anforderung enthalten. In den folgenden Punkten werden die Anforderungen für diesen Ansatz beschrieben:

Die Verbindung mit dem Endpunkt wird standardmäßig unterbrochen, wenn nicht innerhalb eines Zeitfensters von 30 Sekunden eine Antwort zurückgegeben wird. Die Indizierungspipeline ist synchron, und die Indizierung führt zu einem Timeoutfehler, wenn in diesem Zeitraum keine Antwort empfangen wird. Sie können das Intervall auf einen Wert von maximal 230 Sekunden erhöhen, indem Sie den Parameter „timeout“ festlegen:

Formatieren der Web-API-Eingaben

Die Web-API muss ein Array von zu verarbeitenden Datensätzen akzeptieren. Jeder Datensatz muss einen „Eigenschaftenbehälter“ umfassen, der die Eingabe für Ihre Web-API darstellt.

Angenommen, Sie möchten eine einfache Anreicherungsfunktion erstellen, die das erste in einem Vertragstext genannte Datum identifiziert. In diesem Beispiel akzeptiert der benutzerdefinierte Skill nur die Eingabe „contractText“ als Vertragstext. Der Skill hat auch eine einzige Ausgabe: das Datum des Vertrags. Um die Anreicherungsfunktion interessanter zu gestalten, geben Sie diesen Wert „contractDate“ in Form eines mehrteiligen komplexen Typs zurück.

Ihre Web-API muss bereit sein, um einen Stapel von Eingabedatensätzen zu empfangen. Jedes Element des Arrays "values" repräsentiert die Eingabe für einen bestimmten Datensatz. Jeder Datensatz muss die folgenden Elemente enthalten:

  • Ein Element „recordId“, bei dem es sich um den eindeutigen Bezeichner für einen bestimmten Datensatz handelt. Wenn Ihre Anreicherungsfunktion die Ergebnisse zurückgibt, muss diese „recordId“ bereitgestellt werden, damit der Aufrufer die Datensatzergebnisse mit seiner Eingabe abgleichen kann.

  • Ein data-Element, das im Wesentlichen ein Behälter mit Eingabefeldern für jeden Datensatz ist.

Die resultierende Web-API-Anforderung könnte wie folgt aussehen:

{
    "values": [
      {
        "recordId": "a1",
        "data":
           {
             "contractText": 
                "This is a contract that was issues on November 3, 2017 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
           }
      }
    ]
}

In der Praxis kann Ihr Code mit Hunderten oder Tausenden von Datensätzen aufgerufen werden, statt wie hier nur mit drei Datensätzen.

Formatieren von Web-API-Ausgaben

Das Format der Ausgabe ist eine Gruppe von Datensätzen, die ein recordId-Element umfassen, und ein Eigenschaftenbehälter. Dieses spezielle Beispiel hat nur eine Ausgabe, Sie können jedoch auch mehr als eine Eigenschaft ausgeben. Erwägen Sie als bewährte Methode die Ausgabe von Fehler- und Warnmeldungen, wenn ein Datensatz nicht verarbeitet werden konnte.

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

Hinzufügen eines benutzerdefinierten Skills zu einem Skillset

Wenn Sie eine Web-API-Anreicherungsfunktion erstellen, können Sie HTTP-Header und Parameter als Teil der Anforderung beschreiben. Der folgende Codeschnipsel zeigt, wie Anforderungsparameter und optionale HTTP-Header in die Skillsetdefinition aufgenommen werden können. Das Festlegen eines HTTP-Headers ist nützlich, wenn Sie Konfigurationseinstellungen an Ihren Code übergeben müssen.

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

Sehen Sie sich dieses Video an

Die folgende Demo bietet eine Videoeinführung und eine Demonstration.

Nächste Schritte

In diesem Artikel wurden die Schnittstellenanforderungen behandelt, die für die Integration einer benutzerdefinierten Qualifikation in ein Skillset erforderlich sind. Verwenden Sie die folgenden Links, um mehr über benutzerdefinierte Skills und die Zusammensetzung von Skillsets zu erfahren.