Implementieren einer Qualifikation

GILT FÜR: SDK v4

Sie können Qualifikationen verwenden, um einen anderen Bot zu erweitern. Eine Qualifikation (Englisch: Skill) ist ein Bot, der eine Reihe von Aufgaben für einen anderen Bot durchführen kann.

  • Die Benutzeroberfläche einer Qualifikation wird mit einem Manifest beschrieben. Entwickler, die keinen Zugriff auf den Quellcode der Qualifikation haben, können die Informationen im Manifest nutzen, um ihren „Skill-Consumer“ (also den „Verbraucher der Qualifikation“) zu entwerfen.
  • Für eine Qualifikation kann die Anspruchsüberprüfung verwendet werden, um zu verwalten, welche Bots oder Benutzer darauf zugreifen können.

In diesem Artikel wird veranschaulicht, wie Sie eine Qualifikation implementieren, die die Eingabe des Benutzers wiederholt.

Einige Typen von Skillconsumern sind nicht in der Lage, einige Typen von Skill-Bots zu verwenden. In der folgenden Tabelle wird beschrieben, welche Kombinationen unterstützt werden.

  Mehrinstanzenfähiger Skill Single-Tenant-Skill Skill der benutzerseitig zugewiesenen verwalteten Identität
Mehrinstanzenfähige Verbraucher Unterstützt Nicht unterstützt Nicht unterstützt
Einzelinstanzenfähige Verbraucher Nicht unterstützt Unterstützt, wenn beide Apps zu demselben Mandanten gehören Unterstützt, wenn beide Apps zu demselben Mandanten gehören
Consumer einer benutzerseitig zugewiesenen verwalteten Identität Nicht unterstützt Unterstützt, wenn beide Apps zu demselben Mandanten gehören Unterstützt, wenn beide Apps zu demselben Mandanten gehören

Hinweis

Die Bot Framework-JavaScript-, C#- und Python-SDKs werden weiterhin unterstützt, das Java SDK wird jedoch eingestellt und der langfristige Support endet im November 2023. Es werden nur kritische Sicherheits- und Programmfehlerbehebungen innerhalb dieses Repositorys durchgeführt.

Bestehende Bots, die mit dem Java SDK erstellt wurden, werden weiterhin funktionieren.

Wenn Sie einen neuen Bot erstellen möchten, sollten Sie den Einsatz von Power Virtual Agents in Betracht ziehen und sich über die Auswahl der richtigen Chatbot-Lösung informieren.

Weitere Informationen finden Sie unter Die Zukunft des Bot-Buildings.

Voraussetzungen

Hinweis

Ab Version 4.11 benötigen Sie keine App-ID und kein Passwort, um einen Skill lokal im Bot Framework Emulator zu testen. Ein Azure-Abonnement ist weiterhin erforderlich, um Ihre Skills in Azure bereitzustellen.

Informationen zu diesem Beispiel

Das Beispiel skills simple bot-to-bot enthält Projekte für zwei Bots:

  • Echo Skill Bot (Echo-Bot für Qualifikation) zum Implementieren der Qualifikation.
  • Simple Root Bot (einfacher Stamm-Bot) zum Implementieren eines Stamm-Bots, der die Qualifikation nutzt.

Der Schwerpunkt dieses Artikels liegt auf der Qualifikation, und auch die Unterstützungslogik im Bot und Adapter wird beschrieben.

Weitere Informationen zum einfachen Stamm-Bot finden Sie unter Implementieren eines Skill-Consumers.

Ressourcen

Bei eingesetzten Bots erfordert die Bot-zu-Bot-Authentifizierung, dass jeder teilnehmende Bot über gültige Identitätsinformationen verfügt. Sie können jedoch Mandanten-Skills und Skillconsumer mit dem Emulator lokal ohne App-ID und Passwort testen.

Um den Skill für benutzerseitige Bots verfügbar zu machen, registrieren Sie den Skill bei Azure. Weitere Informationen finden Sie unter Registrieren eines Bots bei Azure KI Bot Service.

Anwendungskonfiguration

Fügen Sie optional die Identitätsinformationen der Skills zur Konfigurationsdatei der Skills hinzu. Wenn entweder der Skill oder der Skillconsumer Identitätsinformationen liefert, müssen beide dies tun.

Über das Array allowed callers (Zulässige Aufrufer) kann festgelegt werden, welche Skill-Consumer auf die Qualifikation zugreifen können. Fügen Sie ein "*"-Element hinzu, um Anrufe von jedem Skillconsumer zu akzeptieren.

