Implementace dovednosti

PLATÍ PRO: SDK v4

Dovednosti můžete využít k rozšíření dalšího robota. Dovednost je robot, který může provádět sadu úkolů pro jiného robota.

  • Rozhraní dovednosti je popsáno manifestem. Vývojáři, kteří nemají přístup ke zdrojovému kódu dovednosti, můžou informace v manifestu použít k návrhu příjemce dovedností.
  • Dovednost může pomocí ověřování deklarací identity spravovat roboty nebo uživatele, kteří k němu mají přístup.

Tento článek ukazuje, jak implementovat dovednost, která odpovídá vstupu uživatele.

Některé typy uživatelů dovedností nemůžou používat některé typy robotů dovedností. Následující tabulka popisuje podporované kombinace.

  Dovednosti s více tenanty Dovednost s jedním tenantem Dovednost spravované identity přiřazené uživatelem
Příjemce s více tenanty Podporováno Nepodporováno Nepodporováno
Příjemce s jedním tenantem Nepodporováno Podporováno, pokud obě aplikace patří do stejného tenanta Podporováno, pokud obě aplikace patří do stejného tenanta
Příjemce spravované identity přiřazené uživatelem Nepodporováno Podporováno, pokud obě aplikace patří do stejného tenanta Podporováno, pokud obě aplikace patří do stejného tenanta

Poznámka:

Sady SDK služby Bot Framework JavaScript, C# a Python budou nadále podporovány, ale sada Java SDK se vyřazuje s konečnou dlouhodobou podporou končící v listopadu 2023.

Stávající roboti sestavení pomocí sady Java SDK budou i nadále fungovat.

Pro nové vytváření robotů zvažte použití Power Virtual Agents a přečtěte si o výběru správného řešení chatovacího robota.

Další informace najdete v tématu Budoucnost vytváření robotů.

Požadavky

Poznámka:

Počínaje verzí 4.11 nepotřebujete ID a heslo aplikace k místnímu testování dovednosti v bot Framework Emulatoru. K nasazení dovedností do Azure se stále vyžaduje předplatné Azure.

O této ukázce

Ukázka jednoduchých dovedností robota-robota zahrnuje projekty pro dva roboty:

  • Robot dovedností echo, který implementuje dovednosti.
  • Jednoduchý kořenový robot, který implementuje kořenového robota, který tuto dovednost využívá.

Tento článek se zaměřuje na dovednost, která zahrnuje logiku podpory v robotovi a adaptéru.

Informace o jednoduchém kořenovém robotovi najdete v tématu Implementace příjemce dovedností.

Zdroje informací

U nasazených robotů vyžaduje ověřování robota k robotovi, aby měl každý účastník platné informace o identitě. Můžete ale otestovat dovednosti s více tenanty a uživatele dovedností místně pomocí emulátoru bez ID aplikace a hesla.

Pokud chcete, aby byla dovednost dostupná pro uživatelem robotů, zaregistrujte si dovednost v Azure. Další informace najdete v tématu registrace robota ve službě Azure AI Bot Service.

Konfigurace aplikací

Volitelně můžete do konfiguračního souboru přidat informace o identitě dovednosti. Pokud dovednost nebo spotřebitel dovedností poskytuje informace o identitě, musí být obojí.

Pole povolených volajících může omezit, ke kterým dovednostem mají uživatelé přístup. Přidejte prvek "*", který bude přijímat volání od libovolného příjemce dovedností.

Poznámka:

Pokud testujete svoji dovednost místně bez informací o identitě robota, dovednost ani uživatel dovednosti nespustí kód k ověření deklarací identity.

EchoSkillBot\appsettings.json

Volitelně můžete do souboru appsettings.json přidat informace o identitě dovednosti.

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

Logika obslužné rutiny aktivity

Přijetí vstupních parametrů

Spotřebitel dovedností může posílat informace do dovednosti. Jedním ze způsobů, jak tyto informace přijmout, je přijmout je prostřednictvím vlastnosti hodnoty příchozích zpráv. Dalším způsobem je zpracování událostí a vyvolání aktivit.

Dovednost v tomto příkladu nepřijímá vstupní parametry.

Pokračování nebo dokončení konverzace

Když dovednost odešle aktivitu, uživatel dovednosti by měl aktivitu předat uživateli.

