Udostępnij za pośrednictwem


Implementowanie konsumenta umiejętności

DOTYCZY: ZESTAW SDK w wersji 4

Możesz użyć umiejętności, aby rozszerzyć innego bota. Umiejętność to bot, który może wykonywać zestaw zadań dla innego bota i używa manifestu do opisania interfejsu. Bot główny to bot skierowany do użytkownika, który może wywołać co najmniej jedną umiejętności. Bot główny jest typem konsumenta umiejętności.

  • Użytkownik umiejętności musi używać weryfikacji oświadczeń, aby zarządzać tymi umiejętnościami, które mogą uzyskiwać do niego dostęp.
  • Użytkownik umiejętności może korzystać z wielu umiejętności.
  • Deweloperzy, którzy nie mają dostępu do kodu źródłowego umiejętności, mogą używać informacji w manifeście umiejętności, aby zaprojektować swojego konsumenta umiejętności.

W tym artykule pokazano, jak zaimplementować konsumenta umiejętności, który używa umiejętności echa do echa danych wejściowych użytkownika. Aby zapoznać się z przykładowym manifestem umiejętności i informacjami na temat implementowania umiejętności echa, zobacz, jak zaimplementować umiejętności.

Aby uzyskać informacje na temat korzystania z okna dialogowego umiejętności do korzystania z umiejętności, zobacz, jak używać okna dialogowego do korzystania z umiejętności.

Niektóre typy konsumentów umiejętności nie mogą używać niektórych typów botów umiejętności. W poniższej tabeli opisano, które kombinacje są obsługiwane.

  Umiejętność obsługi wielu dzierżaw Umiejętność z jedną dzierżawą Umiejętność tożsamości zarządzanej przypisanej przez użytkownika
Użytkownik z wieloma dzierżawami Obsługiwane Nieobsługiwane Nieobsługiwane
Użytkownik z jedną dzierżawą Nieobsługiwane Obsługiwane, jeśli obie aplikacje należą do tej samej dzierżawy Obsługiwane, jeśli obie aplikacje należą do tej samej dzierżawy
Odbiorca tożsamości zarządzanej przypisanej przez użytkownika Nieobsługiwane Obsługiwane, jeśli obie aplikacje należą do tej samej dzierżawy Obsługiwane, jeśli obie aplikacje należą do tej samej dzierżawy

Uwaga

Zestawy SDK języka JavaScript, C# i Python platformy Bot Framework będą nadal obsługiwane, jednak zestaw SDK języka Java jest wycofywany z ostatecznym długoterminowym wsparciem kończącym się w listopadzie 2023 r.

Istniejące boty utworzone za pomocą zestawu JAVA SDK będą nadal działać.

W przypadku tworzenia nowego bota rozważ użycie agentów usługi Power Virtual Agents i przeczytaj o wyborze odpowiedniego rozwiązania czatbota.

Aby uzyskać więcej informacji, zobacz Przyszłość tworzenia botów.

Wymagania wstępne

Uwaga

Począwszy od wersji 4.11, nie potrzebujesz identyfikatora aplikacji i hasła, aby przetestować użytkownika umiejętności lokalnie w emulatorze bot framework. Subskrypcja platformy Azure jest nadal wymagana do wdrożenia konsumenta na platformie Azure lub korzystania z wdrożonej umiejętności.

Informacje o tym przykładzie

Przykładowe umiejętności prostego bota do bota obejmują projekty dla dwóch botów:

  • Bot umiejętności echo, który implementuje umiejętności.
  • Prosty bot główny, który implementuje bota głównego, który korzysta z umiejętności.

Ten artykuł koncentruje się na botze głównym, który obejmuje logikę obsługi w obiektach bota i adaptera oraz zawiera obiekty używane do wymiany działań z umiejętnością. Są to:

  • Klient umiejętności używany do wysyłania działań do umiejętności.
  • Program obsługi umiejętności, używany do odbierania działań z poziomu umiejętności.
  • Fabryka identyfikatorów konwersacji umiejętności używana przez klienta umiejętności i program obsługi do tłumaczenia między odwołaniem do konwersacji root użytkownika i odwołaniem do konwersacji z umiejętnościami głównymi.

Aby uzyskać informacje na temat bota umiejętności echo, zobacz implementowanie umiejętności.

