Megosztás a következőn keresztül:


Beszélgetés lejárata

A KÖVETKEZŐKRE VONATKOZIK: SDK v4

A robotnak időnként újra kell indítania egy beszélgetést az elejétől kezdve. Ha például egy felhasználó bizonyos idő elteltével nem válaszol. Ez a cikk a beszélgetések lejáró két módszerét ismerteti:

  • Nyomon követheti, hogy mikor érkezett utoljára üzenet egy felhasználótól, és törölje az állapotot, ha az idő nagyobb, mint egy előre konfigurált hossz, amikor a következő üzenetet megkapja a felhasználótól. További információt a felhasználói beavatkozás lejárati szakaszában talál.
  • Egy tárolási réteg funkció, például a Cosmos DB Élettartam (TTL) használatával automatikusan törölheti az állapotot egy előre konfigurált időtartam után. További információkért tekintse meg a tároló lejárati szakaszát.

Feljegyzés

A Bot Framework JavaScript, C# és Python SDK-k továbbra is támogatottak lesznek, a Java SDK-t azonban 2023 novemberében végső hosszú távú támogatással kivonják.

A Java SDK-val létrehozott meglévő robotok továbbra is működni fognak.

Új robotépítéshez fontolja meg a Power Virtual Agents használatát, és olvassa el a megfelelő csevegőrobot-megoldás kiválasztását.

További információ: A robotépítés jövője.

Előfeltételek

  • Ha még nincs Azure-előfizetése, kezdés előtt hozzon létre egy ingyenes fiókot.
  • A robot alapjainak, az állapot kezelésének és a párbeszédpanelek kódtárának ismerete.
  • A többfordulós parancssori minta másolata C#, JavaScript, Java vagy Python nyelven.

A minta ismertetése

A cikkben szereplő mintakód egy többfordulós robot szerkezetével kezdődik, és további kód hozzáadásával bővíti a robot funkcióit (az alábbi szakaszokban található). Ez a kiterjesztett kód bemutatja, hogyan törölhető a beszélgetés állapota egy adott időszak leteltét követően.

Felhasználói beavatkozás lejárata

Ez a lejáró beszélgetéstípus úgy érhető el, hogy hozzáad egy utolsó hozzáférésű időtulajdonságot a robot beszélgetési állapotához. Ezt a tulajdonságértéket ezután összehasonlítjuk a tevékenységkezelőn belüli aktuális idővel a tevékenységek feldolgozása előtt.

Feljegyzés

Ez a példa 30 másodperces időtúllépést használ a minta egyszerű teszteléséhez.

appsettings.json

Először adjon hozzá egy ExpireAfterSeconds beállítást a appsettings.json:

{
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "ExpireAfterSeconds": 30
}

Robotok\DialogBot.cs

Ezután adjon hozzá ExpireAfterSeconds, LastAccessedTimePropertyés DialogStateProperty mezőket a robotosztályhoz, és inicializálja őket a robot konstruktorában. Adjon hozzá egy paramétert IConfiguration a konstruktorhoz, amellyel lekérheti az ExpireAfterSeconds értéket.

Ahelyett, hogy a párbeszédpanel állapottulajdonság-tartozékát inicializáláskor hozza létre és rögzíti a metódusban OnMessageActivityAsync , akkor hozza létre és rögzítse azt. A robotnak nem csak a párbeszédpanel futtatásához, hanem a párbeszédpanel állapotának törléséhez is szüksége lesz az állapottulajdonság-tartozékra.

protected readonly int ExpireAfterSeconds;
protected readonly IStatePropertyAccessor<DateTime> LastAccessedTimeProperty;
protected readonly IStatePropertyAccessor<DialogState> DialogStateProperty;

// Existing fields omitted...

public DialogBot(IConfiguration configuration, ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger)
{
    ConversationState = conversationState;
    UserState = userState;
    Dialog = dialog;
    Logger = logger;

    ExpireAfterSeconds = configuration.GetValue<int>("ExpireAfterSeconds");
    DialogStateProperty = ConversationState.CreateProperty<DialogState>(nameof(DialogState));
    LastAccessedTimeProperty = ConversationState.CreateProperty<DateTime>(nameof(LastAccessedTimeProperty));
}

Végül adjon hozzá kódot a robot metódusához OnTurnAsync , hogy törölje a párbeszédpanel állapotát, ha a beszélgetés túl régi.

