기술 구현

적용 대상: SDK v4

기술을 사용하여 다른 봇을 확장할 수 있습니다. 기술은 다른 봇에 대한 작업 집합을 수행할 수 있는 봇입니다.

  • 기술의 인터페이스는 매니페스트에 의해 설명됩니다. 기술의 소스 코드에 액세스할 수 없는 개발자는 매니페스트의 정보를 사용하여 기술 소비자를 디자인할 수 있습니다.
  • 기술은 클레임 유효성 검사를 사용하여 액세스할 수 있는 봇 또는 사용자를 관리할 수 있습니다.

이 문서에서는 사용자의 입력을 에코하는 기술을 구현하는 방법을 보여 줍니다.

일부 유형의 기술 소비자는 일부 유형의 기술 봇을 사용할 수 없습니다. 다음 표에서는 지원되는 조합에 대해 설명합니다.

  다중 테넌트 기술 단일 테넌트 기술 사용자 할당 관리 ID 기술
다중 테넌트 소비자 지원됨 지원되지 않음 지원되지 않음
단일 테넌트 소비자 지원되지 않음 두 앱이 동일한 테넌트에 속하는 경우 지원됨 두 앱이 동일한 테넌트에 속하는 경우 지원됨
사용자 할당 관리 ID 소비자 지원되지 않음 두 앱이 동일한 테넌트에 속하는 경우 지원됨 두 앱이 동일한 테넌트에 속하는 경우 지원됨

참고 항목

Bot Framework JavaScript, C#및 Python SDK는 계속 지원되지만 Java SDK는 2023년 11월에 종료되는 최종 장기 지원으로 사용 중지됩니다. 이 리포지토리 내의 중요한 보안 및 버그 수정만 수행됩니다.

Java SDK를 사용하여 빌드된 기존 봇은 계속 작동합니다.

새 봇 빌드의 경우 Power Virtual Agents 사용을 고려하고 올바른 챗봇 솔루션을 선택하는 방법을 읽어 보세요.

자세한 내용은 봇 빌드의 미래를 참조 하세요.

필수 조건

참고 항목

버전 4.11부터 Bot Framework Emulator에서 로컬로 기술을 테스트하기 위해 앱 ID와 암호가 필요하지 않습니다. Azure에 기술을 배포하려면 여전히 Azure 구독이 필요합니다.

이 샘플 정보

간단한 봇 간 샘플 기술에는 두 개의 봇 에 대한 프로젝트가 포함됩니다.

  • 기술을 구현하는 에코 스킬 봇입니다.
  • 단순 루트 봇 - 기술을 사용하는 루트 봇을 구현합니다.

이 문서에서는 봇 및 어댑터의 지원 논리를 포함하는 기술에 중점을 둡니다.

간단한 루트 봇에 대한 자세한 내용은 기술 소비자를 구현하는 방법을 참조하세요.

리소스

배포된 봇의 경우 봇-봇 인증을 사용하려면 참여하는 각 봇에 유효한 ID 정보가 있어야 합니다. 그러나 앱 ID 및 암호 없이 에뮬레이터를 사용하여 로컬에서 다중 테넌트 기술 및 기술 소비자를 테스트할 수 있습니다.

사용자 연결 봇에서 기술을 사용할 수 있도록 하려면 Azure에 기술을 등록합니다. 자세한 내용은 Azure AI Bot Service에 봇을 등록하는 방법을 참조하세요.

애플리케이션 구성

필요에 따라 해당 구성 파일에 기술의 ID 정보를 추가합니다. 기술 또는 기술 소비자가 ID 정보를 제공하는 경우 둘 다 필요합니다.

허용되는 호출자 배열은 소비자가 기술에 액세스할 수 있는 기술을 제한할 수 있습니다. "*" 요소를 추가하여 기술 소비자의 호출을 수락합니다.

참고 항목

봇 ID 정보 없이 로컬로 기술을 테스트하는 경우 기술이나 기술 소비자는 코드를 실행하여 클레임 유효성 검사를 수행하지 않습니다.

EchoSkillBot\appsettings.json

필요에 따라 appsettings.json 파일에 기술의 ID 정보를 추가합니다.

{
  "MicrosoftAppType": "",
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "MicrosoftAppTenantId": "",

  // 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": [ "*" ]
}

활동 처리기 논리

입력 매개 변수를 허용하려면

기술 소비자는 기술에 정보를 보낼 수 있습니다. 이러한 정보를 수락하는 한 가지 방법은 들어오는 메시지의 속성을 통해 수락하는 것입니다. 또 다른 방법은 이벤트를 처리하고 활동을 호출하는 것입니다.

이 예제의 기술은 입력 매개 변수를 허용하지 않습니다.

대화를 계속하거나 완료하려면

기술이 활동을 보내면 기술 소비자는 활동을 사용자에게 전달해야 합니다.

그러나 기술이 완료되면 활동을 보내야 endOfConversation 합니다. 그렇지 않으면 기술 소비자는 사용자 활동을 계속 기술로 전달합니다. 필요한 경우 활동의 value 속성을 사용하여 반환 값을 포함시키고, 활동의 code 속성을 사용하여 기술이 종료되는 이유를 표시합니다.

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