Když se ale dovednost dokončí, musíte odeslat endOfConversation aktivitu. Jinak bude spotřebitel dovedností dál předávat aktivity uživatelů této dovednosti. Volitelně můžete použít vlastnost hodnoty aktivity k zahrnutí návratové hodnoty a pomocí vlastnosti kódu aktivity určit, proč dovednost končí.

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);
    }
}

Zrušení dovednosti

V případě vícenásobných dovedností byste také přijali endOfConversation aktivity od příjemce dovedností, aby spotřebitel mohl aktuální konverzaci zrušit.

Logika pro tuto dovednost se nemění z střídmého otáčení. Pokud implementujete dovednost, která přiděluje prostředky konverzace, přidejte do obslužné rutiny konverzace kód čištění prostředků.

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;
}

Validátor deklarací identity

Tato ukázka používá seznam povolených volajících k ověření deklarací identity. Seznam je definován v konfiguračním souboru dovednosti a při jeho vytvoření se načte do objektu validátoru.

Do konfigurace ověřování musíte přidat validátor deklarací identity. Deklarace identity se vyhodnocují za hlavičkou ověřování. Ověřovací kód by měl vyvolat chybu nebo výjimku, aby požadavek odmítl. Existuje mnoho důvodů, proč můžete chtít odmítnout jinak ověřený požadavek. Příklad:

  • Dovednost je součástí placené služby. Uživatel není v databázi by neměl mít přístup.
  • Dovednost je proprietární. Dovednost může zavolat pouze někteří spotřebitelé dovedností.

Důležité

Pokud nezadáte validátor deklarací identity, robot při přijetí aktivity od příjemce dovednosti vygeneruje chybu nebo výjimku.

Sada SDK poskytuje AllowedCallersClaimsValidator třídu, která přidává autorizaci na úrovni aplikace na základě jednoduchého seznamu ID aplikací, které mohou volat dovednosti. Pokud seznam obsahuje hvězdičku (*), jsou všichni volající povoleni. Validátor deklarací identity je nakonfigurovaný v Startup.cs.

Adaptér dovedností

Když dojde k chybě, adaptér dovednosti by měl vymazat stav konverzace dovednosti a měl by také odeslat endOfConversation aktivitu příjemci dovednosti. Pomocí vlastnosti kódu aktivity signalizovat, že dovednost skončila kvůli chybě.

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}");
    }
}

Registrace služby

Adaptér Bot Framework používá objekt konfigurace ověřování (nastavený při vytvoření adaptéru) k ověření hlavičky ověřování u příchozích požadavků.

Tato ukázka přidává ověřování deklarací identity do konfigurace ověřování a používá adaptér dovedností s obslužnou rutinou chyb popsanou v předchozí části.

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>();

Manifest dovednosti

Manifest dovednosti je soubor JSON, který popisuje aktivity, které může dovednost provádět, její vstupní a výstupní parametry a koncové body dovednosti. Manifest obsahuje informace, které potřebujete pro přístup ke dovednosti z jiného robota. Nejnovější verze schématu je verze 2.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"
    }
  ]
}

Schéma manifestu dovedností je soubor JSON, který popisuje schéma manifestu dovednosti. Aktuální verze schématu je 2.1.0.

Otestování dovednosti

V tomto okamžiku můžete otestovat dovednosti v emulátoru, jako by šlo o normálního robota. Pokud ho ale chcete otestovat jako dovednost, musíte implementovat dovednost spotřebitele.

Stažení a instalace nejnovější aplikace Bot Framework Emulator

  1. Spusťte robota dovedností echo místně na svém počítači. Pokud potřebujete pokyny, projděte si README soubor ukázky C#, JavaScriptu, Javy nebo Pythonu .
  2. Pomocí emulátoru otestujte robota, jak je znázorněno níže. Když dovednost pošlete zprávu "end" nebo "stop", odešle endOfConversation aktivitu kromě zprávy odpovědi. Dovednost odešle endOfConversation aktivitu, která označuje, že dovednost skončila.

Příklad přepisu znázorňující aktivitu na konci konverzace

Další informace o ladění

Vzhledem k tomu, že se ověřuje provoz mezi dovednostmi a uživateli dovedností, při ladění takových robotů existují další kroky.

Jinak můžete ladit dovednost uživatele nebo dovednosti podobně jako ostatní roboty. Další informace naleznete v tématu Ladění robota a ladění pomocí bot Framework Emulator.

Další kroky