Delen via


Save user and conversation data (Gebruikers- en gespreksgegevens opslaan)

VAN TOEPASSING OP: SDK v4

Een bot is inherent staatloos. Zodra uw bot is geïmplementeerd, wordt deze mogelijk niet uitgevoerd in hetzelfde proces of op dezelfde computer van de ene naar de andere. Uw bot moet echter mogelijk de context van een gesprek bijhouden, zodat het gedrag ervan kan worden beheerd en antwoorden op eerdere vragen kan onthouden. Met de status- en opslagfuncties van de Bot Framework SDK kunt u status toevoegen aan uw bot. Bots gebruiken statusbeheer en opslagobjecten om de status te beheren en te behouden. De statusbeheerder biedt een abstractielaag waarmee u toegang hebt tot statuseigenschappen met behulp van eigenschapstoegangsors, onafhankelijk van het type onderliggende opslag.

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

  • Kennis van de basisbeginselen van bots en hoe bots de status beheren is vereist.
  • De code in dit artikel is gebaseerd op het voorbeeld van de statusbeheerbot. U hebt een kopie van het voorbeeld nodig in C#, JavaScript, Java of Python.

Over dit voorbeeld

Na ontvangst van gebruikersinvoer controleert dit voorbeeld de status van het opgeslagen gesprek om te zien of deze gebruiker eerder is gevraagd om zijn of haar naam op te geven. Als dat niet het is, wordt de naam van de gebruiker aangevraagd en wordt die invoer opgeslagen in de gebruikersstatus. Zo ja, dan wordt de naam die in de gebruikersstatus is opgeslagen, gebruikt om te communiceren met de gebruiker en de invoergegevens, samen met de tijd die is ontvangen en de invoerkanaal-id, terug te keren naar de gebruiker. De tijd- en kanaal-id-waarden worden opgehaald uit de gespreksgegevens van de gebruiker en vervolgens opgeslagen in de gespreksstatus. In het volgende diagram ziet u de relatie tussen de gegevensklassen van de bot, het gebruikersprofiel en de gespreksgegevensklassen.

Klassen definiëren

De eerste stap bij het instellen van statusbeheer is het definiëren van de klassen met de informatie die moet worden beheerd in de gebruikers- en gespreksstatus. In het voorbeeld dat in dit artikel wordt gebruikt, worden de volgende klassen gedefinieerd:

  • In UserProfile.cs definieert u een UserProfile klasse voor de gebruikersgegevens die door de bot worden verzameld.
  • In ConversationData.cs definieert u een ConversationData klasse om de gespreksstatus te beheren tijdens het verzamelen van gebruikersgegevens.

In de volgende codevoorbeelden ziet u de definities voor de UserProfile en ConversationData klassen.

UserProfile.cs

public class UserProfile
{
    public string Name { get; set; }
}

ConversationData.cs

public class ConversationData
{
    // The time-stamp of the most recent incoming message.
    public string Timestamp { get; set; }

    // The ID of the user's channel.
    public string ChannelId { get; set; }

    // Track whether we have already asked the user's name
    public bool PromptedUserForName { get; set; } = false;
}

Gespreks- en gebruikersstatusobjecten maken

Vervolgens registreert MemoryStorage u dat wordt gebruikt voor het maken UserState en maken van ConversationState objecten. De gebruikers- en gespreksstatusobjecten worden gemaakt op Startup en afhankelijkheden die zijn geïnjecteerd in de botconstructor. Andere services voor een bot die zijn geregistreerd, zijn: een referentieprovider, een adapter en de bot-implementatie.

Startup.cs

// {
//     TypeNameHandling = TypeNameHandling.All,
// var storage = new BlobsStorage("<blob-storage-connection-string>", "bot-state");

// With a custom JSON SERIALIZER, use this instead.
// var storage = new BlobsStorage("<blob-storage-connection-string>", "bot-state", jsonSerializer);

/* END AZURE BLOB STORAGE */

Bots/StateManagementBot.cs

private BotState _conversationState;
private BotState _userState;

public StateManagementBot(ConversationState conversationState, UserState userState)
{
    _conversationState = conversationState;
    _userState = userState;
}

Toegangsrechten voor statuseigenschappen toevoegen

Nu maakt u eigenschapstoegangsors met behulp van de CreateProperty methode die een ingang voor het BotState object biedt. Met elke toegangsrechten voor statuseigenschappen kunt u de waarde van de bijbehorende statuseigenschap ophalen of instellen. Voordat u de statuseigenschappen gebruikt, gebruikt u elke accessor om de eigenschap uit de opslag te laden en deze op te halen uit de statuscache. Als u de juiste scoped sleutel wilt ophalen die is gekoppeld aan de statuseigenschap, roept u de GetAsync methode aan.

Bots/StateManagementBot.cs

var conversationStateAccessors = _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));

