Freigeben über


Beispiel: Erstellen eines benutzerdefinierten Skills mit Python (archiviert)

Dieses Beispiel ist archiviert und nicht mehr unterstützt. Es wurde erläutert, wie Sie eine benutzerdefinierte Web-API-Qualifikation mit Python und Visual Studio Code erstellen. Im Beispiel wurde eine Azure-Funktion verwendet, die die benutzerdefinierte Qualifikationsschnittstelle implementiert.

Voraussetzungen

Erstellen einer Azure Function

In diesem Beispiel wird eine Azure Function verwendet, um das Konzept des Hostings einer Web-API zu demonstrieren, aber es sind auch andere Ansätze möglich. Solange Sie die Schnittstellenanforderungen für einen kognitiven Skill erfüllen, ist der gewählte Ansatz unerheblich. Mit Azure Functions ist das Erstellen eines benutzerdefinierten Skills jedoch einfacher.

Erstellen eines Projekts für die Funktion

Mit der Azure Functions-Projektvorlage in Visual Studio Code wird ein lokales Projekt erstellt, das in einer Funktions-App in Azure veröffentlicht werden kann. Sie können mit einer Funktionen-App Funktionen zu logischen Einheiten gruppieren, um die Verwaltung, Bereitstellung und Freigabe von Ressourcen zu ermöglichen.

  1. Drücken Sie in Visual Studio Code die F1-Taste, um die Befehlspalette zu öffnen. Suchen Sie in der Befehlspalette den Befehl Azure Functions: Create new project..., und wählen Sie ihn aus.
  2. Wählen Sie einen Verzeichnisspeicherort für Ihren Projektarbeitsbereich und anschließend Auswählen aus. Verwenden Sie keinen Projektordner, der bereits Teil eines Arbeitsbereichs ist.
  3. Auswählen einer Sprache für Ihr Funktions-App-Projekt. Wählen Sie für dieses Tutorial die Option Python aus.
  4. Wählen Sie die Python-Version aus (Version 3.7.5 wird von Azure Functions unterstützt).
  5. Wählen Sie die Vorlage für die erste Funktion Ihres Projekts aus. Wählen Sie HTTP-Trigger aus, um eine durch HTTP ausgelöste Funktion in der neuen Funktions-App zu erstellen.
  6. Angeben eines Funktionsnamens. Verwenden Sie in diesem Fall Concatenator.
  7. Wählen Sie Funktion als Autorisierungsstufe aus. Sie verwenden einen Zugriffsschlüssel für die Funktion, um den HTTP-Endpunkt der Funktion aufzurufen.
  8. Geben Sie an, wie Sie Ihr Projekt öffnen möchten. Wählen Sie für diesen Schritt Zu Arbeitsbereich hinzufügen aus, um die Funktions-App im aktuellen Arbeitsbereich zu erstellen.

Visual Studio Code erstellt das Funktions-App-Projekt in einem neuen Arbeitsbereich. Dieses Projekt enthält die Dateien host.json und local.settings.jsonconfiguration sowie alle sprachspezifischen Projektdateien.

Eine neue HTTP-gesteuerte Funktion wird ebenfalls im Concatenator-Ordner des Funktions-App-Projekts erstellt. Darin ist eine Datei namens „__init__.py“ mit diesem Inhalt enthalten:

import logging

import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             status_code=400
        )

Nun ändern wir diesen Code so, dass er der benutzerdefinierten Qualifikationsschnittstelle folgt. Ersetzen Sie den Standardcode durch den folgenden Inhalt:

import logging
import azure.functions as func
import json

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    try:
        body = json.dumps(req.get_json())
    except ValueError:
        return func.HttpResponse(
             "Invalid body",
             status_code=400
        )
    
    if body:
        result = compose_response(body)
        return func.HttpResponse(result, mimetype="application/json")
    else:
        return func.HttpResponse(
             "Invalid body",
             status_code=400
        )


def compose_response(json_data):
    values = json.loads(json_data)['values']
    
    # Prepare the Output before the loop
    results = {}
    results["values"] = []
    
    for value in values:
        output_record = transform_value(value)
        if output_record != None:
            results["values"].append(output_record)
    return json.dumps(results, ensure_ascii=False)

## Perform an operation on a record
def transform_value(value):
    try:
        recordId = value['recordId']
    except AssertionError  as error:
        return None

    # Validate the inputs
    try:         
        assert ('data' in value), "'data' field is required."
        data = value['data']        
        assert ('text1' in data), "'text1' field is required in 'data' object."
        assert ('text2' in data), "'text2' field is required in 'data' object."
    except AssertionError  as error:
        return (
            {
            "recordId": recordId,
            "errors": [ { "message": "Error:" + error.args[0] }   ]       
            })

    try:                
        concatenated_string = value['data']['text1'] + " " + value['data']['text2']  
        # Here you could do something more interesting with the inputs

    except:
        return (
            {
            "recordId": recordId,
            "errors": [ { "message": "Could not complete operation for record." }   ]       
            })

    return ({
            "recordId": recordId,
            "data": {
                "text": concatenated_string
                    }
            })

Die Methode transform_value führt eine Operation für einen einzelnen Datensatz aus. Sie können die Methode an Ihre spezifischen Bedürfnisse anpassen. Vergessen Sie nicht, die erforderliche Eingabevalidierung durchzuführen und alle Fehler und Warnungen zurückzugeben, wenn der Vorgang nicht abgeschlossen werden kann.

Lokales Debuggen Ihres Codes

