Delen via


Een vaardigheidsconsumer implementeren

VAN TOEPASSING OP: SDK v4

U kunt vaardigheden inzetten om een andere bot verder te ontwikkelen. Een vaardigheid is een bot die een set taken voor een andere bot kan uitvoeren en een manifest gebruikt om de interface ervan te beschrijven. Een hoofdbot is een gebruikersgerichte bot die een of meer vaardigheden kan aanroepen. Een rootbot is een type vaardigheidsgebruiker.

  • Een consument van vaardigheden moet claimvalidatie gebruiken om te beheren welke vaardigheden er toegang toe hebben.
  • Een vaardigheidsconsumer kan meerdere vaardigheden gebruiken.
  • Ontwikkelaars die geen toegang hebben tot de broncode van de vaardigheid, kunnen de informatie in het manifest van de vaardigheid gebruiken om hun vaardigheidsgebruiker te ontwerpen.

In dit artikel wordt gedemonstreerd hoe u een vaardigheidsgebruiker implementeert die gebruik maakt van de echovaardigheid om de invoer van de gebruiker te herhalen. Zie hoe u een vaardigheid implementeert voor een voorbeeldmanifest en informatie over het implementeren van de echovaardigheid.

Voor informatie over het gebruik van een vaardigheidsdialoogvenster om een vaardigheid te gebruiken, raadpleegt u hoe u een dialoogvenster gebruikt om een vaardigheid te gebruiken.

Sommige typen vaardigheidsgebruikers kunnen bepaalde typen vaardigheidsbots niet gebruiken. In de volgende tabel wordt beschreven welke combinaties worden ondersteund.

  Vaardigheid voor meerdere tenants Vaardigheid met één tenant Door de gebruiker toegewezen vaardigheden voor beheerde identiteit
Consument met meerdere tenants Ondersteund Niet ondersteund Niet ondersteund
Consument met één tenant Niet ondersteund Ondersteund als beide apps deel uitmaken van dezelfde tenant Ondersteund als beide apps deel uitmaken van dezelfde tenant
Door de gebruiker toegewezen beheerde identiteitgebruiker Niet ondersteund Ondersteund als beide apps deel uitmaken van dezelfde tenant Ondersteund als beide apps deel uitmaken van dezelfde tenant

Notitie

De Sdk's voor Bot Framework JavaScript, C# en Python blijven ondersteund, maar de Java SDK wordt buiten gebruik gesteld met definitieve langetermijnondersteuning die eindigt op november 2023.

Bestaande bots die zijn gebouwd met de Java SDK blijven functioneren.

Voor het bouwen van nieuwe bots kunt u Microsoft Copilot Studio gebruiken en lezen over het kiezen van de juiste copilot-oplossing.

Zie De toekomst van botbouw voor meer informatie.

Vereisten

Notitie

Vanaf versie 4.11 hebt u geen app-id en wachtwoord nodig om een vaardigheidsconsumer lokaal te testen in de Bot Framework Emulator. Een Azure-abonnement is nog steeds vereist om uw consument te implementeren in Azure of om een geïmplementeerde vaardigheid te gebruiken.

Over dit voorbeeld

Het skills eenvoudige bot-naar-bot-voorbeeld bevat projecten voor twee bots:

  • De bot met echovaardigheden, waarmee de vaardigheid wordt geïmplementeerd.
  • De eenvoudige rootbot, waarmee een rootbot wordt geïmplementeerd die de vaardigheid benut.

Dit artikel focust op de root bot, die ondersteuningslogica bevat in zowel de bot- als adapterobjecten, en bevat objecten die worden gebruikt om activiteiten uit te wisselen met een vaardigheid. Deze omvatten:

  • Een vaardigheidsclient, die wordt gebruikt om activiteiten naar een vaardigheid te verzenden.
  • Een vaardigheidsverwerker, die wordt gebruikt om activiteiten van een vaardigheid te ontvangen.
  • Een vaardigheidsgesprek-ID fabriek, gebruikt door de vaardigheidsclient en verwerker om te vertalen tussen de gebruikergespreksverwijzing en de basisvaardigheidsgespreksverwijzing.

Zie hoe u een vaardigheid implementeert voor informatie over de bot met echovaardigheden.

Middelen

Voor geïmplementeerde bots vereist bot-tot-bot-authenticatie dat elke deelnemende bot geldige identiteitsgegevens heeft. U kunt echter multi-tenant vaardigheden en vaardigheidsgebruikers lokaal testen met de Emulator zonder app-id en wachtwoord.

Toepassingsconfiguratie

  1. Voeg eventueel de identiteitsgegevens van de root-bot toe aan zijn configuratiebestand. Als zowel de vaardigheid als de gebruiker identiteitsinformatie verstrekt, moeten beiden dat doen.
  2. Voeg het hosteindpunt voor vaardigheden (de service- of callback-URL) toe waaraan de vaardigheden moeten reageren op de vaardigheidsgebruiker.
  3. Voeg een vermelding toe voor elke vaardigheid die de consument gaat gebruiken. Elke vermelding omvat:
    • Een id die de consument gebruikt om elke vaardigheid te identificeren.
    • Optioneel: de app- of client-ID van de skill.
    • Het communicatie-eindpunt van de functie.