Zasoby

W przypadku wdrożonych botów uwierzytelnianie bot-to-bot wymaga, aby każdy uczestniczący bot miał prawidłowe informacje o tożsamości. Można jednak testować umiejętności i umiejętności użytkowników z wieloma dzierżawami lokalnie za pomocą emulatora bez identyfikatora aplikacji i hasła.

Konfiguracja aplikacji

  1. Opcjonalnie dodaj informacje o tożsamości głównego bota do pliku konfiguracji. Jeśli użytkownik umiejętności lub umiejętności dostarcza informacje o tożsamości, oba muszą.
  2. Dodaj punkt końcowy hosta umiejętności (adres URL usługi lub wywołania zwrotnego), do którego umiejętności powinny odpowiadać użytkownik umiejętności.
  3. Dodaj wpis dla każdej umiejętności, której będzie używać użytkownik umiejętności. Każdy wpis obejmuje:
    • Identyfikator używany przez konsumenta umiejętności do identyfikowania każdej umiejętności.
    • Opcjonalnie aplikacja umiejętności lub identyfikator klienta.
    • Punkt końcowy obsługi komunikatów umiejętności.

Uwaga

Jeśli użytkownik umiejętności lub umiejętności dostarcza informacje o tożsamości, oba muszą.

SimpleRootBot\appsettings.json

Opcjonalnie dodaj informacje o tożsamości głównego bota i dodaj identyfikator aplikacji lub klienta bota umiejętności echa.

{
  "MicrosoftAppType": "",
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "MicrosoftAppTenantId": "",
  "SkillHostEndpoint": "http://localhost:3978/api/skills/",
  "BotFrameworkSkills": [
    {
      "Id": "EchoSkillBot",
      "AppId": "",
      "SkillEndpoint": "http://localhost:39783/api/messages"
    }
  ]
}

Konfiguracja umiejętności

Ten przykład odczytuje informacje dotyczące każdej umiejętności w pliku konfiguracji w kolekcji obiektów umiejętności .

SimpleRootBot\SkillsConfiguration.cs

public class SkillsConfiguration
{
    public SkillsConfiguration(IConfiguration configuration)
    {
        var section = configuration?.GetSection("BotFrameworkSkills");
        var skills = section?.Get<BotFrameworkSkill[]>();
        if (skills != null)
        {
            foreach (var skill in skills)
            {
                Skills.Add(skill.Id, skill);
            }
        }

        var skillHostEndpoint = configuration?.GetValue<string>(nameof(SkillHostEndpoint));
        if (!string.IsNullOrWhiteSpace(skillHostEndpoint))
        {
            SkillHostEndpoint = new Uri(skillHostEndpoint);
        }
    }

    public Uri SkillHostEndpoint { get; }

    public Dictionary<string, BotFrameworkSkill> Skills { get; } = new Dictionary<string, BotFrameworkSkill>();
}

Fabryka identyfikatorów konwersacji

Spowoduje to utworzenie identyfikatora konwersacji do użycia z umiejętnością i odzyskanie oryginalnego identyfikatora konwersacji użytkownika na podstawie identyfikatora konwersacji umiejętności.

Fabryka identyfikatorów konwersacji dla tego przykładu obsługuje prosty scenariusz, w którym:

  • Bot główny jest przeznaczony do korzystania z jednej konkretnej umiejętności.
  • Bot główny ma tylko jedną aktywną konwersację z umiejętnością naraz.

Zestaw SDK udostępnia klasę SkillConversationIdFactory , która może być używana w dowolnej umiejętności bez konieczności replikowania kodu źródłowego. Fabryka identyfikatorów konwersacji jest skonfigurowana w Startup.cs.

Aby obsługiwać bardziej złożone scenariusze, zaprojektuj fabrykę identyfikatorów konwersacji, aby:

  • Metoda tworzenia identyfikatora konwersacji umiejętności pobiera lub generuje odpowiedni identyfikator konwersacji umiejętności.
  • Metoda uzyskiwania odwołania do konwersacji pobiera prawidłową konwersację użytkownika.

Umiejętność klienta i procedury obsługi umiejętności

Użytkownik umiejętności używa klienta umiejętności do przekazywania działań do umiejętności. W tym celu klient korzysta z informacji o konfiguracji umiejętności i fabryki identyfikatorów konwersacji.

