Beispiel: Erstellen eines benutzerdefinierten Skills mithilfe der Textübersetzungs-APIExample: Create a custom skill using the Text Translate API

In diesem Beispiel erfahren Sie, wie Sie eine benutzerdefinierte Qualifikation einer Web-API erstellen.In this example, learn how to create a web API custom skill. Diese Qualifikation akzeptiert Text in einer beliebigen Sprache und übersetzt diesen ins Englische.This skill will accept text in any language and translates it to English. Das Beispiel verwendet eine Azure-Funktion, um die Textübersetzungs-API so einzubinden, dass sie die Schnittstelle des benutzerdefinierten Skills implementiert.The example uses an Azure Function to wrap the Translate Text API so that it implements the custom skill interface.

VoraussetzungenPrerequisites

Erstellen einer Azure FunctionCreate an Azure Function

Obwohl in diesem Beispiel eine Azure-Funktion zum Hosten einer Web-API verwendet wird, ist dies nicht erforderlich.Although this example uses an Azure Function to host a web API, it isn't required. Solange Sie die Schnittstellenanforderungen für einen kognitiven Skill erfüllen, ist der gewählte Ansatz unerheblich.As long as you meet the interface requirements for a cognitive skill, the approach you take is immaterial. Mit Azure Functions ist das Erstellen eines benutzerdefinierten Skills jedoch einfacher.Azure Functions, however, make it easy to create a custom skill.

Erstellen einer Funktionen-AppCreate a function app

  1. Wählen Sie in Visual Studio im Menü „Datei“ die Optionen Neu > Projekt aus.In Visual Studio, select New > Project from the File menu.

  2. Wählen Sie im Dialogfeld „Neues Projekt“ die Option Installiert, erweitern Sie Visual C# > Cloud, und wählen Sie Azure Functions aus. Geben Sie unter „Name“ einen Namen für Ihr Projekt ein, und wählen Sie OK.In the New Project dialog, select Installed, expand Visual C# > Cloud, select Azure Functions, type a Name for your project, and select OK. Der Name der Funktions-App muss als C#-Namespace gültig sein, verwenden Sie daher keine Unterstriche, Bindestriche oder andere nicht alphanumerische Zeichen.The function app name must be valid as a C# namespace, so don't use underscores, hyphens, or any other nonalphanumeric characters.

  3. Wählen Sie Azure Functions v2 (.NET Core) aus.Select Azure Functions v2 (.NET Core). Sie können dies auch mit Version 1 erreichen, aber der nachfolgende Code basiert auf der Vorlage der Version 2.You could also do it with version 1, but the code written below is based on the v2 template.

  4. Wählen Sie für den Typ HTTP-Trigger aus.Select the type to be HTTP Trigger

  5. Für das Speicherkonto können Sie Kein auswählen, da Sie für diese Funktion keinen Speicher benötigen.For Storage Account, you may select None, as you won't need any storage for this function.

  6. Wählen Sie OK, um das Funktionsprojekt und die per HTTP ausgelöste Funktion zu erstellen.Select OK to create the function project and HTTP triggered function.

Ändern des Codes zum Aufrufen des kognitiven ÜbersetzungsdienstsModify the code to call the Translate Cognitive Service

Visual Studio erstellt ein Projekt, das eine Klasse mit den Codebausteinen für den gewählten Funktionstyp enthält.Visual Studio creates a project and in it a class that contains boilerplate code for the chosen function type. Mit dem FunctionName-Attribut der Methode wird der Name der Funktion festgelegt.The FunctionName attribute on the method sets the name of the function. Mit dem HttpTrigger-Attribut wird angegeben, dass die Funktion mit einer HTTP-Anforderung ausgelöst wird.The HttpTrigger attribute specifies that the function is triggered by an HTTP request.

Ersetzen Sie alle Inhalte der Datei Function1.cs nun durch den folgenden Code:Now, replace all of the content of the file Function1.cs with the following code:

using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;

namespace TranslateFunction
{
    // This function will simply translate messages sent to it.
    public static class Function1
    {
        static string path = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0";

        // NOTE: Replace this example key with a valid subscription key.
        static string key = "<enter your api key here>";

        #region classes used to serialize the response
        private class WebApiResponseError
        {
            public string message { get; set; }
        }

        private class WebApiResponseWarning
        {
            public string message { get; set; }
        }