public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
{
    // Retrieve the property value, and compare it to the current time.
    var lastAccess = await LastAccessedTimeProperty.GetAsync(turnContext, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);
    if ((DateTime.UtcNow - lastAccess) >= TimeSpan.FromSeconds(ExpireAfterSeconds))
    {
        // Notify the user that the conversation is being restarted.
        await turnContext.SendActivityAsync("Welcome back!  Let's start over from the beginning.").ConfigureAwait(false);

        // Clear state.
        await ConversationState.ClearStateAsync(turnContext, cancellationToken).ConfigureAwait(false);
    }

    await base.OnTurnAsync(turnContext, cancellationToken).ConfigureAwait(false);

    // Set LastAccessedTime to the current time.
    await LastAccessedTimeProperty.SetAsync(turnContext, DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

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

Tároló lejárata

A Cosmos DB egy Élettartam (TTL) funkciót biztosít, amellyel bizonyos idő elteltével automatikusan törölhet elemeket egy tárolóból. Ez konfigurálható az Azure Portalon vagy a tároló létrehozása során (a nyelvspecifikus Cosmos DB SDK-k használatával).

A Bot Framework SDK nem tesz közzé TTL-konfigurációs beállítást. A tároló inicializálása azonban felülbírálható, és a Cosmos DB SDK használható a TTL konfigurálására a Bot Framework storage inicializálása előtt.

Kezdje a többfordulós parancssori minta friss másolatával, és adja hozzá a Microsoft.Bot.Builder.Azure NuGet-csomagot a projekthez.

appsettings.json

Frissítse a appsettings.json a Cosmos DB tárolási beállításainak belefoglalásához:

{
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",

  "CosmosDbTimeToLive": 30,
  "CosmosDbEndpoint": "<endpoint-for-your-cosmosdb-instance>",
  "CosmosDbAuthKey": "<your-cosmosdb-auth-key>",
  "CosmosDbDatabaseId": "<your-database-id>",
  "CosmosDbUserStateContainerId": "<no-ttl-container-id>",
  "CosmosDbConversationStateContainerId": "<ttl-container-id>"
}

Figyelje meg a két ContainerIds, egy for UserState és egy for ConversationState. Az alapértelmezett TTL be van állítva a ConversationState tárolón, de nem bekapcsolva UserState.

CosmosDbStorageInitializerHostedService.cs

Ezután hozzon létre egy osztályt CosmosDbStorageInitializerHostedService , amely létrehozza a tárolót a konfigurált élettartammal.

// Add required using statements...

public class CosmosDbStorageInitializerHostedService : IHostedService
{
    readonly CosmosDbPartitionedStorageOptions _storageOptions;
    readonly int _cosmosDbTimeToLive;

    public CosmosDbStorageInitializerHostedService(IConfiguration config)
    {
        _storageOptions = new CosmosDbPartitionedStorageOptions()
        {
            CosmosDbEndpoint = config["CosmosDbEndpoint"],
            AuthKey = config["CosmosDbAuthKey"],
            DatabaseId = config["CosmosDbDatabaseId"],
            ContainerId = config["CosmosDbConversationStateContainerId"]
        };

        _cosmosDbTimeToLive = config.GetValue<int>("CosmosDbTimeToLive");
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        using (var client = new CosmosClient(
            _storageOptions.CosmosDbEndpoint,
            _storageOptions.AuthKey,
            _storageOptions.CosmosClientOptions ?? new CosmosClientOptions()))
        {
            // Create the contaier with the provided TTL
            var containerResponse = await client
                .GetDatabase(_storageOptions.DatabaseId)
                .DefineContainer(_storageOptions.ContainerId, "/id")
                .WithDefaultTimeToLive(_cosmosDbTimeToLive)
                .WithIndexingPolicy().WithAutomaticIndexing(false).Attach()
                .CreateIfNotExistsAsync(_storageOptions.ContainerThroughput)
                .ConfigureAwait(false);
        }
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

Startup.cs

Végül frissítsen Startup.cs a tároló inicializálójának és a Cosmos DB állapotának használatára:

// Existing code omitted...

// commented out MemoryStorage, since we are using CosmosDbPartitionedStorage instead
// services.AddSingleton<IStorage, MemoryStorage>();

// Add the Initializer as a HostedService (so it's called during the app service startup)
services.AddHostedService<CosmosDbStorageInitializerHostedService>();

// Create the storage options for User state
var userStorageOptions = new CosmosDbPartitionedStorageOptions()
{
    CosmosDbEndpoint = Configuration["CosmosDbEndpoint"],
    AuthKey = Configuration["CosmosDbAuthKey"],
    DatabaseId = Configuration["CosmosDbDatabaseId"],
    ContainerId = Configuration["CosmosDbUserStateContainerId"]
};

// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton(new UserState(new CosmosDbPartitionedStorage(userStorageOptions)));

// Create the storage options for Conversation state
var conversationStorageOptions = new CosmosDbPartitionedStorageOptions()
{
    CosmosDbEndpoint = Configuration["CosmosDbEndpoint"],
    AuthKey = Configuration["CosmosDbAuthKey"],
    DatabaseId = Configuration["CosmosDbDatabaseId"],
    ContainerId = Configuration["CosmosDbConversationStateContainerId"]
};

// Create the Conversation state. (Used by the Dialog system itself.)
services.AddSingleton(new ConversationState(new CosmosDbPartitionedStorage(conversationStorageOptions)));

// Existing code omitted...

A Cosmos DB 30 másodperc inaktivitás után automatikusan törli a beszélgetési állapot rekordjait.

További információ: Élettartam konfigurálása az Azure Cosmos DB-ben

A robot tesztelése

  1. Ha még nem tette meg, telepítse a Bot Framework Emulatort.
  2. Futtassa a mintát helyileg a számítógépen.
  3. Indítsa el az Emulatort, csatlakozzon a robothoz, és küldjön neki egy üzenetet.
  4. Az egyik kérés után várjon 30 másodpercet, mielőtt válaszol.