Użytkownik umiejętności używa programu obsługi umiejętności do odbierania działań z poziomu umiejętności. Procedura obsługi używa fabryki identyfikatorów konwersacji, konfiguracji uwierzytelniania i dostawcy poświadczeń do tego celu, a także ma zależności od karty głównej bota i procedury obsługi działań

SimpleRootBot\Startup.cs

services.AddSingleton<IBotFrameworkHttpAdapter>(sp => sp.GetService<CloudAdapter>());
services.AddSingleton<BotAdapter>(sp => sp.GetService<CloudAdapter>());

Ruch HTTP z umiejętności wejdzie do punktu końcowego adresu URL usługi, który użytkownik umiejętności anonsuje do umiejętności. Użyj programu obsługi punktu końcowego specyficznego dla języka, aby przekazać ruch do programu obsługi umiejętności.

Domyślny program obsługi umiejętności:

  • Jeśli istnieje identyfikator aplikacji i hasło, użyje obiektu konfiguracji uwierzytelniania do przeprowadzenia zarówno uwierzytelniania bota do bota, jak i weryfikacji oświadczeń.
  • Używa fabryki identyfikatorów konwersacji do tłumaczenia konwersacji z konwersacji z użytkownikiem głównym.
  • Generuje proaktywny komunikat, dzięki czemu użytkownik umiejętności może ponownie opublikować kontekst zwrotu użytkownika głównego i przekazać działania użytkownikowi.

Logika obsługi działań

Należy pamiętać, że logika konsumenta umiejętności powinna:

  • Należy pamiętać, czy istnieją jakieś aktywne umiejętności i w razie potrzeby przekazywać do nich działania.
  • Zwróć uwagę, że użytkownik wysyła żądanie, które powinno zostać przekazane do umiejętności, i rozpocznij umiejętności.
  • Poszukaj aktywności z dowolnej aktywnej endOfConversation umiejętności, aby zobaczyć, kiedy zostanie ukończona.
  • W razie potrzeby dodaj logikę, aby umożliwić użytkownikowi lub użytkownikowi umiejętności anulowanie umiejętności, które nie zostały jeszcze ukończone.
  • Zapisz stan przed wywołaniem umiejętności, ponieważ każda odpowiedź może wrócić do innego wystąpienia konsumenta umiejętności.

SimpleRootBot\Bots\RootBot.cs

Główny bot ma zależności od stanu konwersacji, informacji o umiejętnościach, klienta umiejętności i ogólnej konfiguracji. ASP.NET zapewnia te obiekty poprzez wstrzyknięcie zależności. Bot główny definiuje również metodę dostępu do właściwości stanu konwersacji w celu śledzenia, która umiejętność jest aktywna.

public static readonly string ActiveSkillPropertyName = $"{typeof(RootBot).FullName}.ActiveSkillProperty";
private readonly IStatePropertyAccessor<BotFrameworkSkill> _activeSkillProperty;
private readonly string _botId;
private readonly ConversationState _conversationState;
private readonly BotFrameworkAuthentication _auth;
private readonly SkillConversationIdFactoryBase _conversationIdFactory;
private readonly SkillsConfiguration _skillsConfig;
private readonly BotFrameworkSkill _targetSkill;

public RootBot(BotFrameworkAuthentication auth, ConversationState conversationState, SkillsConfiguration skillsConfig, SkillConversationIdFactoryBase conversationIdFactory, IConfiguration configuration)
{
    _auth = auth ?? throw new ArgumentNullException(nameof(auth));
    _conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
    _skillsConfig = skillsConfig ?? throw new ArgumentNullException(nameof(skillsConfig));
    _conversationIdFactory = conversationIdFactory ?? throw new ArgumentNullException(nameof(conversationIdFactory));

    if (configuration == null)
    {
        throw new ArgumentNullException(nameof(configuration));
    }

    _botId = configuration.GetSection(MicrosoftAppCredentials.MicrosoftAppIdKey)?.Value;

    // We use a single skill in this example.
    var targetSkillId = "EchoSkillBot";
    _skillsConfig.Skills.TryGetValue(targetSkillId, out _targetSkill);

    // Create state property to track the active skill
    _activeSkillProperty = conversationState.CreateProperty<BotFrameworkSkill>(ActiveSkillPropertyName);
}

