Реализация навыкаImplement a skill

применимо к: Пакет SDK v4APPLIES TO: SDK v4

Вы можете использовать навыки для расширения функциональности другого бота.You can use skills to extend another bot. Навыком здесь называется бот, который может выполнять ряд задач для другого бота.A skill is a bot that can perform a set of tasks for another bot.

  • Интерфейс навыка описывается манифестом.A skill's interface is described by a manifest. Разработчики, у которых нет доступа к исходному коду навыка, могут использовать информацию из этого манифеста для разработки потребителя навыка.Developers who don't have access to the skill's source code can use the information in the manifest to design their skill consumer.
  • Навык может использовать проверку утверждений для управления доступом от других ботов и пользователей.A skill can use claims validation to manage which bots or users can access it.

В этой статье демонстрируется реализация навыка, который выводит на экран вводимые пользователем данные.This article demonstrates how to implement a skill that echoes the user's input.

Предварительные требованияPrerequisites

Примечание

Начиная с версии 4,11 для проверки навыка локально в Emulator не требуется идентификатор приложения и пароль.Starting with version 4.11, you do not need an app ID and password to test a skill locally in the Emulator. Подписка Azure по-прежнему необходима для развертывания вашего навыка в Azure.An Azure subscription is still required to deploy your skill to Azure.

Об этом примереAbout this sample

В пример простого навыка для ботов включены проекты двух ботов:The skills simple bot-to-bot sample includes projects for two bots:

  • бот эхо-навыка, который реализует этот навык;The echo skill bot, which implements the skill.
  • простой корневой бот, который реализует бот для использования этого навыка.The simple root bot, which implements a root bot that consumes the skill.

Эта статья посвящена навыку, в том числе логике поддержки в боте и адаптере.This article focuses on the skill, which includes support logic in its bot and adapter.

Сведения о простом корневом боте см. в статье о реализации потребителя навыка.For information about the simple root bot, see how to Implement a skill consumer.

РесурсыResources

Для развернутого программы-роботы проверка подлинности «Bot-to-Bot» требует, чтобы каждый участвующий робот получил допустимые идентификатор приложения и пароль.For deployed bots, bot-to-bot authentication requires that each participating bot has a valid app ID and password. тем не менее вы можете протестировать навыки и квалификацию для потребителей локально с Emulator без идентификатора приложения и пароля.However, you can test skills and skill consumers locally with the Emulator without an app ID and password.

Чтобы сделать навык доступным для программы-роботы пользователей, зарегистрируйте навык в Azure.To make the skill available to user-facing bots, register the skill with Azure. Для этого можно применить службу "Регистрация каналов бота".You can use a Bot Channels Registration. Дополнительные сведения см. в статье о регистрации бота в службе Azure Bot.For more information, see how to register a bot with Azure Bot Service.

Конфигурация приложенийApplication configuration

При необходимости добавьте идентификатор и пароль приложения навыка в файл конфигурации навыка.Optionally, add the skill's app ID and password to the skill's configuration file. (Если потребитель или навык используют идентификатор приложения и пароль, оба должны быть.)(If either the skill or skill consumer uses an app ID and password, both must.)

Массив allowed callers позволяет ограничить круг потребителей, имеющих доступ к этому навыку.The allowed callers array can restrict which skill consumers can access the skill. Добавьте элемент "*", чтобы принимать вызовы от любого потребителя навыков.Add an "*" element, to accept calls from any skill consumer.

Примечание

Если вы тестируете свой навык локально без идентификатора и пароля приложения, ни навык, ни потребитель опыта не выполняют код для проверки утверждения.If you are testing your skill locally without an app ID and password, neither the skill nor the skill consumer run the code to perform claims validation.

EchoSkillBot\appsettings.jsonEchoSkillBot\appsettings.json

