Bagikan melalui


Menerapkan konsumen keterampilan

BERLAKU UNTUK: SDK v4

Anda dapat menggunakan keterampilan untuk memperluas bot lain. Keterampilan adalah bot yang dapat melakukan serangkaian tugas untuk bot lain dan menggunakan manifes untuk menggambarkan antarmukanya. Bot root adalah bot yang menghadap pengguna yang dapat memanggil satu atau beberapa keterampilan. Bot root adalah jenis konsumen keterampilan.

  • Konsumen keterampilan harus menggunakan validasi klaim untuk mengelola keterampilan mana yang dapat mengaksesnya.
  • Konsumen keterampilan dapat menggunakan beberapa keterampilan.
  • Pengembang yang tidak memiliki akses ke kode sumber keterampilan dapat menggunakan informasi dalam manifes keterampilan untuk merancang konsumen keterampilan mereka.

Artikel ini menunjukkan cara mengimplementasikan konsumen keterampilan yang menggunakan keterampilan gema untuk menggemakan input pengguna. Untuk contoh manifes keterampilan dan informasi tentang mengimplementasikan keterampilan echo, lihat cara menerapkan keterampilan.

Untuk informasi tentang menggunakan dialog keterampilan untuk menggunakan keterampilan, lihat cara menggunakan dialog untuk menggunakan keterampilan.

Beberapa jenis konsumen keterampilan tidak dapat menggunakan beberapa jenis bot keterampilan. Tabel berikut ini menjelaskan kombinasi mana yang didukung.

  Keterampilan multi-penyewa Keterampilan penyewa tunggal Keterampilan identitas terkelola yang ditetapkan pengguna
Konsumen multi-penyewa Didukung Tidak didukung Tidak didukung
Konsumen penyewa tunggal Tidak didukung Didukung jika kedua aplikasi milik penyewa yang sama Didukung jika kedua aplikasi milik penyewa yang sama
Konsumen identitas terkelola yang ditetapkan pengguna Tidak didukung Didukung jika kedua aplikasi milik penyewa yang sama Didukung jika kedua aplikasi milik penyewa yang sama

Catatan

Bot Framework JavaScript, C#, dan Python SDK akan terus didukung, namun, Java SDK dihentikan dengan dukungan jangka panjang akhir yang berakhir pada November 2023.

Bot yang ada yang dibangun dengan Java SDK akan terus berfungsi.

Untuk pembuatan bot baru, pertimbangkan untuk menggunakan Power Virtual Agents dan baca tentang memilih solusi chatbot yang tepat.

Untuk informasi selengkapnya, lihat Masa depan pembuatan bot.

Prasyarat

Catatan

Dimulai dengan versi 4.11, Anda tidak memerlukan ID dan kata sandi aplikasi untuk menguji konsumen keterampilan secara lokal di Bot Framework Emulator. Langganan Azure masih diperlukan untuk menyebarkan konsumen Anda ke Azure atau untuk menggunakan keterampilan yang disebarkan.

Tentang sampel ini

Sampel bot-ke-bot sederhana keterampilan mencakup proyek untuk dua bot:

  • Bot keterampilan gema, yang mengimplementasikan keterampilan.
  • Bot akar sederhana, yang mengimplementasikan bot akar yang mengonsumsi keterampilan.

Artikel ini berfokus pada bot akar, yang mencakup logika dukungan dalam objek bot dan adaptornya dan mencakup objek yang digunakan untuk bertukar aktivitas dengan keterampilan. Ini termasuk:

  • Klien keterampilan, digunakan untuk mengirim aktivitas ke keterampilan.
  • Penangan keterampilan, digunakan untuk menerima aktivitas dari keterampilan.
  • Pabrik ID percakapan keterampilan, digunakan oleh klien keterampilan dan handler untuk menerjemahkan antara referensi percakapan akar pengguna dan referensi percakapan keterampilan akar.

Untuk informasi tentang bot keterampilan gema, lihat cara Menerapkan keterampilan.

Sumber

Untuk bot yang disebarkan, autentikasi bot-ke-bot mengharuskan setiap bot yang berpartisipasi memiliki informasi identitas yang valid. Namun, Anda dapat menguji keterampilan multi-penyewa dan konsumen keterampilan secara lokal dengan Emulator tanpa ID aplikasi dan kata sandi.

Konfigurasi aplikasi

  1. Secara opsional, tambahkan informasi identitas bot akar ke file konfigurasinya. Jika konsumen keterampilan atau keterampilan memberikan informasi identitas, keduanya harus.
  2. Tambahkan titik akhir host keterampilan (LAYANAN atau URL panggilan balik) tempat keterampilan harus membalas ke konsumen keterampilan.
  3. Tambahkan entri untuk setiap keterampilan yang akan digunakan konsumen keterampilan. Setiap entri meliputi:
    • ID yang akan digunakan konsumen keterampilan untuk mengidentifikasi setiap keterampilan.
    • Secara opsional, aplikasi keterampilan atau ID klien.
    • Titik akhir olahpesan keterampilan.