        private class WebApiResponseRecord
        {
            public string recordId { get; set; }
            public Dictionary<string, object> data { get; set; }
            public List<WebApiResponseError> errors { get; set; }
            public List<WebApiResponseWarning> warnings { get; set; }
        }

        private class WebApiEnricherResponse
        {
            public List<WebApiResponseRecord> values { get; set; }
        }
        #endregion

        [FunctionName("Translate")]
        public static IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequest req,
            TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            string recordId = null;
            string originalText = null;
            string toLanguage = null;
            string translatedText = null;

            string requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data = JsonConvert.DeserializeObject(requestBody);

            // Validation
            if (data?.values == null)
            {
                return new BadRequestObjectResult(" Could not find values array");
            }
            if (data?.values.HasValues == false || data?.values.First.HasValues == false)
            {
                // It could not find a record, then return empty values array.
                return new BadRequestObjectResult(" Could not find valid records in values array");
            }

            recordId = data?.values?.First?.recordId?.Value as string;
            originalText = data?.values?.First?.data?.text?.Value as string;
            toLanguage = data?.values?.First?.data?.language?.Value as string;

            if (recordId == null)
            {
                return new BadRequestObjectResult("recordId cannot be null");
            }

            translatedText = TranslateText(originalText, toLanguage).Result;
        
            // Put together response.
            WebApiResponseRecord responseRecord = new WebApiResponseRecord();
            responseRecord.data = new Dictionary<string, object>();
            responseRecord.recordId = recordId;
            responseRecord.data.Add("text", translatedText);

            WebApiEnricherResponse response = new WebApiEnricherResponse();
            response.values = new List<WebApiResponseRecord>();
            response.values.Add(responseRecord);

            return (ActionResult)new OkObjectResult(response);
        }


        /// <summary>
        /// Use Cognitive Service to translate text from one language to another.
        /// </summary>
        /// <param name="originalText">The text to translate.</param>
        /// <param name="toLanguage">The language you want to translate to.</param>
        /// <returns>Asynchronous task that returns the translated text. </returns>
        async static Task<string> TranslateText(string originalText, string toLanguage)
        {
            System.Object[] body = new System.Object[] { new { Text = originalText } };
            var requestBody = JsonConvert.SerializeObject(body);

            var uri = $"{path}&to={toLanguage}";

            string result = "";

            using (var client = new HttpClient())
            using (var request = new HttpRequestMessage())
            {
                request.Method = HttpMethod.Post;
                request.RequestUri = new Uri(uri);
                request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
                request.Headers.Add("Ocp-Apim-Subscription-Key", key);

                var response = await client.SendAsync(request);
                var responseBody = await response.Content.ReadAsStringAsync();

                dynamic data = JsonConvert.DeserializeObject(responseBody);
                result = data?.First?.translations?.First?.text?.Value as string;

            }
            return result;
        }
    }
}

Stellen Sie sicher, dass Sie Ihren eigenen key-Wert in die TranslateText-Methode eingeben, der auf dem Schlüssel basiert, den Sie bei der Anmeldung für die Textübersetzungs-API erhalten haben.Make sure to enter your own key value in the TranslateText method based on the key you got when signing up for the Translate Text API.

Dieses Beispiel ist eine einfache Anreicherungsfunktion, die immer nur an einem Datensatz arbeitet.This example is a simple enricher that only works on one record at a time. Diese Tatsache wird später wichtig, wenn die Batchgröße für den Skillset festgelegt wird.This fact becomes important later, when setting the batch size for the skillset.

Testen der Funktion aus Visual StudioTest the function from Visual Studio

Drücken Sie F5, um das Programm- und Testfunktionsverhalten auszuführen.Press F5 to run the program and test function behaviors. In diesem Fall wird die Funktion unten verwendet, um einen spanischen Text ins Englische zu übersetzen.In this case, we'll use the function below to translate a text in Spanish to English. Verwenden Sie Postman oder Fiddler, um einen Aufruf wie den unten gezeigten auszugeben:Use Postman or Fiddler to issue a call like the one shown below:

POST https://localhost:7071/api/Translate

AnforderungstextRequest body

{
   "values": [
        {
            "recordId": "a1",
            "data":
            {
               "text":  "Este es un contrato en Inglés",
               "language": "en"
            }
        }
   ]
}

responseResponse

Die Antwort sollte in etwa wie hier dargestellt aussehen:You should see a response similar to the following example:

{
    "values": [
        {
            "recordId": "a1",
            "data": {
                "text": "This is a contract in English"
            },
            "errors": null,
            "warnings": null
        }
    ]
}