Hinweis

Wenn Sie Ihre Skills lokal ohne Bot-Identitätsinformationen testen, führen weder der Skill noch der Skillconsumer den Code aus, um die Anspruchsüberprüfung durchzuführen.

EchoSkillBot\appsettings.json

Fügen Sie optional die Identitätsinformationen des Skills zur Datei „appsettings.json“ hinzu.

{
  "MicrosoftAppType": "",
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "MicrosoftAppTenantId": "",

  // This is a comma separate list with the App IDs that will have access to the skill.
  // This setting is used in AllowedCallersClaimsValidator.
  // Examples: 
  //    [ "*" ] allows all callers.
  //    [ "AppId1", "AppId2" ] only allows access to parent bots with "AppId1" and "AppId2".
  "AllowedCallers": [ "*" ]
}

Aktivitätshandlerlogik

So akzeptieren Sie Eingabeparameter

Der Skill-Consumer kann Informationen an die Qualifikation senden. Eine Möglichkeit, Informationen dieser Art zu akzeptieren, ist die value-Eigenschaft in eingehenden Nachrichten. Eine andere Möglichkeit ist das Verarbeiten des Ereignisses und das Aufrufen von Aktivitäten.

Für die Qualifikation in diesem Beispiel werden keine Eingabeparameter akzeptiert.

So setzen Sie eine Bot-Konversation fort oder schließen sie ab

Wenn die Qualifikation eine Aktivität sendet, sollte diese vom Skill-Consumer an den Benutzer weitergeleitet werden.

Sie müssen aber eine endOfConversation-Aktivität senden, wenn die Qualifikation abgeschlossen ist. Andernfalls sendet der Skill-Consumer weiterhin Benutzeraktivitäten an die Qualifikation. Optional können Sie die value-Eigenschaft der Aktivität verwenden, um einen Rückgabewert einzubinden, und mit der code-Eigenschaft der Aktivität angeben, warum die Qualifikation beendet wird.

EchoSkillBot\Bots\EchoBot.cs

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Text.Contains("end") || turnContext.Activity.Text.Contains("stop"))
    {
        // Send End of conversation at the end.
        var messageText = $"ending conversation from the skill...";
        await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.IgnoringInput), cancellationToken);
        var endOfConversation = Activity.CreateEndOfConversationActivity();
        endOfConversation.Code = EndOfConversationCodes.CompletedSuccessfully;
        await turnContext.SendActivityAsync(endOfConversation, cancellationToken);
    }
    else
    {
        var messageText = $"Echo: {turnContext.Activity.Text}";
        await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.IgnoringInput), cancellationToken);
        messageText = "Say \"end\" or \"stop\" and I'll end the conversation and back to the parent.";
        await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.ExpectingInput), cancellationToken);
    }
}

So brechen Sie die Qualifikation ab

Für Qualifikationen mit mehreren Durchläufen können Sie auch endOfConversation-Aktivitäten von einem Skill-Consumer akzeptieren, damit der Consumer die aktuelle Konversation abbrechen kann.

Die Logik für diese Qualifikation ändert sich von Durchlauf zu Durchlauf nicht. Wenn Sie eine Qualifikation implementieren, von der Konversationsressourcen zugeordnet werden, sollten Sie dem Handler für das Ende der Konversation (endOfConversation) Code für die Ressourcenbereinigung hinzufügen.

EchoSkillBot\Bots\EchoBot.cs

protected override Task OnEndOfConversationActivityAsync(ITurnContext<IEndOfConversationActivity> turnContext, CancellationToken cancellationToken)
{
    // This will be called if the root bot is ending the conversation.  Sending additional messages should be
    // avoided as the conversation may have been deleted.
    // Perform cleanup of resources if needed.
    return Task.CompletedTask;
}

Validierungssteuerelement für Ansprüche

In diesem Beispiel wird eine Liste mit zulässigen Aufrufern für die Anspruchsüberprüfung verwendet. Die Liste wird in der Konfigurationsdatei der Qualifikation definiert und nach der Erstellung in das Validierungssteuerelement-Objekt eingelesen.