Ten przykład zawiera metodę pomocnika przekazywania działań do umiejętności. Zapisuje stan konwersacji przed wywołaniem umiejętności i sprawdza, czy żądanie HTTP zakończyło się pomyślnie.

private async Task SendToSkill(ITurnContext turnContext, BotFrameworkSkill targetSkill, CancellationToken cancellationToken)
{
    // NOTE: Always SaveChanges() before calling a skill so that any activity generated by the skill
    // will have access to current accurate state.
    await _conversationState.SaveChangesAsync(turnContext, force: true, cancellationToken: cancellationToken);

    // Create a conversationId to interact with the skill and send the activity
    var options = new SkillConversationIdFactoryOptions
    {
        FromBotOAuthScope = turnContext.TurnState.Get<string>(BotAdapter.OAuthScopeKey),
        FromBotId = _botId,
        Activity = turnContext.Activity,
        BotFrameworkSkill = targetSkill
    };
    var skillConversationId = await _conversationIdFactory.CreateSkillConversationIdAsync(options, cancellationToken);

    using var client = _auth.CreateBotFrameworkClient();

    // route the activity to the skill
    var response = await client.PostActivityAsync(_botId, targetSkill.AppId, targetSkill.SkillEndpoint, _skillsConfig.SkillHostEndpoint, skillConversationId, turnContext.Activity, cancellationToken);

    // Check response status
    if (!(response.Status >= 200 && response.Status <= 299))
    {
        throw new HttpRequestException($"Error invoking the skill id: \"{targetSkill.Id}\" at \"{targetSkill.SkillEndpoint}\" (status is {response.Status}). \r\n {response.Body}");
    }
}

Należy pamiętać, że bot główny zawiera logikę przekazywania działań do umiejętności, rozpoczynanie umiejętności na żądanie użytkownika i zatrzymywanie umiejętności po ukończeniu umiejętności.

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Text.Contains("skill"))
    {
        await turnContext.SendActivityAsync(MessageFactory.Text("Got it, connecting you to the skill..."), cancellationToken);

        // Save active skill in state
        await _activeSkillProperty.SetAsync(turnContext, _targetSkill, cancellationToken);

        // Send the activity to the skill
        await SendToSkill(turnContext, _targetSkill, cancellationToken);
        return;
    }

    // just respond
    await turnContext.SendActivityAsync(MessageFactory.Text("Me no nothin'. Say \"skill\" and I'll patch you through"), cancellationToken);

    // Save conversation state
    await _conversationState.SaveChangesAsync(turnContext, force: true, cancellationToken: cancellationToken);
}

protected override async Task OnEndOfConversationActivityAsync(ITurnContext<IEndOfConversationActivity> turnContext, CancellationToken cancellationToken)
{
    // forget skill invocation
    await _activeSkillProperty.DeleteAsync(turnContext, cancellationToken);

    // Show status message, text and value returned by the skill
    var eocActivityMessage = $"Received {ActivityTypes.EndOfConversation}.\n\nCode: {turnContext.Activity.Code}";
    if (!string.IsNullOrWhiteSpace(turnContext.Activity.Text))
    {
        eocActivityMessage += $"\n\nText: {turnContext.Activity.Text}";
    }

    if ((turnContext.Activity as Activity)?.Value != null)
    {
        eocActivityMessage += $"\n\nValue: {JsonConvert.SerializeObject((turnContext.Activity as Activity)?.Value)}";
    }

    await turnContext.SendActivityAsync(MessageFactory.Text(eocActivityMessage), cancellationToken);

    // We are back at the root
    await turnContext.SendActivityAsync(MessageFactory.Text("Back in the root bot. Say \"skill\" and I'll patch you through"), cancellationToken);

    // Save conversation state
    await _conversationState.SaveChangesAsync(turnContext, cancellationToken: cancellationToken);
}

Włącz procedurę obsługi błędów

W przypadku wystąpienia błędu karta czyści stan konwersacji, aby zresetować konwersację z użytkownikiem i uniknąć utrwalania stanu błędu.