Mit Visual Studio Code lässt sich der Code leicht debuggen. Drücken Sie F5, oder wählen Sie im Menü Debuggen die Option Debuggen starten aus.

Sie können beliebige Breakpoints im Code setzen, indem Sie auf der betreffenden Zeile „F9“ drücken.

Sobald Sie das Debuggen gestartet haben, wird Ihre Funktion lokal ausgeführt. Sie können ein Tool wie Postman oder Fiddler verwenden, um die Anforderung an „localhost“ zu stellen. Notieren Sie die Position Ihres lokalen Endpunkts im Terminalfenster.

Erstellen einer Funktions-App in Azure

Wenn Sie mit dem Funktionsverhalten zufrieden sind, können Sie sie veröffentlichen. Bisher haben Sie lokal gearbeitet. In diesem Abschnitt erstellen Sie eine Funktions-App in Azure und stellen dann das lokale Projekt für die von Ihnen erstellte App bereit.

Erstellen der App in Visual Studio Code

  1. Drücken Sie in Visual Studio Code die F1-Taste, um die Befehlspalette zu öffnen. Suchen Sie in der Befehlspalette nach Funktions-App in Azure erstellen, und wählen Sie den Befehl aus.

  2. Wenn Sie mehrere Abonnements haben, wählen Sie das Abonnement für diese App aus.

  3. Geben Sie einen global eindeutigen Namen für die Funktions-App ein. Geben Sie einen Namen ein, der für eine URL gültig ist.

  4. Wählen Sie einen Laufzeitstapel und dann die Sprachversion aus, die Sie lokal ausgeführt haben.

  5. Wählen Sie einen Standort für die App aus. Wählen Sie nach Möglichkeit dieselbe Region aus, in der auch Ihr Suchdienst gehostet wird.

Das Erstellen der App dauert einige Minuten. Wenn sie bereit ist, wird die neue App unter Ressourcen und Funktions-App des aktiven Abonnements angezeigt.

In Azure bereitstellen

  1. Drücken Sie immer noch in Visual Studio Code F1, um die Befehlspalette zu öffnen. Suchen Sie in der Befehlspalette nach In Funktions-App bereitstellen..., und führen Sie den Befehl aus.

  2. Wählen Sie die erstellte Funktions-App aus.

  3. Bestätigen Sie, dass Sie den Vorgang fortsetzen möchten, und wählen Sie dann Bereitstellen aus. Sie können den Bereitstellungsstatus im Ausgabefenster überwachen.

  4. Wechseln Sie zum Azure-Portal, und navigieren Sie zu Alle Ressourcen. Suchen Sie mithilfe des global eindeutigen Namens, den Sie in einem früheren Schritt erstellt haben, nach der bereitgestellten Funktions-App.

    Tipp

    Sie können auch mit der rechten Maustaste in Visual Studio Code auf die Funktions-App klicken und Im Portal öffnen auswählen.

  5. Wählen Sie im Portal auf der linken Seite Funktionen aus, und wählen Sie dann die von Ihnen erstellte Funktion aus.

  6. Wählen Sie auf der Übersichtsseite der Funktion in der Befehlsleiste oben Funktions-URL abrufen aus. Dadurch können Sie die URL kopieren, um die Funktion aufzurufen.

    Screenshot des Befehls „Funktions-URL abrufen“ im Azure-Portal.

Testen der Funktion in Azure

Testen Sie Ihre Funktion im Azure-Portal mithilfe des Standardhostschlüssels und der von Ihnen kopierten URL.

  1. Wählen Sie auf der linken Seite unter „Entwickler“ Programmieren/Testen aus.

  2. Wählen Sie in der Befehlsleiste Testen/Ausführen aus.

  3. Verwenden Sie als Eingabe Post (Veröffentlichen), den Standardschlüssel, und fügen Sie dann den Anforderungstext ein:

    {
        "values": [
            {
                "recordId": "e1",
                "data":
                {
                    "text1":  "Hello",
                    "text2":  "World"
                }
            },
            {
                "recordId": "e2",
                "data": "This is an invalid input"
            }
        ]
    }
    
  4. Klicken Sie auf Run (Ausführen).

    Screenshot der Eingabespezifikation.

Dieses Beispiel sollte das gleiche Ergebnis liefern wie die Ausführung der Funktion in der lokalen Umgebung.

Hinzufügen zu einem Skillset

Nun, da Sie über einen neuen benutzerdefinierten Skill verfügen, können Sie diesen zu Ihrem Skillset hinzufügen. Das folgende Beispiel zeigt, wie Sie den Skill aufrufen, um den Titel und den Autor des Dokuments in einem einzigen Feld namens „merged_title_author“ zu verketten.

Ersetzen Sie [your-function-url-here] durch die URL Ihrer neuen Azure Function.

{
    "skills": [
      "[... other existing skills in the skillset are here]",  
      {
        "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
        "description": "Our new search custom skill",
        "uri": "https://[your-function-url-here]",        
          "context": "/document/merged_content/organizations/*",
          "inputs": [
            {
              "name": "text1",
              "source": "/document/metadata_title"
            },
            {
              "name": "text2",
              "source": "/document/metadata_author"
            },
          ],
          "outputs": [
            {
              "name": "text",
              "targetName": "merged_title_author"
            }
          ]
      }
  ]
}

Denken Sie daran, in der Indexerdefinition eine „outputFieldMapping“ hinzuzufügen, um „merged_title_author“ an ein „fullname“-Feld im Suchindex zu senden.

"outputFieldMappings": [
    {
        "sourceFieldName": "/document/content/merged_title_author",
        "targetFieldName": "fullname"
    }
]