Catatan

Jika konsumen keterampilan atau keterampilan memberikan informasi identitas, keduanya harus.

SimpleRootBot\appsettings.json

Secara opsional, tambahkan informasi identitas bot akar dan tambahkan aplikasi atau ID klien untuk bot keterampilan gema.

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

Konfigurasi keterampilan

Sampel ini membaca informasi untuk setiap keterampilan dalam file konfigurasi ke dalam kumpulan objek keterampilan .

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

Pabrik ID Percakapan

Ini membuat ID percakapan untuk digunakan dengan keterampilan dan dapat memulihkan ID percakapan pengguna asli dari ID percakapan keterampilan.

Pabrik ID percakapan untuk sampel ini mendukung skenario sederhana di mana:

  • Bot akar dirancang untuk mengonsumsi satu keterampilan khusus.
  • Bot root hanya memiliki satu percakapan aktif dengan keterampilan pada satu waktu.

SDK menyediakan SkillConversationIdFactory kelas yang dapat digunakan di seluruh keterampilan apa pun tanpa memerlukan kode sumber untuk direplikasi. Pabrik ID percakapan dikonfigurasi di Startup.cs.

Untuk mendukung skenario yang lebih kompleks, rancang pabrik ID percakapan Anda sehingga:

  • Metode BUAT ID percakapan keterampilan mendapatkan atau menghasilkan ID percakapan keterampilan yang sesuai.
  • Metode dapatkan referensi percakapan mendapatkan percakapan pengguna yang benar.

Klien keterampilan dan penangan keterampilan

Konsumen keterampilan menggunakan klien keterampilan untuk meneruskan aktivitas ke keterampilan. Klien menggunakan informasi konfigurasi keterampilan dan pabrik ID percakapan untuk melakukannya.

Konsumen keterampilan menggunakan penangan keterampilan untuk menerima aktivitas dari keterampilan. Handler menggunakan pabrik ID percakapan, konfigurasi autentikasi, dan penyedia kredensial untuk melakukannya, dan juga memiliki dependensi pada adaptor bot akar dan penanganan aktivitas

SimpleRootBot\Startup.cs

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

Lalu lintas HTTP dari keterampilan akan masuk ke titik akhir URL layanan yang diiklankan konsumen keterampilan ke keterampilan. Gunakan handler titik akhir khusus bahasa untuk meneruskan lalu lintas ke penangan keterampilan.

Penangan keterampilan default:

  • Jika ID aplikasi dan kata sandi ada, gunakan objek konfigurasi autentikasi untuk melakukan autentikasi bot-ke-bot dan validasi klaim.
  • Menggunakan pabrik ID percakapan untuk menerjemahkan dari percakapan keterampilan konsumen kembali ke percakapan pengguna akar.
  • Menghasilkan pesan proaktif sehingga konsumen keterampilan dapat membangun kembali konteks giliran pengguna akar dan meneruskan aktivitas kepada pengguna.

Logika penangan aktivitas

Sebagai catatan, logika konsumen keterampilan harus:

  • Ingat apakah ada keterampilan aktif dan meneruskan aktivitas kepada mereka sebagaimana mewajarkannya.
  • Perhatikan ketika pengguna membuat permintaan yang harus diteruskan ke keterampilan, dan memulai keterampilan.
  • Cari endOfConversation aktivitas dari keterampilan aktif apa pun, untuk diperhatikan ketika selesai.
  • Jika sesuai, tambahkan logika untuk membiarkan pengguna atau konsumen keterampilan membatalkan keterampilan yang belum selesai.
  • Simpan status sebelum melakukan panggilan ke keterampilan, karena respons apa pun dapat kembali ke instans yang berbeda dari konsumen keterampilan.

SimpleRootBot\Bots\RootBot.cs

Bot root memiliki dependensi pada status percakapan, informasi keterampilan, klien keterampilan, dan konfigurasi umum. ASP.NET menyediakan objek ini melalui injeksi dependensi. Bot akar juga mendefinisikan pengaktif properti status percakapan untuk melacak keterampilan mana yang aktif.

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

Sampel ini memiliki metode pembantu untuk meneruskan aktivitas ke keterampilan. Ini menyimpan status percakapan sebelum memanggil keterampilan, dan memeriksa apakah permintaan HTTP berhasil.

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

Sebagai catatan, bot root mencakup logika untuk meneruskan aktivitas ke keterampilan, memulai keterampilan atas permintaan pengguna, dan menghentikan keterampilan ketika keterampilan selesai.

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

Aktifkan handler kesalahan

Ketika terjadi kesalahan, adapter menghapus status percakapan untuk mengatur ulang percakapan dengan pengguna dan menghindari status kesalahan yang berlanjut.

Ini adalah praktik yang baik untuk mengirim akhir aktivitas percakapan ke keterampilan aktif apa pun sebelum membersihkan status percakapan di konsumen keterampilan. Ini memungkinkan keterampilan merilis sumber daya apa pun yang terkait dengan percakapan keterampilan konsumen sebelum konsumen keterampilan merilis percakapan.