Dobrym rozwiązaniem jest wysłanie zakończenia aktywności konwersacji do jakichkolwiek aktywnych umiejętności przed wyczyszczeniem stanu konwersacji u konsumenta umiejętności. Dzięki temu można zwolnić wszelkie zasoby skojarzone z konwersacją z umiejętnościami konsumenckimi, zanim użytkownik umiejętności wyda konwersację.

SimpleRootBot\AdapterWithErrorHandler.cs

W tym przykładzie logika błędu kolei jest podzielona na kilka metod pomocnika.

private async Task HandleTurnError(ITurnContext turnContext, Exception exception)
{
    // Log any leaked exception from the application.
    // NOTE: In production environment, you should consider logging this to
    // Azure Application Insights. Visit https://aka.ms/bottelemetry to see how
    // to add telemetry capture to your bot.
    _logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

    await SendErrorMessageAsync(turnContext, exception);
    await EndSkillConversationAsync(turnContext);
    await ClearConversationStateAsync(turnContext);
}

private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception)
{
    try
    {
        // Send a message to the user
        var errorMessageText = "The bot 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
        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 EndSkillConversationAsync(ITurnContext turnContext)
{
    if (_skillsConfig == null)
    {
        return;
    }

    try
    {
        // Inform the active skill that the conversation is ended so that it has
        // a chance to clean up.
        // Note: ActiveSkillPropertyName is set by the RooBot while messages are being
        // forwarded to a Skill.
        var activeSkill = await _conversationState.CreateProperty<BotFrameworkSkill>(RootBot.ActiveSkillPropertyName).GetAsync(turnContext, () => null);
        if (activeSkill != null)
        {
            var botId = _configuration.GetSection(MicrosoftAppCredentials.MicrosoftAppIdKey)?.Value;

            var endOfConversation = Activity.CreateEndOfConversationActivity();
            endOfConversation.Code = "RootSkillError";
            endOfConversation.ApplyConversationReference(turnContext.Activity.GetConversationReference(), true);

            await _conversationState.SaveChangesAsync(turnContext, true);

            using var client = _auth.CreateBotFrameworkClient();

            await client.PostActivityAsync(botId, activeSkill.AppId, activeSkill.SkillEndpoint, _skillsConfig.SkillHostEndpoint, endOfConversation.Conversation.Id, (Activity)endOfConversation, CancellationToken.None);
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught on attempting to send EndOfConversation : {ex}");
    }
}

private async Task ClearConversationStateAsync(ITurnContext turnContext)
{
    try
    {
        // Delete the conversationState for the current conversation to prevent the
        // bot from getting stuck in a error-loop caused by being in a bad state.
        // ConversationState should be thought of as similar to "cookie-state" in a Web pages.
        await _conversationState.DeleteAsync(turnContext);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught on attempting to Delete ConversationState : {ex}");
    }
}

Punkt końcowy umiejętności

Bot definiuje punkt końcowy, który przekazuje przychodzące działania umiejętności do obsługi umiejętności bota głównego.

SimpleRootBot\Controllers\SkillController.cs

[ApiController]
[Route("api/skills")]
public class SkillController : ChannelServiceController
{
    public SkillController(ChannelServiceHandlerBase handler)
        : base(handler)
    {
    }
}

Rejestracja usługi

Uwzględnij obiekt konfiguracji uwierzytelniania z weryfikacją oświadczeń oraz wszystkie dodatkowe obiekty. W tym przykładzie użyto tej samej logiki konfiguracji uwierzytelniania do sprawdzania poprawności działań zarówno użytkowników, jak i umiejętności.

SimpleRootBot\Startup.cs

// Register the skills configuration class
services.AddSingleton<SkillsConfiguration>();

// Register AuthConfiguration to enable custom claim validation.
services.AddSingleton(sp =>
{
    var allowedSkills = sp.GetService<SkillsConfiguration>().Skills.Values.Select(s => s.AppId).ToList();

    var claimsValidator = new AllowedSkillsClaimsValidator(allowedSkills);

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

Testowanie bota głównego

Możesz przetestować użytkownika umiejętności w emulatorze tak, jakby był to normalny bot; należy jednak jednocześnie uruchamiać boty konsumpcyjne umiejętności i umiejętności. Zobacz, jak zaimplementować umiejętności , aby uzyskać informacje na temat sposobu konfigurowania umiejętności.

Pobierz i zainstaluj najnowszą wersję emulatora platformy Bot Framework

  1. Uruchom bota umiejętności echa i prostego bota głównego lokalnie na maszynie. Jeśli potrzebujesz instrukcji, zapoznaj się z plikiem README przykładowym języka C#, JavaScript, Java lub Python .
  2. Użyj emulatora, aby przetestować bota, jak pokazano poniżej. Podczas wysyłania end wiadomości lub stop do umiejętności umiejętności umiejętności ta wysyła do bota endOfConversation głównego działanie oprócz wiadomości odpowiedzi. Właściwość endOfConversation kodu działania wskazuje, że umiejętność została ukończona pomyślnie.

Przykładowa transkrypcja interakcji z użytkownikiem umiejętności.

Więcej informacji o debugowaniu

Ponieważ ruch między umiejętnościami i użytkownikami umiejętności jest uwierzytelniany, podczas debugowania takich botów są wykonywane dodatkowe kroki.

  • Użytkownik umiejętności i wszystkie umiejętności, których używa, bezpośrednio lub pośrednio, muszą być uruchomione.
  • Jeśli boty działają lokalnie i jeśli którykolwiek z botów ma identyfikator aplikacji i hasło, wszystkie boty muszą mieć prawidłowe identyfikatory i hasła.
  • Jeśli wszystkie boty są wdrożone, zobacz, jak debugować bota z dowolnego kanału przy użyciu narzędzia ngrok.
  • Jeśli niektóre boty działają lokalnie, a niektóre są wdrażane, zobacz, jak debugować umiejętności lub umiejętności użytkownika.

W przeciwnym razie możesz debugować użytkownika umiejętności lub umiejętności podobne do debugowania innych botów. Aby uzyskać więcej informacji, zobacz Debugowanie bota i Debugowanie za pomocą emulatora platformy Bot Framework.

Dodatkowe informacje

Poniżej przedstawiono kilka kwestii, które należy wziąć pod uwagę podczas implementowania bardziej złożonego bota głównego.

Aby umożliwić użytkownikowi anulowanie wieloetapowej umiejętności

Bot główny powinien sprawdzić komunikat użytkownika przed przekazaniem go do aktywnej umiejętności. Jeśli użytkownik chce anulować bieżący proces, bot główny może wysłać endOfConversation działanie do umiejętności, zamiast przekazywać komunikat.

Aby wymieniać dane między botami głównymi i umiejętnościami

Aby wysłać parametry do umiejętności, użytkownik umiejętności może ustawić właściwość value w komunikatach wysyłanych do umiejętności. Aby otrzymywać wartości zwracane z umiejętności, użytkownik umiejętności powinien sprawdzić właściwość value , gdy umiejętność wysyła endOfConversation działanie.

Aby użyć wielu umiejętności

  • Jeśli umiejętność jest aktywna, bot główny musi określić, która umiejętność jest aktywna, i przekazać komunikat użytkownika do właściwej umiejętności.
  • Jeśli żadna umiejętność nie jest aktywna, bot główny musi określić, które umiejętności należy uruchomić, jeśli istnieją, na podstawie stanu bota i danych wejściowych użytkownika.
  • Jeśli chcesz zezwolić użytkownikowi na przełączanie się między wieloma współbieżnymi umiejętnościami, główny bot musi określić, które z aktywnych umiejętności użytkownik zamierza wchodzić w interakcję przed przekazaniem wiadomości użytkownika.

Aby użyć trybu dostarczania oczekiwanych odpowiedzi

Aby użyć trybu dostarczania oczekiwanych odpowiedzi:

  • Sklonuj działanie z kontekstu kolei.
  • Ustaw właściwość trybu dostarczania nowego działania na "ExpectReplies" przed wysłaniem działania z bota głównego do umiejętności.
  • Odczytaj oczekiwane odpowiedzi z treści odpowiedzi wywołania zwróconej z odpowiedzi żądania.
  • Przetwarzaj każde działanie w ramach bota głównego lub wysyłając je do kanału, który zainicjował oryginalne żądanie.

Oczekiwane odpowiedzi mogą być przydatne w sytuacjach, w których bot, który odpowiada na działanie, musi być tym samym wystąpieniem bota, który otrzymał działanie.