Notitie

Als de vaardigheid of de gebruiker van de vaardigheid identiteitsinformatie verstrekt, moeten beiden dat doen.

SimpleRootBot\appsettings.json

Voeg eventueel de identiteitsgegevens van de hoofdbot toe en voeg de app- of client-id voor de bot met echovaardigheden toe.

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

Vaardighedenconfiguratie

In dit voorbeeld wordt informatie voor elke vaardigheid in het configuratiebestand gelezen in een verzameling vaardigheidsobjecten .

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

Gespreks-ID fabriek

Hiermee wordt de gespreks-id voor gebruik met de vaardigheid aangemaakt, en kan de oorspronkelijke gespreks-id van de gebruiker worden hersteld uit de gespreks-id van de vaardigheid.

De gespreks-id factory voor dit voorbeeld ondersteunt een eenvoudig scenario waarbij:

  • De hoofdbot is ontworpen om één specifieke vaardigheid te gebruiken.
  • De hoofdbot heeft maar één actief gesprek met een vaardigheid tegelijk.

De SDK biedt een SkillConversationIdFactory klasse die kan worden gebruikt voor elke vaardigheid zonder dat de broncode hoeft te worden gerepliceerd. De gespreks-ID-fabriek is geconfigureerd in Startup.cs.

Als u complexere scenario's wilt ondersteunen, ontwerpt u uw gespreks-id factory zodat:

  • Met de methode voor het creëren van gespreks-id's voor vaardigheden wordt de juiste gespreks-id voor vaardigheden opgehaald of gegenereerd.
  • De get-gespreksreferentie-methode haalt het juiste gebruikersgesprek op.

Vaardigheidsclient en vaardigheidsverwerker

De gebruiker van de vaardigheid gebruikt een vaardigheidsclient om activiteiten door te sturen naar de vaardigheid. De client gebruikt hiervoor de informatie over de configuratie van vaardigheden en gespreks-id's.

De vaardigheidsgebruiker gebruikt een vaardigheidsbeheerder om activiteiten van een vaardigheid te ontvangen. De handler maakt gebruik van de gespreks-ID-fabriek, de verificatieconfiguratie en een referentieverschaffer om dit te doen, en heeft ook afhankelijkheden van de adapter en de activiteitshandler van de hoofdbot.

SimpleRootBot\Startup.cs

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

HTTP-verkeer van de skill komt binnen op het service-URL-eindpunt dat de gebruiker doorgeeft aan de skill. Gebruik een taalspecifieke eindpunthandler om verkeer door te sturen naar de vaardigheidshandler.

De standaardhandler voor vaardigheden:

  • Als er een app-id en wachtwoord aanwezig zijn, gebruikt u een verificatieconfiguratieobject om zowel bot-naar-bot-verificatie als claimvalidatie uit te voeren.
  • Gebruikt de gespreks-ID-fabriek om te vertalen van het consument-skills-gesprek terug naar het hoofdgebruiker-gesprek.
  • Genereert een proactief bericht zodat de gebruiker van de vaardigheid de root-gebruikercontext kan herstellen en activiteiten naar de gebruiker kan doorsturen.

Logica voor activiteitenbeheerder

Opmerking: de logica van de verbruiker met betrekking tot vaardigheden moet:

  • Onthoud of er actieve vaardigheden zijn en stuur indien van toepassing activiteiten naar hen door.
  • U merkt op wanneer een gebruiker een verzoek doet dat moet worden doorgestuurd naar een vaardigheid, en start vervolgens de vaardigheid.
  • Zoek naar een endOfConversation activiteit van elke actieve vaardigheid om te zien wanneer deze is voltooid.
  • Voeg indien van toepassing logica toe om de gebruiker of gebruiker van vaardigheden een vaardigheid te laten annuleren die nog niet is voltooid.
  • Sla de status op voordat u de aanroep naar een vaardigheid maakt, omdat elk antwoord kan terugkeren naar een ander exemplaar van de vaardigheidsgebruiker.

SimpleRootBot\Bots\RootBot.cs

De hoofdbot heeft afhankelijkheden van de gespreksstatus, de informatie over competenties, de competentieclient en de algemene configuratie. ASP.NET biedt deze objecten via afhankelijkheidsinjectie. De hoofdbot definieert ook een gespreksstatus-eigenschapstoegang om bij te houden welke vaardigheid actief is.

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

Dit voorbeeld heeft een helpermethode voor het doorsturen van activiteiten naar een vaardigheid. Hiermee wordt de gespreksstatus opgeslagen voordat de vaardigheid wordt aangeroepen en wordt gecontroleerd of de HTTP-aanvraag is geslaagd.

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

Opmerking: de hoofdbot bevat logica voor het doorsturen van activiteiten naar de vaardigheid, het starten van de vaardigheid op verzoek van de gebruiker en het stoppen van de vaardigheid wanneer deze is voltooid.

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

Fouthandler inschakelen