Добавьте в файл appsettings.json идентификатор приложения и пароль для этого навыка.Add the skill's app ID and password to the appsettings.json file.

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

  // This is a comma separate list with the App IDs that will have access to the skill.
  // This setting is used in AllowedCallersClaimsValidator.
  // Examples: 
  //    [ "*" ] allows all callers.
  //    [ "AppId1", "AppId2" ] only allows access to parent bots with "AppId1" and "AppId2".
  "AllowedCallers": [ "*" ]
}

Логика обработчика действийActivity handler logic

Прием входных параметровTo accept input parameters

Потребитель навыка может отправить информацию в этот навык.The skill consumer can send information to the skill. Один из способов принять такую информацию — через свойство value входящего сообщения.One way to accept such information is to accept them via the value property on incoming messages. Другой способ — обработка действий события и вызова.Another way is to handle event and invoke activities.

В этом примере навык не принимает входные параметры.The skill in this example doesn't accept input parameters.

Продолжение или завершение беседыTo continue or complete a conversation

Когда навык отправляет действие, потребитель навыка должен перенаправить это действие пользователю.When the skill sends an activity, the skill consumer should forward the activity on to the user.

Но при завершении работы навыка необходимо отправить действие endOfConversation, иначе потребитель навыка будет и далее пересылать действия пользователя в навык.However, you need to send an endOfConversation activity when the skill finishes; otherwise, the skill consumer will continue to forward user activities to the skill. Можно также поместить возвращаемое значение в свойство value, а причину завершения навыка — в свойство code обрабатываемого действия.Optionally, use the activity's value property to include a return value, and use the activity's code property to indicate why the skill is ending.

EchoSkillBot\Bots\EchoBot.csEchoSkillBot\Bots\EchoBot.cs

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Text.Contains("end") || turnContext.Activity.Text.Contains("stop"))
    {
        // Send End of conversation at the end.
        var messageText = $"ending conversation from the skill...";
        await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.IgnoringInput), cancellationToken);
        var endOfConversation = Activity.CreateEndOfConversationActivity();
        endOfConversation.Code = EndOfConversationCodes.CompletedSuccessfully;
        await turnContext.SendActivityAsync(endOfConversation, cancellationToken);
    }
    else
    {
        var messageText = $"Echo: {turnContext.Activity.Text}";
        await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.IgnoringInput), cancellationToken);
        messageText = "Say \"end\" or \"stop\" and I'll end the conversation and back to the parent.";
        await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.ExpectingInput), cancellationToken);
    }
}

Отмена выполнения навыкаTo cancel the skill

В навыках с несколькими репликами необходимо также принимать от потребителя навыков действия endOfConversation, которые позволят потребителю отменить текущую беседу.For multi-turn skills, you would also accept endOfConversation activities from a skill consumer, to allow the consumer to cancel the current conversation.

Логика для этого навыка не меняется от включения.The logic for this skill doesn't change from turn to turn. Если реализуемый вами навык выделяет ресурсы для беседы, добавьте в обработчик завершения беседы код для очистки этих ресурсов.If you implement a skill that allocates conversation resources, add resource cleanup code to the end-of-conversation handler.

EchoSkillBot\Bots\EchoBot.csEchoSkillBot\Bots\EchoBot.cs

protected override Task OnEndOfConversationActivityAsync(ITurnContext<IEndOfConversationActivity> turnContext, CancellationToken cancellationToken)
{
    // This will be called if the root bot is ending the conversation.  Sending additional messages should be
    // avoided as the conversation may have been deleted.
    // Perform cleanup of resources if needed.
    return Task.CompletedTask;
}

Средство проверки утвержденийClaims validator

В нашем примере для проверки утверждений используется список разрешенных вызывающих объектов.This sample uses an allowed callers list for claims validation. Этот список определен в файле конфигурации навыка и считывается в объект средства проверки при его создании.The list is defined in the skill's configuration file and is read into the validator object when it's created.