Sie müssen der Authentifizierungskonfiguration ein Validierungssteuerelement für Ansprüche hinzufügen. Die Ansprüche werden nach dem Authentifizierungsheader ausgewertet. Ihr Überprüfungscode sollte einen Fehler oder eine Ausnahme auslösen, um die Anforderung abzulehnen. Es kann viele Gründe geben, warum Sie eine Anforderung ggf. ablehnen möchten, die sonst authentifiziert wird. Beispiel:

  • Die Qualifikation ist Teil eines kostenpflichtigen Diensts. Benutzer, die nicht in der Datenbank sind, sollten keinen Zugriff haben.
  • Es handelt sich um eine proprietäre Qualifikation. Nur bestimmte Skill-Consumer können die Qualifikation aufrufen.

Wichtig

Wenn Sie keinen Anspruchsprüfer bereitstellen, wird Ihr Bot einen Fehler oder eine Ausnahme erzeugen, wenn er eine Aktivität vom Skillconsumer erhält.

Das SDK stellt eine AllowedCallersClaimsValidator-Klasse bereit, die die Autorisierung auf Anwendungsebene basierend auf einer einfachen Liste der IDs der Anwendungen hinzufügt, die den Skill aufrufen dürfen. Wenn die Liste ein Sternchen (*) enthält, sind alle Anrufer zulässig. Der Anspruchsprüfer wird in Startup.cs konfiguriert.

Adapter für Qualifikation

Wenn ein Fehler auftritt, sollte der Adapter der Qualifikation den Konversationszustand für die Qualifikation löschen und eine endOfConversation-Aktivität an den Skill-Consumer senden. Verwenden Sie die code-Eigenschaft der Aktivität, um zu signalisieren, dass die Qualifikation aufgrund eines Fehlers beendet wurde.

EchoSkillBot\SkillAdapterWithErrorHandler.cs

private async Task HandleTurnError(ITurnContext turnContext, Exception exception)
{
    // Log any leaked exception from the application.
    _logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

    await SendErrorMessageAsync(turnContext, exception);
    await SendEoCToParentAsync(turnContext, exception);
}

private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception)
{
    try
    {
        // Send a message to the user.
        var errorMessageText = "The skill encountered an error or bug.";
        var errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.IgnoringInput);
        await turnContext.SendActivityAsync(errorMessage);

        errorMessageText = "To continue to run this bot, please fix the bot source code.";
        errorMessage = MessageFactory.Text(errorMessageText, errorMessageText, InputHints.ExpectingInput);
        await turnContext.SendActivityAsync(errorMessage);

        // Send a trace activity, which will be displayed in the Bot Framework Emulator.
        // Note: we return the entire exception in the value property to help the developer;
        // this should not be done in production.
        await turnContext.TraceActivityAsync("OnTurnError Trace", exception.ToString(), "https://www.botframework.com/schemas/error", "TurnError");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught in SendErrorMessageAsync : {ex}");
    }
}

private async Task SendEoCToParentAsync(ITurnContext turnContext, Exception exception)
{
    try
    {
        // Send an EndOfConversation activity to the skill caller with the error to end the conversation,
        // and let the caller decide what to do.
        var endOfConversation = Activity.CreateEndOfConversationActivity();
        endOfConversation.Code = "SkillError";
        endOfConversation.Text = exception.Message;
        await turnContext.SendActivityAsync(endOfConversation);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught in SendEoCToParentAsync : {ex}");
    }
}

Dienstregistrierung

Der Bot Framework-Adapter nutzt ein Objekt für die Authentifizierungskonfiguration (wird bei der Erstellung des Adapters festgelegt), um den Authentifizierungsheader für eingehende Anforderungen zu überprüfen.

In diesem Beispiel wird der Authentifizierungskonfiguration eine Überprüfung für Ansprüche hinzugefügt und der Adapter für Qualifikationen mit Fehlerhandler verwendet, der im vorherigen Abschnitt beschrieben wurde.

EchoSkillBot\Startup.cs

    options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth;
});

// Register AuthConfiguration to enable custom claim validation.
services.AddSingleton(sp =>
{
    var allowedCallers = new List<string>(sp.GetService<IConfiguration>().GetSection("AllowedCallers").Get<string[]>());

    var claimsValidator = new AllowedCallersClaimsValidator(allowedCallers);

    // If TenantId is specified in config, add the tenant as a valid JWT token issuer for Bot to Skill conversation.
    // The token issuer for MSI and single tenant scenarios will be the tenant where the bot is registered.
    var validTokenIssuers = new List<string>();
    var tenantId = sp.GetService<IConfiguration>().GetSection(MicrosoftAppCredentials.MicrosoftAppTenantIdKey)?.Value;

    if (!string.IsNullOrWhiteSpace(tenantId))
    {
        // For SingleTenant/MSI auth, the JWT tokens will be issued from the bot's home tenant.
        // Therefore, these issuers need to be added to the list of valid token issuers for authenticating activity requests.
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidTokenIssuerUrlTemplateV1, tenantId));
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidTokenIssuerUrlTemplateV2, tenantId));
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV1, tenantId));
        validTokenIssuers.Add(string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ValidGovernmentTokenIssuerUrlTemplateV2, tenantId));
    }

    return new AuthenticationConfiguration
    {
        ClaimsValidator = claimsValidator,
        ValidTokenIssuers = validTokenIssuers
    };
});