Wanneer er een fout optreedt, wist de adapter de gespreksstatus om het gesprek opnieuw in te stellen met de gebruiker en te voorkomen dat een foutstatus behouden blijft.

Het is een goede gewoonte om een einde aan het gesprek te sturen naar elke actieve skill voordat de gespreksstatus in de gebruikersapplicatie wordt gewist. Hiermee kan de vaardigheid alle resources vrijgeven die zijn gekoppeld aan het gesprek over consumentenvaardigheden voordat de consument van de vaardigheid het gesprek vrijgeeft.

SimpleRootBot\AdapterWithErrorHandler.cs

In dit voorbeeld wordt de logica voor turnfouten opgesplitst in een aantal helpermethoden.

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

Eindpunt voor vaardigheden

De bot definieert een eindpunt dat binnenkomende vaardigheidsactiviteiten doorstuurt naar de vaardigheidshandler van de hoofdbot.

SimpleRootBot\Controllers\SkillController.cs

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

Serviceregistratie

Neem een configuratieobject voor authenticatie op met claimsvalidatie en alle aanvullende objecten. In dit voorbeeld wordt dezelfde verificatieconfiguratielogica gebruikt voor het valideren van activiteiten van zowel gebruikers als vaardigheden.

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

De basisbot testen

U kunt de skill consumer in de emulator testen alsof het een normale bot is; U moet echter tegelijkertijd zowel de vaardigheidsbot als de skill consumer bots uitvoeren. Lees hoe u een vaardigheid implementeert voor informatie over het configureren van de vaardigheid.

De nieuwste Bot Framework Emulator downloaden en installeren

  1. Voer de echo-bot en de simpele basisbot lokaal uit op uw computer. Als u instructies nodig hebt, raadpleegt u het bestand voor het READMEC#-, JavaScript-, Java- of Python-voorbeeld.
  2. Gebruik de emulator om de bot te testen zoals hieronder wordt weergegeven. Wanneer u een end of stop bericht naar de vaardigheid verzendt, stuurt de vaardigheid naast het antwoordbericht een endOfConversation activiteit naar de hoofdbot. De endOfConversation activiteit's code-eigenschap geeft aan dat de taak succesvol is voltooid.

Voorbeeldtranscript van een interactie met de vaardighedengebruiker.

Meer informatie over foutopsporing

Omdat verkeer tussen vaardigheden en vaardigheidsgebruikers wordt geverifieerd, zijn er extra stappen bij het opsporen van fouten in dergelijke bots.

Anders kunt u een vaardigheidsgebruiker of vaardigheid debuggen, net zoals bij het opsporen van fouten in andere bots. Zie Fouten opsporen in een bot en fouten opsporen met de Bot Framework Emulator voor meer informatie.

Aanvullende informatie

Hier volgen enkele aandachtspunten bij het implementeren van een complexere hoofdbot.

De gebruiker toestaan een vaardigheid met meerdere stappen te annuleren

De root bot moet het bericht van de gebruiker controleren voordat het naar de actieve skill wordt doorgestuurd. Als de gebruiker het huidige proces wil annuleren, kan de hoofdbot een endOfConversation activiteit naar de vaardigheid verzenden in plaats van het bericht door te sturen.

Gegevens uitwisselen tussen de basis- en vaardigheidsbots

Als u parameters naar de skill wilt verzenden, kan de gebruiker van de skill de waarde-eigenschap instellen voor berichten die naar de skill worden verzonden. Als u retourwaarden van de vaardigheid wilt ontvangen, moet de gebruiker van de vaardigheid de waarde-eigenschap controleren wanneer de vaardigheid een endOfConversation activiteit verzendt.

Meerdere vaardigheden gebruiken

  • Als een vaardigheid actief is, moet de hoofdbot bepalen welke vaardigheid actief is en het bericht van de gebruiker doorsturen naar de juiste vaardigheid.
  • Als er geen vaardigheid actief is, moet de hoofdbot bepalen welke vaardigheid moet worden gestart, indien van toepassing, op basis van de botstatus en de invoer van de gebruiker.
  • Als u wilt dat de gebruiker moet kunnen schakelen tussen meerdere gelijktijdige vaardigheden, moet de hoofdbot bepalen met welke van de actieve vaardigheden de gebruiker wil communiceren, voordat het bericht van de gebruiker wordt doorgestuurd.

Een bezorgingsmodus van verwachte antwoorden gebruiken

Ga als volgt te werk om de modus voor beantwoording verwachten te gebruiken:

  • Kloon de activiteit vanuit de turncontext.
  • Stel de eigenschap leveringsmodus van de nieuwe activiteit in op 'ExpectReplies' voordat u de activiteit van de root bot naar de Skill verzendt.
  • Lees verwachte antwoorden uit de hoofdtekst van de aanroeprespons die is geretourneerd door de aanvraag.
  • Verwerkt elke activiteit, binnen de hoofdbot of door deze naar het kanaal te verzenden dat de oorspronkelijke aanvraag heeft gestart.

U kunt verwachten dat antwoorden nuttig kunnen zijn in situaties waarin de bot die antwoordt op een activiteit hetzelfde exemplaar moet zijn van de bot die de activiteit heeft ontvangen.