Veröffentlichen der Funktion in AzurePublish the function to Azure

Wenn Sie mit dem Funktionsverhalten zufrieden sind, können Sie sie veröffentlichen.When you're satisfied with the function behavior, you can publish it.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Veröffentlichen aus.In Solution Explorer, right-click the project and select Publish. Wählen Sie Neu erstellen > Veröffentlichen.Choose Create New > Publish.

  2. Wenn Sie Visual Studio noch nicht mit Ihrem Azure-Konto verbunden haben, wählen Sie Konto hinzufügen... aus.If you haven't already connected Visual Studio to your Azure account, select Add an account....

  3. Befolgen Sie die Anweisungen auf dem Bildschirm.Follow the on-screen prompts. Sie werden aufgefordert, das Azure-Konto, die Ressourcengruppe, den Hostingplan und das gewünschte Speicherkonto anzugeben.You're asked to specify the Azure account, the resource group, the hosting plan, and the storage account you want to use. Sie können eine neue Ressourcengruppe, einen neuen Hostingplan und ein Speicherkonto erstellen, wenn Sie noch nicht über diese verfügen.You can create a new resource group, a new hosting plan, and a storage account if you don't already have these. Wenn Sie fertig sind, klicken Sie auf Erstellen.When finished, select Create

  4. Beachten Sie die Website-URL nach Abschluss der Bereitstellung.After the deployment is complete, notice the Site URL. Es ist die Adresse der Funktions-App in Azure.It is the address of your function app in Azure.

  5. Navigieren Sie im Azure-Portal zur Ressourcengruppe, und suchen Sie nach der von Ihnen veröffentlichten Übersetzungsfunktion.In the Azure portal, navigate to the Resource Group, and look for the Translate Function you published. Im Abschnitt Verwalten sollten Sie Hostschlüssel angezeigt werden.Under the Manage section, you should see Host Keys. Wählen Sie das Symbol Kopieren für den Hostschlüssel Standard aus.Select the Copy icon for the default host key.

Testen der Funktion in AzureTest the function in Azure

Nachdem Sie nun den Standardhostschlüssel haben, testen Sie Ihre Funktion wie folgt:Now that you have the default host key, test your function as follows:

POST https://translatecogsrch.azurewebsites.net/api/Translate?code=[enter default host key here]

AnforderungstextRequest Body

{
   "values": [
        {
            "recordId": "a1",
            "data":
            {
               "text":  "Este es un contrato en Inglés",
               "language": "en"
            }
        }
   ]
}

Dieses Beispiel sollte ein ähnliches Ergebnis liefern wie das, das Sie zuvor bei der Ausführung der Funktion in der lokalen Umgebung gesehen haben.This example should produce a similar result to the one you saw previously when running the function in the local environment.

Herstellen einer Verbindung mit Ihrer PipelineConnect to your pipeline

Nun, da Sie über einen neuen benutzerdefinierten Skill verfügen, können Sie diesen zu Ihrem Skillset hinzufügen.Now that you have a new custom skill, you can add it to your skillset. Im folgenden Beispiel wird gezeigt, wie Sie den Skill aufrufen.The example below shows you how to call the skill. Da der Skill keine Batches verarbeitet, fügen Sie eine Anweisung hinzu, dass die maximale Batchgröße nur 1 sein darf, um Dokumente einzeln zu versenden.Because the skill doesn't handle batches, add an instruction for maximum batch size to be just 1 to send documents one at a time.

{
    "skills": [
      ...,  
      {
        "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
        "description": "Our new translator custom skill",
        "uri": "https://translatecogsrch.azurewebsites.net/api/Translate?code=[enter default host key here]",
        "batchSize":1,
        "context": "/document",
        "inputs": [
          {
            "name": "text",
            "source": "/document/content"
          },
          {
            "name": "language",
            "source": "/document/destinationLanguage"
          }
        ],
        "outputs": [
          {
            "name": "text",
            "targetName": "translatedText"
          }
        ]
      }
  ]
}

Nächste SchritteNext steps

Glückwunsch!Congratulations! Sie haben Ihre erste benutzerdefinierte Anreicherungsfunktion erstellt.You've created your first custom enricher. Nun können Sie Ihre eigene benutzerdefinierte Funktionalität nach dem gleichen Muster hinzufügen.Now you can follow the same pattern to add your own custom functionality.