SimpleRootBot\AdapterWithErrorHandler.cs

Dalam sampel ini, logika kesalahan giliran dibagi di antara beberapa metode pembantu.

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

Titik akhir keterampilan

Bot mendefinisikan titik akhir yang meneruskan aktivitas keterampilan masuk ke penangan keterampilan bot akar.

SimpleRootBot\Controllers\SkillController.cs

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

Registrasi layanan

Sertakan objek konfigurasi autentikasi dengan validasi klaim apa pun, ditambah semua objek tambahan. Sampel ini menggunakan logika konfigurasi autentikasi yang sama untuk memvalidasi aktivitas dari pengguna dan keterampilan.

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

Menguji bot akar

Anda dapat menguji konsumen keterampilan di Emulator seolah-olah itu adalah bot normal; namun, Anda perlu menjalankan bot konsumen keterampilan dan keterampilan secara bersamaan. Lihat cara menerapkan keterampilan untuk informasi tentang cara mengonfigurasi keterampilan.

Unduh dan instal Emulator Kerangka Kerja Bot terbaru

  1. Jalankan bot keterampilan gema dan bot akar sederhana secara lokal di komputer Anda. Jika Anda memerlukan instruksi, lihat README file untuk sampel C#, JavaScript, Java, atau Python .
  2. Gunakan Emulator untuk menguji bot seperti yang ditunjukkan di bawah ini. Saat Anda mengirim end pesan atau stop ke keterampilan, keterampilan mengirim ke bot endOfConversation akar aktivitas, selain pesan balasan. endOfConversation Properti kode aktivitas menunjukkan bahwa keterampilan berhasil diselesaikan.

Contoh transkrip interaksi dengan konsumen keterampilan.

Selengkapnya tentang penelusuran kesalahan

Karena lalu lintas antara keterampilan dan konsumen keterampilan diautentikasi, ada langkah tambahan saat men-debug bot tersebut.

  • Konsumen keterampilan dan semua keterampilan yang dikonsumsinya, secara langsung atau tidak langsung, harus berjalan.
  • Jika bot berjalan secara lokal dan jika salah satu bot memiliki ID aplikasi dan kata sandi, semua bot harus memiliki ID dan kata sandi yang valid.
  • Jika semua bot disebarkan, lihat cara Men-debug bot dari saluran apa pun menggunakan ngrok.
  • Jika beberapa bot berjalan secara lokal dan beberapa disebarkan, lihat cara Men-debug keterampilan atau konsumen keterampilan.

Jika tidak, Anda dapat men-debug konsumen keterampilan atau keterampilan seperti Anda men-debug bot lain. Untuk informasi selengkapnya, lihat Men-debug bot dan Debug dengan Emulator Kerangka Kerja Bot.

Informasi Tambahan

Berikut adalah beberapa hal yang perlu dipertimbangkan saat menerapkan bot akar yang lebih kompleks.

Untuk memungkinkan pengguna membatalkan keterampilan multi-langkah

Bot root harus memeriksa pesan pengguna sebelum meneruskannya ke keterampilan aktif. Jika pengguna ingin membatalkan proses saat ini, bot akar dapat mengirim endOfConversation aktivitas ke keterampilan, alih-alih meneruskan pesan.

Untuk bertukar data antara bot akar dan keterampilan

Untuk mengirim parameter ke keterampilan, konsumen keterampilan dapat mengatur properti nilai pada pesan yang dikirimnya ke keterampilan. Untuk menerima nilai pengembalian dari keterampilan, konsumen keterampilan harus memeriksa properti nilai ketika keterampilan mengirim endOfConversation aktivitas.

Untuk menggunakan beberapa keterampilan

  • Jika keterampilan aktif, bot root perlu menentukan keterampilan mana yang aktif dan meneruskan pesan pengguna ke keterampilan yang benar.
  • Jika tidak ada keterampilan yang aktif, bot root perlu menentukan keterampilan mana yang akan dimulai, jika ada, berdasarkan status bot dan input pengguna.
  • Jika Anda ingin mengizinkan pengguna beralih di antara beberapa keterampilan bersamaan, bot root perlu menentukan keterampilan aktif mana yang ingin berinteraksi dengan pengguna sebelum meneruskan pesan pengguna.

Untuk menggunakan mode pengiriman balasan yang diharapkan

Untuk menggunakan mode pengiriman balasan yang diharapkan:

  • Kloning aktivitas dari konteks giliran.
  • Atur properti mode pengiriman aktivitas baru ke "ExpectReplies" sebelum mengirim aktivitas dari bot akar ke keterampilan.
  • Baca balasan yang diharapkan dari isi respons pemanggilan yang dikembalikan dari respons permintaan.
  • Proses setiap aktivitas, baik dalam bot akar atau dengan mengirimkannya ke saluran yang memulai permintaan asli.

Mengharapkan balasan dapat berguna dalam situasi di mana bot yang membalas aktivitas harus menjadi instans bot yang sama yang menerima aktivitas.