Condividi tramite


Implementare un'abilità

SI APPLICA A: SDK v4

È possibile usare le competenze per estendere un altro bot. Una competenza è un bot che può eseguire un set di attività per un altro bot.

  • Un manifesto descrive l'interfaccia di una competenza. Gli sviluppatori che non hanno accesso al codice sorgente della skill possono usare le informazioni nel manifesto per progettare il proprio utente della skill.
  • Una competenza può usare la convalida delle attestazioni per gestire quali bot o utenti possono accedervi.

Questo articolo illustra come implementare un'abilità che restituisce l'input dell'utente.

Alcuni tipi di utenti delle competenze non sono in grado di usare alcuni tipi di bot delle competenze. Nella tabella seguente vengono descritte le combinazioni supportate.

  Competenza multi-tenant Competenza a locatario unico Abilità di identità gestita assegnata dall'utente
Consumer multi-tenant Supportato Non supportato Non supportato
Consumer a tenant singolo Non supportato Supportato se entrambe le app appartengono allo stesso tenant Supportato se entrambe le app appartengono allo stesso tenant
Consumer di identità gestita assegnata dall'utente Non supportato Supportato se entrambe le app appartengono allo stesso tenant Supportato se entrambe le app appartengono allo stesso tenant

Nota

Gli SDK JavaScript, C# e Python di Bot Framework continueranno a essere supportati, ma Java SDK verrà ritirato con il supporto finale a lungo termine che termina a novembre 2023.

I bot esistenti creati con Java SDK continueranno a funzionare.

Per la creazione di nuovi bot, è consigliabile usare Microsoft Copilot Studio e leggere le informazioni sulla scelta della soluzione copilota appropriata.

Per altre informazioni, vedere Il futuro della creazione di bot.

Prerequisiti

Nota

A partire dalla versione 4.11, non è necessario un ID app e una password per testare una competenza in locale in Bot Framework Emulator. Per distribuire la skill in Azure, è ancora necessario un abbonamento Azure.

Informazioni sull'esempio

L'esempio di competenza semplice da bot a bot include i progetti per due bot:

  • Il bot di echo skill, che implementa l'abilità.
  • Il bot radice semplice, che implementa un bot radice che sfrutta l'abilità.

Questo articolo è incentrato sull'abilità, che include la logica di supporto nei relativi bot e adattatori.

Per informazioni sul bot radice semplice, vedere Implementare un consumatore di abilità.

Risorse

Per i bot distribuiti, l'autenticazione da bot a bot richiede che ogni bot partecipante disponga di informazioni di identità valide. Tuttavia, è possibile testare le competenze multi-tenant e i consumer di competenze in locale con l'emulatore senza un ID app e una password.

Per rendere disponibile la competenza per i bot rivolti agli utenti, registrare la competenza con Azure. Per altre informazioni, vedere come registrare un bot con Azure AI servizio Bot.

Configurazione dell'applicazione

Facoltativamente, aggiungere le informazioni sull'identità della competenza al file di configurazione. Se le competenze o l'utente delle competenze forniscono informazioni sull'identità, entrambi devono farlo.

La matrice di chiamanti consentiti può limitare quali utenti possono accedere alla competenza. Per accettare chiamate da qualsiasi utente di abilità, si deve aggiungere un elemento '*'.

Nota

Se si sta testando la skill in locale senza i dati sull'identità del bot, né la skill né l'utilizzatore della skill eseguono il codice per effettuare la convalida delle attestazioni.

EchoSkillBot\appsettings.json

Facoltativamente, aggiungere le informazioni sull'identità della competenza al file di appsettings.json.

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

Logica del gestore di attività

Accettare parametri di input

L'utente della skill può inviare informazioni all'abilità. Un modo per accettare tali informazioni è tramite la proprietà value dei messaggi in arrivo. Un altro modo consiste nel gestire l'evento e richiamare le attività.

L'abilità in questo esempio non accetta parametri di input.

Per continuare o completare una conversazione

Quando l'abilità invia un'attività, il consumatore dell'abilità deve inoltrare l'attività all'utente.

Tuttavia, è necessario inviare un'attività endOfConversation al termine dell'uso della skill; in caso contrario, l'utente continua a inoltrare le attività utente alla skill. Facoltativamente, usare la proprietà value dell'attività per includere un valore restituito e la proprietà code dell'attività per indicare il motivo per cui la competenza verrà terminata.

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

Per annullare l'abilità

