Ukládání dat uživatelů a konverzací

PLATÍ PRO: SDK v4

Robot je ze své podstaty bezstavový. Jakmile je robot nasazený, nemusí běžet ve stejném procesu nebo na stejném počítači z jednoho na další. Robot ale může potřebovat sledovat kontext konverzace, aby mohl spravovat své chování a pamatovat si odpovědi na předchozí otázky. Funkce stavu a úložiště sady SDK služby Bot Framework umožňují přidat do robota stav. Roboti používají ke správě a zachování stavu objekty stavu a objekty úložiště. Správce stavů poskytuje abstraktní vrstvu, která umožňuje přístup k vlastnostem stavu pomocí přístupových objektů vlastností nezávisle na typu základního úložiště.

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. V tomto úložišti budou provedeny pouze kritické opravy zabezpečení a chyb.

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ů.

Předpoklady

O této ukázce

Po přijetí uživatelského vstupu tato ukázka zkontroluje uložený stav konverzace a zjistí, jestli byl tento uživatel dříve vyzván k zadání jména. Pokud ne, je požadováno jméno uživatele a tento vstup se uloží do stavu uživatele. Pokud ano, jméno uložené ve stavu uživatele se použije ke zopakování s uživatelem a jejich vstupními daty, spolu s časem přijatým a ID vstupního kanálu, se vrátí zpět uživateli. Hodnoty ID času a kanálu se načtou z dat konverzace uživatele a pak se uloží do stavu konverzace. Následující diagram znázorňuje vztah mezi datovými třídami robota, profilu uživatele a konverzace.

Definování tříd

Prvním krokem při nastavování správy stavu je definování tříd obsahujících informace, které se mají spravovat ve stavu uživatele a konverzace. Příklad použitý v tomto článku definuje následující třídy:

  • V souboru UserProfile.cs definujete UserProfile třídu pro informace o uživateli, které robot bude shromažďovat.
  • V souboru ConversationData.cs definujete ConversationData třídu pro řízení stavu naší konverzace při shromažďování informací o uživatelích.

Následující příklady kódu ukazují definice pro třídy UserProfile a ConversationData třídy.

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

Vytváření objektů stavu konverzací a uživatelů

V dalším kroku zaregistrujete MemoryStorage , který se používá k vytváření UserState a ConversationState objektům. Objekty stavu uživatele a konverzace jsou vytvořeny v Startup konstruktoru robota a vloženy do konstruktoru závislostí. Další služby pro robota, který je zaregistrovaný, jsou: zprostředkovatel přihlašovacích údajů, adaptér a implementace robota.

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

Přidání přístupových objektů vlastností stavu

Nyní vytvoříte přístupové objekty vlastností pomocí CreateProperty metody, která poskytuje popisovač objektu BotState . Každý přístup k vlastnostem stavu umožňuje získat nebo nastavit hodnotu přidružené vlastnosti stavu. Před použitím vlastností stavu načtěte vlastnost z úložiště pomocí každého přístupového objektu a získejte ji z mezipaměti stavu. Chcete-li získat správně vymezený klíč přidružený k vlastnosti stavu, zavoláte metodu GetAsync .

Bots/StateManagementBot.cs

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

Stav přístupu z robota

Předchozí část popisuje kroky inicializace a času přidání přístupových objektů stavu k robotovi. Teď můžete tyto přístupové objekty použít za běhu ke čtení a zápisu informací o stavu. Následující ukázkový kód používá následující tok logiky:

  • Pokud userProfile.Name je prázdný a conversationData.PromptedUserForName je true, načtete zadané uživatelské jméno a uložíte ho v rámci stavu uživatele.
  • Pokud userProfile.Name je prázdný a conversationData.PromptedUserForName je false, požádáte o jméno uživatele.
  • Pokud userProfile.Name jste dříve uložili, načtete čas zprávy a ID kanálu ze vstupu uživatele, ozvěte všechna data zpět uživateli a uložíte načtená data v rámci stavu konverzace.

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

Před ukončením obslužné rutiny otáčení použijete metodu SaveChangesAsync() objektů správy stavu k zápisu všech změn stavu zpět do úložiště.

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

Testování robota

  1. Stažení a instalace nejnovější aplikace Bot Framework Emulator
  2. Spusťte ukázku místně na svém počítači. Pokud potřebujete pokyny, přečtěte si soubor README pro C#, JavaScript, Javu nebo Python.
  3. Pomocí emulátoru otestujte ukázkového robota.

Další informace

Tento článek popisuje, jak do robota přidat stav. Další informace o souvisejících tématech najdete v následující tabulce.

Popis Notes
Ochrana osobních údajů Pokud máte v úmyslu ukládat osobní údaje uživatele, měli byste zajistit dodržování obecného nařízení o ochraně osobních údajů.
Správa stavu Všechna volání správy stavu jsou asynchronní a ve výchozím nastavení vyhrává poslední zapisovač. V praxi byste měli získat, nastavit a uložit stav co nejblíže v robotovi. Diskuzi o implementaci optimistického uzamčení najdete v tématu Implementace vlastního úložiště robota.
Důležitá obchodní data Pomocí stavu robota můžete ukládat předvolby, uživatelské jméno nebo poslední věc, kterou si objednali, ale nepoužívejte ho k ukládání důležitých obchodních dat. Pro důležitá data vytvořte vlastní součásti úložiště nebo přímo do úložiště zapisujte.
Rozpoznávání textu Ukázka používá knihovny Microsoft/Recognizers-Text k analýze a ověření uživatelského vstupu. Další informace najdete na stránce přehledu.

Další kroky

Přečtěte si, jak uživateli položit řadu otázek, ověřit odpovědi a uložit svůj vstup.