Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Importante
A partire dal 20 settembre 2023 non sarà possibile creare nuove risorse di Personalizer. Il servizio Personalizer sarà ritirato il 1° ottobre 2026. Consigliamo di migrare al microsoft/learning-loop open-source.
Usare un chatbot C# .NET con un loop Personalizer per fornire il contenuto corretto a un utente. Questo chatbot suggerisce un caffè o un tè specifico a un utente. L'utente può accettare o rifiutare il suggerimento. In questo modo, vengono fornite a Personalizer informazioni per aiutare a rendere il prossimo suggerimento più appropriato.
In questa esercitazione si imparerà come:
- Configurare le risorse di Azure
- Configurare ed eseguire il bot
- Interagire con il bot tramite Bot Framework Emulator
- Acquisire informazioni su dove e come il bot utilizza Personalizer
Come funziona il chat bot?
Un chatbot è in genere una conversazione in più passaggi con un utente. Questo chatbot specifico utilizza Personalizer per selezionare la migliore azione (caffè o tè) da offrire all'utente. Personalizer usa l'apprendimento per rinforzo per effettuare la selezione.
Il chatbot deve gestire i turni nella conversazione. Il chatbot usa Bot Framework per gestire l'architettura e la conversazione del bot e usa Azure AI Language Understanding (LUIS) per comprendere la finalità del linguaggio naturale dell'utente.
Il chatbot è un sito Web con una route specifica disponibile per rispondere alle richieste, http://localhost:3978/api/messages. È possibile usare l'emulatore di Bot Framework Emulator per interagire visivamente con il chatbot in esecuzione mentre sviluppi un bot in locale.
Interazioni utente con il bot
Questo è un semplice chatbot che consente di immettere query di testo.
| L'utente immette il testo | Il bot risponde con un testo | Descrizione dell'azione eseguita dal bot per determinare il testo della risposta |
|---|---|---|
| Nessun testo immesso. Il bot avvia la conversazione. | This is a simple chatbot example that illustrates how to use Personalizer. The bot learns what coffee or tea order is preferred by customers given some context information (such as weather, temperature, and day of the week) and information about the user.To use the bot, just follow the prompts. To try out a new imaginary context, type “Reset” and a new one will be randomly generated.Welcome to the coffee bot, please tell me if you want to see the menu or get a coffee or tea suggestion for today. Once I’ve given you a suggestion, you can reply with ‘like’ or ‘don’t like’. It’s Tuesday today and the weather is Snowy. |
Il bot avvia la conversazione con testo informativo e comunica all'utente le informazioni sul contesto: Tuesday, Snowy. |
Show menu |
Here is our menu: Coffee: Cappuccino Espresso Latte Macchiato Mocha Tea: GreenTea Rooibos |
Determina la finalità della query con LUIS, quindi visualizza le opzioni del menu per gli elementi caffè e tè. Caratteristiche delle azioni: |
What do you suggest |
How about Latte? |
Determina la finalità della query con LUIS, quindi chiama l'API Classificazione e visualizza la scelta migliore come una domanda How about {response.RewardActionId}?. Visualizza anche la chiamata e la risposta JSON a scopo illustrativo. |
I like it |
That’s great! I’ll keep learning your preferences over time.Would you like to get a new suggestion or reset the simulated context to a new day? |
Determina la finalità della query con LUIS, quindi chiama l'API Ricompensa con la ricompensa 1 e visualizza la chiamata e la risposta JSON a scopo illustrativo. |
I don't like it |
Oh well, maybe I’ll guess better next time.Would you like to get a new suggestion or reset the simulated context to a new day? |
Determina la finalità della query con LUIS, quindi chiama l'API Ricompensa con la ricompensa 0 e visualizza la chiamata e la risposta JSON a scopo illustrativo. |
Reset |
Restituisce il testo istruttivo. | Determina la finalità della query con LUIS, quindi visualizza il testo informativo e reimposta il contesto. |
Personalizzatore in questo bot
Questo chatbot utilizza Personalizer per selezionare l'azione principale (caffè o tè specifico) in base a un elenco di azioni (tipo di contenuto) e funzionalità del contesto.
Il bot invia l'elenco di azioni, insieme alle caratteristiche del contesto, al ciclo di Personalizer. Personalizer restituisce la singola migliore azione al tuo bot, che il tuo bot visualizza.
In questa esercitazione le azioni sono tipi di caffè o tè:
| Caffè | Tè |
|---|---|
| Cappuccino Caffè espresso Latte Moka |
Tè verde Rooibos |
API Classificazione: per consentire al Personalizer di imparare dalle tue azioni, il bot invia quanto segue con ogni richiesta dell'API Classificazione:
- Azioni con caratteristiche
- Caratteristiche del contesto
Una caratteristica del modello è costituita da informazioni sull'azione o sul contesto che possono essere aggregate (raggruppate) tra i membri della base di utenti del chatbot. Una caratteristica non è specifica per un individuo, come un ID utente, né altamente specifica, come l'ora esatta del giorno.
Le caratteristiche vengono usate per allineare le azioni al contesto corrente nel modello. Il modello è una rappresentazione delle conoscenze passate di Personalizer riguardanti azioni, contesto e relative caratteristiche che consente al servizio di prendere decisioni informate.
Il modello, incluse le funzionalità, viene aggiornato in base a una pianificazione basata sulla frequenza di aggiornamento Model nel portale di Azure.
Le caratteristiche devono essere selezionate con la stessa pianificazione e gli stessi criteri che si applicherebbero a qualsiasi schema o modello nell'architettura tecnica. I valori delle caratteristiche possono essere impostati con la logica di business o con sistemi di terze parti.
Attenzione
Le caratteristiche di questa applicazione sono a scopo dimostrativo e potrebbero non essere necessariamente le caratteristiche migliori da usare in un'app Web per il caso d'uso corrente.
Caratteristiche delle azioni
Ogni azione (elemento di contenuto) include caratteristiche che aiutano a distinguere l'elemento specifico di caffè o tè.
Le funzionalità non sono configurate come parte della configurazione del ciclo nel portale di Azure. Vengono invece inviate come oggetto JSON con ogni chiamata all'API Classificazione. In questo modo, le azioni e le relative caratteristiche possono aumentare, cambiare e diminuire con flessibilità, consentendo a Personalizer di seguire le tendenze.
Le caratteristiche per caffè e tè includono:
- Località di origine dei chicchi di caffè, ad esempio Kenya e Brasile
- Il caffè o il tè è biologico?
- Tostatura del caffè chiara o scura
Sebbene per il caffè siano presenti tre caratteristiche nell'elenco precedente, il tè ne include solo una. Passare a Personalizza esperienze solo le caratteristiche significative per l'azione. Non passare un valore vuoto per una caratteristica se non è applicabile all'azione.
Caratteristiche del contesto
Le caratteristiche contestuali consentono a Personalizer di comprendere il contesto, come il dispositivo di visualizzazione, l'utente, la località e altre funzionalità rilevanti per il vostro caso d'uso.
Il contesto per questo chatbot include:
- Tipo di meteo (nevoso, piovoso, soleggiato)
- Giorno della settimana
La selezione delle caratteristiche è casuale in questo chatbot. In un bot reale usare dati reali per le caratteristiche del contesto.
Considerazioni di progettazione per questo bot
Per questa conversazione, è necessario prestare attenzione ad alcuni fattori:
- Interazione con il bot: la conversazione è molto semplice perché mostra l'uso della classificazione e della ricompensa in un caso d'uso di base. Non vengono illustrate le funzionalità complete di Bot Framework SDK o dell'emulatore.
- Personalizer: le funzionalità vengono selezionate in modo casuale per simulare l'utilizzo. Non selezionare le caratteristiche in modo casuale in uno scenario di Personalizza esperienze di produzione.
- Language Understanding (LUIS): le poche espressioni di esempio del modello LUIS sono destinate solo a questo esempio. Non usare un numero così ridotto di espressioni di esempio nell'applicazione LUIS di produzione.
Installare il software necessario
- Visual Studio 2019. Il repository degli esempi scaricabili include istruzioni se preferisci usare .NET Core CLI.
- Microsoft Bot Framework Emulator è un'applicazione desktop che consente agli sviluppatori di bot di testare ed eseguire il debug dei bot in localhost o in esecuzione in remoto tramite un tunnel.
Scaricare il codice di esempio del chatbot
Il chatbot è disponibile nel repository degli esempi di Personalizer. Clonare o scaricare il repository, quindi aprire l'esempio nella directory con Visual Studio 2019.
Per clonare il repository, usare il comando GIT seguente in una shell Bash (terminale).
git clone https://github.com/Azure-Samples/cognitive-services-personalizer-samples.git
Creare e configurare le risorse Personalizer e LUIS
Creare risorse Azure
Per usare questo chatbot, è necessario creare risorse di Azure per Personalizer e Language Understanding (LUIS).
- Creare le risorse di LUIS. Creare sia una risorsa di creazione che di previsione.
-
Crea la risorsa Personalizer quindi copia la chiave e l'endpoint dal portale di Azure. È necessario impostare questi valori nel file
appsettings.jsondel progetto .NET.
Creare l'app LUIS
Se non si ha familiarità con LUIS, è necessario eseguire l'accesso e procedere immediatamente alla migrazione dell'account. Non è necessario creare nuove risorse, ma selezionare le risorse create nella sezione precedente di questa esercitazione.
- Per creare una nuova applicazione LUIS, nel portale di LUIS selezionare la sottoscrizione e la risorsa di creazione.
- Sempre nella stessa pagina selezionare + Nuova app per la conversazione, quindi Importa come JSON.
- Nella finestra di dialogo popup selezionare Scegliere un file, quindi selezionare il file
/samples/ChatbotExample/CognitiveModels/coffeebot.json. Immettere il nomePersonalizer Coffee bot. - Nella barra di navigazione in alto a destra del portale LUIS, selezionare il pulsante Train.
- Selezionare il pulsante Pubblica per pubblicare l'app nello slot di produzione per il runtime di previsione.
- Selezionare Gestisci e quindi Impostazioni. Copiare il valore di ID App. È necessario impostare questo valore nel file
appsettings.jsondel progetto di .NET. - Sempre nella sezione Manage selezionare Azure Resources. Verranno visualizzate le risorse associate nell'app.
- Selezionare Aggiungi risorsa di previsione. Nella finestra di dialogo popup selezionare la sottoscrizione e la risorsa di previsione creata in una sezione precedente di questa esercitazione, quindi selezionare Fine.
- Copiare i valori di Chiave primaria e URL endpoint. È necessario impostare questi valori nel file
appsettings.jsondel progetto .NET.
Configurare bot con il file appsettings.json
Aprire il file della soluzione chat bot,
ChatbotSamples.sln, con Visual Studio 2019.Aprire
appsettings.jsonnella directory radice del progetto.Impostare tutte e cinque le impostazioni copiate nella sezione precedente di questa esercitazione.
{ "PersonalizerChatbot": { "LuisAppId": "", "LuisAPIKey": "", "LuisServiceEndpoint": "", "PersonalizerServiceEndpoint": "", "PersonalizerAPIKey": "" } }
Compilare ed eseguire il bot
Dopo aver configurato il file appsettings.json, è possibile compilare ed eseguire il chatbot. Quando si esegue questa operazione, viene aperto un browser nel sito Web in esecuzione, http://localhost:3978.
Mantenere il sito Web in esecuzione perché l'esercitazione illustra le operazioni eseguite dal bot, in modo da poter interagire con esso.
Configurare Bot Framework Emulator.
Aprire Bot Framework Emulator e selezionare Open Bot (Apri bot).
Configurare il bot con l'URL del bot seguente, quindi selezionare Connetti:
http://localhost:3978/api/messages
L'emulatore si connette al chatbot e visualizza il testo informativo, insieme alle informazioni di registrazione e di debug utili per lo sviluppo locale.
Usare il bot in Bot Framework Emulator
Per chiedere di visualizzare il menu, immettere
I would like to see the menu. Il chatbot visualizza gli elementi.Per consentire al bot di suggerire un elemento, immettere
Please suggest a drink for me.. L'emulatore visualizza la richiesta e la risposta di classificazione nella finestra della chat, in modo che sia possibile visualizzare il codice JSON completo. Il bot mostra un suggerimento, ad esempioHow about Latte?Se si risponde che si gradisce l'elemento suggerito, significa che si accetta la selezione con la priorità più elevata di Personalizza esperienze,
I like it.. L'emulatore mostra la richiesta di ricompensa con il punteggio di ricompensa 1 e la risposta nella finestra della chat, in modo che sia possibile visualizzare il codice JSON completo. Il bot risponde conThat’s great! I’ll keep learning your preferences over time.eWould you like to get a new suggestion or reset the simulated context to a new day?Se alla selezione si risponde con
no, a Personalizza esperienze verrà inviato il punteggio di ricompensa 0.
Comprendi il codice .NET utilizzando Personalizer
La soluzione .NET è un semplice chatbot di Bot Framework. Il codice relativo a Personalizza esperienze si trova nelle cartelle seguenti:
/samples/ChatbotExample/Bots- File
PersonalizerChatbot.csper l'interazione tra il bot e Personalizza esperienze
- File
-
/samples/ChatbotExample/ReinforcementLearning: gestisce le azioni e le caratteristiche per il modello di Personalizza esperienze -
/samples/ChatbotExample/Model: file per le azioni e le caratteristiche di Personalizza esperienze e per le finalità di LUIS
PersonalizerChatbot.cs - Utilizzo con Personalizer
La classe PersonalizerChatbot deriva dal Microsoft.Bot.Builder.ActivityHandler. Sono disponibili tre proprietà e metodi per gestire il flusso della conversazione.
Attenzione
Non copiare il codice da questa esercitazione. Usare il codice di esempio disponibile nel repository degli esempi di Personalizza esperienze.
public class PersonalizerChatbot : ActivityHandler
{
private readonly LuisRecognizer _luisRecognizer;
private readonly PersonalizerClient _personalizerClient;
private readonly RLContextManager _rlFeaturesManager;
public PersonalizerChatbot(LuisRecognizer luisRecognizer, RLContextManager rlContextManager, PersonalizerClient personalizerClient)
{
_luisRecognizer = luisRecognizer;
_rlFeaturesManager = rlContextManager;
_personalizerClient = personalizerClient;
}
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
await base.OnTurnAsync(turnContext, cancellationToken);
if (turnContext.Activity.Type == ActivityTypes.Message)
{
// Check LUIS model
var recognizerResult = await _luisRecognizer.RecognizeAsync(turnContext, cancellationToken);
var topIntent = recognizerResult?.GetTopScoringIntent();
if (topIntent != null && topIntent.HasValue && topIntent.Value.intent != "None")
{
Intents intent = (Intents)Enum.Parse(typeof(Intents), topIntent.Value.intent);
switch (intent)
{
case Intents.ShowMenu:
await turnContext.SendActivityAsync($"Here is our menu: \n Coffee: {CoffeesMethods.DisplayCoffees()}\n Tea: {TeaMethods.DisplayTeas()}", cancellationToken: cancellationToken);
break;
case Intents.ChooseRank:
// Here we generate the event ID for this Rank.
var response = await ChooseRankAsync(turnContext, _rlFeaturesManager.GenerateEventId(), cancellationToken);
_rlFeaturesManager.CurrentPreference = response.Ranking;
await turnContext.SendActivityAsync($"How about {response.RewardActionId}?", cancellationToken: cancellationToken);
break;
case Intents.RewardLike:
if (!string.IsNullOrEmpty(_rlFeaturesManager.CurrentEventId))
{
await RewardAsync(turnContext, _rlFeaturesManager.CurrentEventId, 1, cancellationToken);
await turnContext.SendActivityAsync($"That's great! I'll keep learning your preferences over time.", cancellationToken: cancellationToken);
await SendByebyeMessageAsync(turnContext, cancellationToken);
}
else
{
await turnContext.SendActivityAsync($"Not sure what you like. Did you ask for a suggestion?", cancellationToken: cancellationToken);
}
break;
case Intents.RewardDislike:
if (!string.IsNullOrEmpty(_rlFeaturesManager.CurrentEventId))
{
await RewardAsync(turnContext, _rlFeaturesManager.CurrentEventId, 0, cancellationToken);
await turnContext.SendActivityAsync($"Oh well, maybe I'll guess better next time.", cancellationToken: cancellationToken);
await SendByebyeMessageAsync(turnContext, cancellationToken);
}
else
{
await turnContext.SendActivityAsync($"Not sure what you dislike. Did you ask for a suggestion?", cancellationToken: cancellationToken);
}
break;
case Intents.Reset:
_rlFeaturesManager.GenerateRLFeatures();
await SendResetMessageAsync(turnContext, cancellationToken);
break;
default:
break;
}
}
else
{
var msg = @"Could not match your message with any of the following LUIS intents:
'ShowMenu'
'ChooseRank'
'RewardLike'
'RewardDislike'.
Try typing 'Show me the menu','What do you suggest','I like it','I don't like it'.";
await turnContext.SendActivityAsync(msg);
}
}
else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate)
{
// Generate a new weekday and weather condition
// These will act as the context features when we call rank with Personalizer
_rlFeaturesManager.GenerateRLFeatures();
// Send a welcome message to the user and tell them what actions they may perform to use this bot
await SendWelcomeMessageAsync(turnContext, cancellationToken);
}
else
{
await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected", cancellationToken: cancellationToken);
}
}
// code removed for brevity, full sample code available for download
private async Task SendWelcomeMessageAsync(ITurnContext turnContext, CancellationToken cancellationToken)
private async Task SendResetMessageAsync(ITurnContext turnContext, CancellationToken cancellationToken)
private async Task SendByebyeMessageAsync(ITurnContext turnContext, CancellationToken cancellationToken)
private async Task<RankResponse> ChooseRankAsync(ITurnContext turnContext, string eventId, CancellationToken cancellationToken)
private async Task RewardAsync(ITurnContext turnContext, string eventId, double reward, CancellationToken cancellationToken)
}
I metodi preceduti da Send gestiscono la conversazione con il bot e LUIS. I metodi ChooseRankAsync e RewardAsync interagiscono con Personalizer.
Chiamata dell'API di Ranking e visualizzazione dei risultati
Il metodo ChooseRankAsync costruisce i dati JSON da inviare all'API Personalizer Rank raccogliendo le azioni con le feature e le feature di contesto.
private async Task<RankResponse> ChooseRankAsync(ITurnContext turnContext, string eventId, CancellationToken cancellationToken)
{
IList<object> contextFeature = new List<object>
{
new { weather = _rlFeaturesManager.RLFeatures.Weather.ToString() },
new { dayofweek = _rlFeaturesManager.RLFeatures.DayOfWeek.ToString() },
};
Random rand = new Random(DateTime.UtcNow.Millisecond);
IList<RankableAction> actions = new List<RankableAction>();
var coffees = Enum.GetValues(typeof(Coffees));
var beansOrigin = Enum.GetValues(typeof(CoffeeBeansOrigin));
var organic = Enum.GetValues(typeof(Organic));
var roast = Enum.GetValues(typeof(CoffeeRoast));
var teas = Enum.GetValues(typeof(Teas));
foreach (var coffee in coffees)
{
actions.Add(new RankableAction
{
Id = coffee.ToString(),
Features =
new List<object>()
{
new { BeansOrigin = beansOrigin.GetValue(rand.Next(0, beansOrigin.Length)).ToString() },
new { Organic = organic.GetValue(rand.Next(0, organic.Length)).ToString() },
new { Roast = roast.GetValue(rand.Next(0, roast.Length)).ToString() },
},
});
}
foreach (var tea in teas)
{
actions.Add(new RankableAction
{
Id = tea.ToString(),
Features =
new List<object>()
{
new { Organic = organic.GetValue(rand.Next(0, organic.Length)).ToString() },
},
});
}
// Sending a rank request to Personalizer
// Here we are asking Personalizer to decide which drink the user is most likely to want
// based on the current context features (weather, day of the week generated in RLContextManager)
// and the features of the drinks themselves
var request = new RankRequest(actions, contextFeature, null, eventId);
await turnContext.SendActivityAsync(
"===== DEBUG MESSAGE CALL TO RANK =====\n" +
"This is what is getting sent to Rank:\n" +
$"{JsonConvert.SerializeObject(request, Formatting.Indented)}\n",
cancellationToken: cancellationToken);
var response = await _personalizerClient.RankAsync(request, cancellationToken);
await turnContext.SendActivityAsync(
$"===== DEBUG MESSAGE RETURN FROM RANK =====\n" +
"This is what Rank returned:\n" +
$"{JsonConvert.SerializeObject(response, Formatting.Indented)}\n",
cancellationToken: cancellationToken);
return response;
}
Chiamata dell'API Ricompensa e visualizzazione dei risultati
Il metodo RewardAsync costruisce i dati JSON da inviare all'API Personalizer Reward determinando il punteggio. Il punteggio è determinato dalla finalità di LUIS identificata nel testo dell'utente e inviata dal metodo OnTurnAsync.
private async Task RewardAsync(ITurnContext turnContext, string eventId, double reward, CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"===== DEBUG MESSAGE CALL REWARD =====\n" +
"Calling Reward:\n" +
$"eventId = {eventId}, reward = {reward}\n",
cancellationToken: cancellationToken);
// Sending a reward request to Personalizer
// Here we are responding to the drink ranking Personalizer provided us
// If the user liked the highest ranked drink, we give a high reward (1)
// If they did not, we give a low reward (0)
await _personalizerClient.RewardAsync(eventId, new RewardRequest(reward), cancellationToken);
}
Considerazioni di progettazione per un bot
Questo esempio è pensato per dimostrare una semplice soluzione end-to-end di Personalizer in un bot. Il caso d'uso corrente potrebbe essere più complesso.
Se hai intenzione di utilizzare Personalizer in un bot di produzione, pianifica quanto segue:
- Accesso in tempo reale a Personalizza esperienze ogni volta che è necessaria una selezione classificata. Non è possibile eseguire in batch o memorizzare nella cache l'API Classificazione. È possibile ritardare o eseguire l'offload della chiamata di ricompensa in un processo separato e se non viene restituita una ricompensa entro il periodo definito, viene impostato un valore di ricompensa predefinito per l'evento.
- Calcolo della ricompensa mediante calcolo basato sul caso d’uso: questo esempio ha mostrato due ricompense pari a zero e una senza intervallo e nessun valore negativo per un punteggio. Il sistema in uso potrebbe richiedere un sistema di assegnazione dei punteggi più granulare.
- Canali bot: questo esempio usa un solo canale, ma se intendi usare più di un canale o varianti del bot su un solo canale, potrebbe essere necessario considerare questo aspetto come parte delle caratteristiche del contesto del modello Personalizer.
Pulire le risorse
Al termine di questa esercitazione, pulire le risorse seguenti:
- Eliminare la directory del progetto di esempio.
- Elimina la risorsa Personalizer e LUIS nel portale di Azure.
Passaggi successivi
- Come funziona il Personalizer
- Caratteristiche: informazioni sui concetti relativi alle caratteristiche usate con azioni e contesto
- Ricompense: informazioni sul calcolo delle ricompense