// Create the Bot Framework Authentication to be used with the Bot Adapter.
services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();

Qualifikationsmanifest

Ein Qualifikationsmanifest ist eine JSON-Datei, in der die von der Qualifikation durchführbaren Aktivitäten, die Eingabe- und Ausgabeparameter und die Endpunkte der Qualifikation beschrieben sind. Das Manifest enthält die Informationen, die Sie für den Zugriff auf die Qualifikation mit einem anderen Bot benötigen. Die neueste Schema-Version ist v2.1.

EchoSkillBot\wwwroot\manifest\echoskillbot-manifest-1.0.json

{
  "$schema": "https://schemas.botframework.com/schemas/skills/skill-manifest-2.0.0.json",
  "$id": "EchoSkillBot",
  "name": "Echo Skill bot",
  "version": "1.0",
  "description": "This is a sample echo skill",
  "publisherName": "Microsoft",
  "privacyUrl": "https://echoskillbot.contoso.com/privacy.html",
  "copyright": "Copyright (c) Microsoft Corporation. All rights reserved.",
  "license": "",
  "iconUrl": "https://echoskillbot.contoso.com/icon.png",
  "tags": [
    "sample",
    "echo"
  ],
  "endpoints": [
    {
      "name": "default",
      "protocol": "BotFrameworkV3",
      "description": "Default endpoint for the skill",
      "endpointUrl": "http://echoskillbot.contoso.com/api/messages",
      "msAppId": "00000000-0000-0000-0000-000000000000"
    }
  ]
}

Das Schema des Qualifikationsmanifests ist eine JSON-Datei, in der das Schema des Qualifikationsmanifests beschrieben ist. Die aktuelle Schemaversion ist 2.1.0.

Testen der Qualifikation

An diesem Punkt können Sie die Qualifikation im Emulator testen, als ob es sich um einen regulären Bot handeln würde. Zum Testen als Qualifikation müssen Sie aber einen Skill-Consumer implementieren.

Laden Sie die aktuelle Version von Bot Framework Emulator herunter, und installieren Sie sie.

  1. Führen Sie den „Echo Skill Bot“ lokal auf Ihrem Computer aus. Wenn Sie eine Anleitung benötigen, helfen Ihnen die README-Datei des Beispiels für C#, JavaScript, Java oder Python weiter.
  2. Verwenden Sie den Emulator, um den Bot wie unten dargestellt zu testen. Wenn Sie eine „end“- oder „stop“-Nachricht an die Qualifikation senden, wird zusätzlich zur Antwortnachricht eine endOfConversation-Aktivität gesendet. Die Qualifikation sendet die endOfConversation-Aktivität, um anzugeben, dass die Qualifikation beendet wurde.

Example transcript showing the end-of-conversation activity.

Mehr über Debuggen

Da der Datenverkehr zwischen Skills und Skill-Verbraucher authentifiziert wird, gibt es zusätzliche Schritte beim Debuggen solcher Bots.

  • Der Skill-Verbraucher und alle Skills, die er direkt oder indirekt verbraucht, müssen ausgeführt werden.
  • Wenn die Bots lokal ausgeführt werden und einer der Bots über eine App-ID und ein Passwort verfügt, müssen alle Bots gültige IDs und Passwörter besitzen.
  • Wenn alle Bots bereitgestellt werden, erfahren Sie, wie Sie einen Bot über einen beliebigen Kanal mit ngrok debuggen.
  • Wenn einige der Bots lokal ausgeführt werden und einige bereitgestellt werden, erfahren Sie, wie Sie einen Skill oder einen Skill-Verbraucher debuggen.

Andernfalls können Sie einen Skill-Verbraucher oder einen Skill ähnlich debuggen, wie Sie andere Bots debuggen. Weitere Informationen finden Sie unter Debuggen eines Bots und Debuggen mit dem Bot Framework Emulator.

Nächste Schritte