기술을 취소하려면

멀티 턴 기술의 경우 기술 소비자의 활동을 수락 endOfConversation 하여 소비자가 현재 대화를 취소할 수 있도록 합니다.

이 기술에 대한 논리는 차례로 변경되지 않습니다. 대화 리소스를 할당하는 기술을 구현하는 경우 리소스 클린up 코드를 대화 종료 처리기에 추가합니다.

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

클레임 유효성 검사기

이 샘플에서는 클레임 유효성 검사에 허용되는 호출자 목록을 사용합니다. 목록은 기술의 구성 파일에 정의되며, 이 목록을 만들 때 유효성 검사기 개체로 읽습니다.

인증 구성에 클레임 유효성 검사기를 추가해야 합니다. 클레임은 인증 헤더 후에 평가됩니다. 유효성 검사 코드는 요청을 거부하는 오류 또는 예외를 throw해야 합니다. 그렇지 않으면 인증된 요청을 거부할 수 있는 여러 가지 이유가 있습니다. 예시:

  • 이 기술은 유료 서비스의 일부입니다. 데이터베이스에 사용자가 없으면 액세스할 수 없습니다.
  • 기술은 독점적입니다. 특정 기술 소비자만 이 기술을 호출할 수 있습니다.

Important

클레임 유효성 검사기를 제공하지 않으면 봇은 기술 소비자로부터 활동을 받으면 오류 또는 예외를 생성합니다.

SDK는 기술을 호출할 수 있는 애플리케이션의 간단한 ID 목록을 기반으로 애플리케이션 수준 권한 부여를 추가하는 클래스를 제공합니다 AllowedCallersClaimsValidator . 목록에 별표(*)가 포함되어 있으면 모든 호출자가 허용됩니다. 클레임 유효성 검사기는 Startup.cs에서 구성됩니다.

기술 어댑터

오류가 발생하면 기술 어댑터가 기술에 대한 대화 상태를 지워야 하며 기술 소비자에게도 활동을 보내야 endOfConversation 합니다. 활동의 code 속성을 사용하여 오류로 인해 기술이 종료되었다는 신호를 보냅니다.

EchoSkillBot\SkillAdapterWithErrorHandler.cs

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

서비스 등록

Bot Framework 어댑터는 인증 구성 개체(어댑터가 만들어질 때 설정됨)를 사용하여 들어오는 요청에서 인증 헤더의 유효성을 검사합니다.

이 샘플에서는 클레임 유효성 검사를 인증 구성에 추가하고, 이전 섹션에서 설명한 오류 처리기가 있는 기술 어댑터를 사용합니다.

EchoSkillBot\Startup.cs

    options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth;
});

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

    var claimsValidator = new AllowedCallersClaimsValidator(allowedCallers);

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

// Create the Bot Framework Authentication to be used with the Bot Adapter.
services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();

기술 매니페스트

기술 매니페스트는 기술이 수행할 수 있는 활동, 입력 및 출력 매개 변수 및 기술의 엔드포인트를 설명하는 JSON 파일입니다. 매니페스트에는 다른 봇의 기술에 액세스하는 데 필요한 정보가 포함됩니다. 최신 스키마 버전은 v2.1입니다.

EchoSkillBot\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 파일입니다. 현재 스키마 버전은 2.1.0입니다.

기술 테스트

이제 Emulator에서 기술을 표준 봇처럼 테스트할 수 있습니다. 그러나 기술로 테스트하려면 기술 소비자구현해야 합니다.

최신 Bot Framework Emulator를 다운로드하고 설치합니다.

  1. 머신에서 에코 기술 봇을 로컬로 실행합니다. 지침이 필요한 경우 C#, JavaScript, Java 또는 Python 샘플에 대한 파일을 참조 README 하세요.
  2. 에뮬레이터를 사용하여 아래와 같이 봇을 테스트합니다. 기술에 "end" 또는 "stop" 메시지를 보내면 회신 메시지 외에 활동을 보냅니다 endOfConversation . 기술에서 기술이 완료되었음을 나타내는 endOfConversation 활동을 보냅니다.

Example transcript showing the end-of-conversation activity.

디버깅에 대한 자세한 정보

기술과 기술 소비자 간의 트래픽이 인증되므로 이러한 봇을 디버깅할 때 추가 단계가 있습니다.

  • 기술 소비자와 직접 또는 간접적으로 사용하는 모든 기술을 실행해야 합니다.
  • 봇이 로컬로 실행되고 앱 ID와 암호가 있는 봇이 있는 경우 모든 봇에는 유효한 ID와 암호가 있어야 합니다.
  • 봇이 모두 배포된 경우 ngrok사용하여 모든 채널에서 봇을 디버그하는 방법을 참조하세요.
  • 일부 봇이 로컬로 실행되고 일부 봇이 배포된 경우 기술 또는 기술 소비자를 디버그하는 방법을 알아보세요.

그렇지 않으면 다른 봇을 디버그하는 것처럼 기술 소비자 또는 기술을 디버그할 수 있습니다. 자세한 내용은 Bot Framework Emulator를 사용하여 봇 디버깅 및 디버그를 참조하세요.

다음 단계