Необходимо добавить проверяющий элемент управления утверждения в конфигурацию проверки подлинности.You must add a claims validator to the authentication configuration. Утверждения оцениваются после заголовка проверки подлинности.The claims are evaluated after the authentication header. Код средства проверки должен создавать исключение или ошибку, чтобы отклонить запрос.Your validation code should throw an error or exception to reject the request. Отклонение запроса, уже прошедшего проверку подлинности, может потребоваться по разным причинам.There are many reasons you may want to reject an otherwise authenticated request. Пример:For example:

  • навык предоставляется как часть платной службы;The skill is part of a paid-for service. Пользователь не должен иметь доступ к базе данных.User's not in the database shouldn't have access.
  • доступ к навыку ограничен правообладателем;The skill is proprietary. вызвать навык могут только определенные потребители.Only certain skill consumers can call the skill.

Важно!

Если вы не предложит проверяющий элемент управления утверждениями, программа Bot создаст ошибку или исключение при получении действия от потребителя навыков.If you don't provide a claims validator, your bot will generate an error or exception upon receiving an activity from the skill consumer.

Пакет SDK предоставляет AllowedCallersClaimsValidator класс, который добавляет авторизацию на уровне приложения на основе простого списка идентификаторов приложений, которым разрешено вызывать навык.The SDK provides an AllowedCallersClaimsValidator class that adds application-level authorization based on a simple list of IDs of the applications that are allowed to call the skill. Если список содержит звездочку (*), то все вызывающие объекты разрешены.If the list contains an asterisk (*), then all callers are allowed. Проверяющий элемент управления утверждениями настраивается в Startup. CS.The claims validator is configured in Startup.cs.

Адаптер навыкаSkill adapter

При возникновении ошибки адаптер навыка должен очистить состояние беседы для этого навыка и отправить потребителю действие endOfConversation.When an error occurs, the skill's adapter should clear conversation state for the skill, and it should also send an endOfConversation activity to the skill consumer. Используйте свойство code в этом действии, чтобы сообщить о завершении навыка из-за ошибки.Use the code property of the activity to signal that the skill ended due to an error.

EchoSkillBot\SkillAdapterWithErrorHandler.csEchoSkillBot\SkillAdapterWithErrorHandler.cs

public SkillAdapterWithErrorHandler(IConfiguration configuration, ICredentialProvider credentialProvider, AuthenticationConfiguration authConfig, ILogger<BotFrameworkHttpAdapter> logger)
    : base(configuration, credentialProvider, authConfig, logger: logger)
{
    _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    OnTurnError = HandleTurnError;
}

private async Task HandleTurnError(ITurnContext turnContext, Exception exception)
{
    // Log any leaked exception from the application.
    _logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

    await SendErrorMessageAsync(turnContext, exception);
    await SendEoCToParentAsync(turnContext, exception);
}