Toegangsstatus vanuit uw bot

In de voorgaande sectie worden de initialisatiestappen beschreven voor het toevoegen van toegangsrechten voor statuseigenschappen aan onze bot. U kunt deze accessors nu tijdens runtime gebruiken om statusinformatie te lezen en te schrijven. In de onderstaande voorbeeldcode wordt de volgende logicastroom gebruikt:

  • Als userProfile.Name dit leeg is en conversationData.PromptedUserForName waar is, haalt u de opgegeven gebruikersnaam op en slaat u deze op in de gebruikersstatus.
  • Als userProfile.Name deze leeg is en conversationData.PromptedUserForName onwaar is, vraagt u om de naam van de gebruiker.
  • Als userProfile.Name dit eerder is opgeslagen, haalt u de berichttijd en kanaal-id op uit de invoer van de gebruiker, echot u alle gegevens terug naar de gebruiker en slaat u de opgehaalde gegevens op binnen de gespreksstatus.

Bots/StateManagementBot.cs

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    // Get the state properties from the turn context.

    var conversationStateAccessors = _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
    var conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData());

    var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
    var userProfile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile());

    if (string.IsNullOrEmpty(userProfile.Name))
    {
        // First time around this is set to false, so we will prompt user for name.
        if (conversationData.PromptedUserForName)
        {
            // Set the name to what the user provided.
            userProfile.Name = turnContext.Activity.Text?.Trim();

            // Acknowledge that we got their name.
            await turnContext.SendActivityAsync($"Thanks {userProfile.Name}. To see conversation data, type anything.");

            // Reset the flag to allow the bot to go through the cycle again.
            conversationData.PromptedUserForName = false;
        }
        else
        {
            // Prompt the user for their name.
            await turnContext.SendActivityAsync($"What is your name?");

            // Set the flag to true, so we don't prompt in the next turn.
            conversationData.PromptedUserForName = true;
        }
    }
    else
    {
        // Add message details to the conversation data.
        // Convert saved Timestamp to local DateTimeOffset, then to string for display.
        var messageTimeOffset = (DateTimeOffset)turnContext.Activity.Timestamp;
        var localMessageTime = messageTimeOffset.ToLocalTime();
        conversationData.Timestamp = localMessageTime.ToString();
        conversationData.ChannelId = turnContext.Activity.ChannelId.ToString();

        // Display state data.
        await turnContext.SendActivityAsync($"{userProfile.Name} sent: {turnContext.Activity.Text}");
        await turnContext.SendActivityAsync($"Message received at: {conversationData.Timestamp}");
        await turnContext.SendActivityAsync($"Message received from: {conversationData.ChannelId}");
    }
}

Voordat u de draaihandler afsluit, gebruikt u de saveChangesAsync()-methode van de statusbeheerobjecten om alle statuswijzigingen terug te schrijven naar de opslag.

Bots/StateManagementBot.cs

public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
    await base.OnTurnAsync(turnContext, cancellationToken);

    // Save any state changes that might have occurred during the turn.
    await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
    await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
}

Uw bot testen

  1. De nieuwste Bot Framework Emulator downloaden en installeren
  2. Voer het voorbeeld lokaal uit op uw computer. Als u instructies nodig hebt, raadpleegt u de LEESMIJ voor C#, JavaScript, Java of Python.
  3. Gebruik de emulator om uw voorbeeldbot te testen.

Aanvullende informatie

In dit artikel wordt beschreven hoe u de status aan uw bot kunt toevoegen. Zie de volgende tabel voor meer informatie over verwante onderwerpen.

Onderwerp Opmerkingen
Privacy Als u de persoonlijke gegevens van de gebruiker wilt opslaan, moet u ervoor zorgen dat de algemene verordening gegevensbescherming wordt nageleefd.
Statusbeheer Alle statusbeheeraanroepen zijn standaard asynchroon en last-writer-wins. In de praktijk moet u de status zo dicht mogelijk bij elkaar krijgen, instellen en opslaan in uw bot. Zie Aangepaste opslag implementeren voor uw bot voor een discussie over het implementeren van optimistische vergrendeling.
Kritieke bedrijfsgegevens Gebruik de botstatus om voorkeuren, gebruikersnaam of het laatste wat ze hebben besteld op te slaan, maar gebruik deze niet om kritieke bedrijfsgegevens op te slaan. Voor kritieke gegevens maakt u uw eigen opslagonderdelen of schrijft u rechtstreeks naar de opslag.
Recognizer-Text In het voorbeeld worden de Microsoft/Recognizers-Text-bibliotheken gebruikt om gebruikersinvoer te parseren en valideren. Zie de overzichtspagina voor meer informatie.

Volgende stappen

Meer informatie over het stellen van een reeks vragen, het valideren van hun antwoorden en het opslaan van hun invoer.