Per le abilità a più turni, si accettano anche le attività endOfConversation inviate da un utente dell'abilità, per permettere all'utente di annullare la conversazione corrente.

La logica per questa abilità non cambia da turno a turno. Se si implementa una skill che alloca le risorse della conversazione, aggiungere il codice di pulizia delle risorse al gestore di fine conversazione.

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

Validatore di richieste

Questo esempio usa un elenco di chiamanti consentiti per la convalida delle attestazioni. Il file di configurazione della competenza definisce l'elenco. L'oggetto validator legge quindi l'elenco.

È necessario aggiungere un validator di attestazioni alla configurazione di autenticazione. Le attestazioni vengono valutate dopo l'intestazione di autenticazione. Il codice di convalida deve generare un errore o un'eccezione per rifiutare la richiesta. Esistono molti motivi per cui si potrebbe voler rifiutare una richiesta altrimenti autenticata. Ad esempio:

  • La competenza è inclusa in un servizio a pagamento. Gli utenti che non sono nel database non dovrebbero avere accesso.
  • La competenza è proprietaria. Solo alcuni utenti delle competenze possono utilizzare la competenza.

Importante

Se non si fornisce un validatore di reclami, il bot genererà un errore o un'eccezione quando riceverà un'attività dal consumatore di competenze.

L'SDK fornisce una classe che aggiunge l'autorizzazione AllowedCallersClaimsValidator a livello di applicazione in base a un semplice elenco di ID delle applicazioni autorizzate a chiamare la competenza. Se l'elenco contiene un asterisco (*), tutti i chiamanti sono consentiti. Il validator di attestazioni è configurato in Startup.cs.

Adattatore di abilità

Quando si verifica un errore, l'adattatore dell'abilità deve cancellare lo stato della conversazione per l'abilità e inviare un'attività endOfConversation all'utente dell'abilità. Per segnalare che l'abilità è terminata a causa di un errore, usare la proprietà code dell'attività.

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

Registrazione del servizio

Per la convalida dell'intestazione di autenticazione nelle richieste in arrivo, l'adapter Bot Framework usa un oggetto configurazione dell'autenticazione impostato durante la creazione dell'adapter.

In questo esempio la convalida delle attestazioni viene aggiunta alla configurazione di autenticazione e viene usato l'adapter della competenza con il gestore di errori descritto nella sezione precedente.

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

Manifesto della competenza

Un manifesto della competenza è un file JSON che descrive le attività eseguibili con la competenza, i relativi parametri di input e output e gli endpoint della competenza. Il manifest contiene le informazioni necessarie per accedere alla funzionalità da un altro bot. La versione più recente dello schema è 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"
    }
  ]
}

Lo schema del manifesto della competenza è un file JSON che descrive lo schema del manifesto della competenza. La versione corrente dello schema è 2.1.0.

Testare la competenza

A questo punto è possibile testare la competenza in Emulator come se si trattasse di un normale bot. Per testarlo come una competenza, è necessario implementare un consumer di competenze.

Scaricare e installare l'ultima versione di Bot Framework Emulator

  1. Eseguire il bot della skill echo localmente nel computer. Se hai bisogno di istruzioni, fai riferimento al file per l'esempio README, JavaScript, Java o Python.
  2. Usare l'emulatore per testare il bot. Quando si invia un messaggio "end" o "stop" alla skill, invia un'attività endOfConversation oltre al semplice messaggio di risposta. La funzionalità invia l'attività endOfConversation per indicare che l'abilità è conclusa.

Esempio di trascrizione che mostra l'attività di fine conversazione.

Altre informazioni sul debug

Poiché il traffico tra competenze e utilizzatori di competenze viene autenticato, è necessario eseguire passaggi aggiuntivi durante il debugging di tali bot.

  • Il consumatore di capacità e tutte le capacità che esso consuma, direttamente o indirettamente, devono essere attive.
  • Se i bot vengono eseguiti localmente e se uno dei bot ha un ID app e una password, tutti i bot devono avere ID e password validi.
  • Se tutti i bot vengono distribuiti, vedere come eseguire il debug di un bot da qualsiasi canale usando devtunnel.
  • Se alcuni bot sono in esecuzione in locale e alcuni vengono distribuiti, vedere come eseguire il debug di una competenza o di un consumer di competenze.

In caso contrario, è possibile eseguire il debug di un consumatore di abilità o di un'abilità in modo molto simile al debug di altri bot. Per altre informazioni, vedere Debug di un bot e Debug con Bot Framework Emulator.

Passaggi successivi