スキルを実装する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 でスキルをローカルにテストするために、アプリ ID とパスワードは必要ありません。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

skills simple bot-to-bot サンプルには、次の 2 つのボットのプロジェクトが含まれています。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 の場合、bot to bot 認証では、参加している各 bot が有効なアプリ ID とパスワードを持っている必要があります。For deployed bots, bot-to-bot authentication requires that each participating bot has a valid app ID and password. ただし、アプリ ID とパスワードを使用せずに、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. Bot Channels Registration を使用できます。You can use a Bot Channels Registration. 詳細については、「ボットを Azure Bot Service に登録する」を参照してください。For more information, see how to register a bot with Azure Bot Service.

アプリケーションの構成Application configuration

必要に応じて、スキルのアプリ ID とパスワードをスキルの構成ファイルに追加します。Optionally, add the skill's app ID and password to the skill's configuration file. (スキルまたはスキルのコンシューマーがアプリ ID とパスワードを使用している場合、どちらもである必要があります)。(If either the skill or skill consumer uses an app ID and password, both must.)

"許可される呼び出し元" の配列 (AllowedCallers) では、スキルにアクセスできるスキル コンシューマーを制限できます。The allowed callers array can restrict which skill consumers can access the skill. 任意のスキルコンシューマーからの呼び出しを受け入れるには、"*" 要素を追加します。Add an "*" element, to accept calls from any skill consumer.

注意

アプリ ID とパスワードを使用せずにスキルをローカルでテストしている場合は、スキルとスキルの両方のコンシューマーが、要求の検証を実行するコードを実行しません。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

スキルのアプリ ID とパスワードを 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. この情報を受け入れる方法の 1 つは、受信したメッセージの value プロパティを介して受け入れることです。One way to accept such information is to accept them via the value property on incoming messages. もう 1 つの方法は、イベントを処理し、アクティビティを呼び出すことです。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 には、スキルの呼び出しが許可されているアプリケーションの ID の単純な一覧に基づいて、アプリケーション レベルの承認を追加 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. 最新のスキーマ バージョンは v2.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. スキルに "end" または "stop" メッセージを送信すると、応答メッセージに加 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