private async Task SendErrorMessageAsync(ITurnContext turnContext, Exception exception)
{
    try
    {
        // Send a message to the user.
        var errorMessageText = "The skill 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.
        // Note: we return the entire exception in the value property to help the developer;
        // this should not be done in production.
        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 SendEoCToParentAsync(ITurnContext turnContext, Exception exception)
{
    try
    {
        // Send an EndOfConversation activity to the skill caller with the error to end the conversation,
        // and let the caller decide what to do.
        var endOfConversation = Activity.CreateEndOfConversationActivity();
        endOfConversation.Code = "SkillError";
        endOfConversation.Text = exception.Message;
        await turnContext.SendActivityAsync(endOfConversation);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Exception caught in SendEoCToParentAsync : {ex}");
    }
}

Регистрация службыService registration

Адаптер Bot Framework использует объект конфигурации проверки подлинности, который настраивается при создании адаптера, для проверки заголовков проверки подлинности во входящих запросах.The Bot Framework adapter uses an authentication configuration object (set when the adapter is created) to validate the authentication header on incoming requests.

В нашем примере в конфигурацию проверки подлинности добавляется проверка утверждений, а также применяется адаптер навыка с обработчиком ошибок, который описан в предыдущем разделе.This sample adds claims validation to the authentication configuration and uses the skill adapter with error handler described in the previous section.

EchoSkillBot\Startup.csEchoSkillBot\Startup.cs

// Register AuthConfiguration to enable custom claim validation.
services.AddSingleton(sp => new AuthenticationConfiguration
{
    ClaimsValidator = new AllowedCallersClaimsValidator(new List<string>(sp.GetService<IConfiguration>().GetSection("AllowedCallers").Get<string[]>()))
});

// Create the Bot Framework Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, SkillAdapterWithErrorHandler>();

Манифест навыкаSkill manifest

Манифест навыка — это файл в формате JSON с описанием действий, которые может выполнять навык, его входных и выходных параметров, а также конечных точек навыка.A skill manifest is a JSON file that describes the activities the skill can perform, its input and output parameters, and the skill's endpoints. Манифест содержит сведения, которые вам нужны для доступа к навыку из другого бота.The manifest contains the information you need to access the skill from another bot. Последняя версия схемы — v 2.1.The latest schema version is v2.1.

EchoSkillBot\wwwroot\manifest\echoskillbot-manifest-1.0.jsonEchoSkillBot\wwwroot\manifest\echoskillbot-manifest-1.0.json

{
  "$schema": "https://schemas.botframework.com/schemas/skills/skill-manifest-2.0.0.json",
  "$id": "EchoSkillBot",
  "name": "Echo Skill bot",
  "version": "1.0",
  "description": "This is a sample echo skill",
  "publisherName": "Microsoft",
  "privacyUrl": "https://echoskillbot.contoso.com/privacy.html",
  "copyright": "Copyright (c) Microsoft Corporation. All rights reserved.",
  "license": "",
  "iconUrl": "https://echoskillbot.contoso.com/icon.png",
  "tags": [
    "sample",
    "echo"
  ],
  "endpoints": [
    {
      "name": "default",
      "protocol": "BotFrameworkV3",
      "description": "Default endpoint for the skill",
      "endpointUrl": "http://echoskillbot.contoso.com/api/messages",
      "msAppId": "00000000-0000-0000-0000-000000000000"
    }
  ]
}

Схема манифеста навыка представляет собой файл в формате JSON с описанием схемы манифеста навыков.The skill manifest schema is a JSON file that describes the schema of the skill manifest. Текущая версия схемы — 2.1.0.The current schema version is 2.1.0.

Тестирование навыкаTest the skill

На этом этапе вы можете проверить работу навыка в эмуляторе, как для любого обычного бота.At this point, you can test the skill in the Emulator as if it were a normal bot. Но прежде, чем протестировать его как навык, необходимо реализовать потребитель навыка.However, to test it as a skill, you would need to implement a skill consumer.

Скачайте и установите последнюю версию Bot Framework Emulator.Download and install the latest Bot Framework Emulator

  1. Запустите бот с эхо-навыком на локальном компьютере.Run the echo skill bot locally on your machine. Если вам нужны инструкции, ознакомьтесь с README файлом для примера на C#, JavaScript, Javaили Python .If you need instructions, refer to the README file for the C#, JavaScript, Java, or Python sample.
  2. Примените эмулятор для тестирования бота, как показано ниже.Use the Emulator to test the bot as shown below. При отправке "конечного" или "завершающего" сообщения в навык он отправляет endOfConversation в дополнение к ответному сообщению действие.When you send an "end" or "stop" message to the skill, it sends an endOfConversation activity in addition to the reply message. Навык отправляет действие endOfConversation, чтобы обозначить завершение своей работы.The skill sends the endOfConversation activity to indicate the skill has finished.

Тестирование эхо-навыка

Дальнейшие действияNext steps