Konverzační jazyk understanding (CLU), funkce jazyka Azure AI, je aktualizovaná verze služby LUIS.
Další informace o podpoře porozumění jazyku v sadě SDK služby Bot Framework najdete v tématu Principy přirozeného jazyka.
Schopnost pochopit, co uživatel znamená konverzační a kontextově, může být obtížná úloha, ale může robotovi poskytnout přirozenější pocit konverzace. Language Understanding (LUIS) je cloudová služba ROZHRANÍ API, která umožňuje provádět jenom to, aby robot mohl rozpoznat záměr uživatelských zpráv, umožnit uživatelům více přirozeného jazyka a lépe směrovat tok konverzace.
Toto téma vás provede přidáním služby LUIS do aplikace pro rezervaci letů za účelem rozpoznávání různých záměrů a entit obsažených ve vstupu uživatele.
Poznámka:
Sady SDK služby Bot Framework JavaScript, C# a Python budou nadále podporovány, ale sada Java SDK se vyřazuje s konečnou dlouhodobou podporou končící v listopadu 2023.
Stávající roboti sestavení pomocí sady Java SDK budou i nadále fungovat.
Tato ukázka základního robota ukazuje příklad aplikace pro rezervaci letů na letišti. Používá službu LUIS k rozpoznávání vstupu uživatele a vrácení záměru služby LUIS s nejvyšším rozpoznamem.
Jazykový model obsahuje tři záměry: Book Flight, Cancela None. Služba LUIS použije tyto záměry k pochopení toho, co uživatel myslel při odesílání zprávy robotovi. Jazykový model také definuje entity, které služba LUIS může extrahovat ze vstupu uživatele, například z počátečního nebo cílového letiště.
Po každém zpracování uživatelského vstupu DialogBot uloží aktuální stav obou UserState a ConversationState. Jakmile se shromáždí všechny požadované informace, ukázka kódování vytvoří ukázkovou rezervaci rezervace letů. V tomto článku se budeme věnujeme aspektům služby LUIS této ukázky. Obecný tok ukázky je však následující:
OnMembersAddedAsync je volána, když je nový uživatel připojen a zobrazí uvítací kartu.
OnMessageActivityAsync je volána pro každý přijatý uživatelský vstup.
Modul OnMessageActivityAsync spustí příslušné dialogové okno prostřednictvím metody rozšíření dialogového Run okna. Potom hlavní dialogové okno zavolá pomocníka služby LUIS, aby zjistil záměr uživatele s nejvyšším skóre. Pokud hlavní záměr pro vstup uživatele vrátí "BookFlight", pomocná rutina vyplní informace od uživatele, který služba LUIS vrátila. Potom se spustí BookingDialoghlavní dialog , který získá další informace podle potřeby od uživatele, například:
Origin původní město
TravelDate datum rezervace letu
Destination cílové město
Po každém zpracování uživatelského vstupu dialogBot uloží aktuální stav obou userState a conversationState. Jakmile se shromáždí všechny požadované informace, ukázka kódování vytvoří ukázkovou rezervaci rezervace letů. V tomto článku se budeme věnujeme aspektům služby LUIS této ukázky. Obecný tok ukázky je však následující:
onMembersAdded je volána, když je nový uživatel připojen a zobrazí uvítací kartu.
OnMessage je volána pro každý přijatý uživatelský vstup.
Modul onMessage spustí mainDialog, který shromažďuje uživatelský vstup.
Potom hlavní dialogové okno zavolá pomocníka FlightBookingRecognizer služby LUIS, aby zjistil záměr uživatele s nejvyšším skóre. Pokud hlavní záměr pro vstup uživatele vrátí "BookFlight", pomocná rutina vyplní informace od uživatele, který služba LUIS vrátila.
Po zpětné mainDialog odpovědi zachová informace pro uživatele vráceného službou LUIS a spustí bookingDialogse . bookingDialog získá další informace podle potřeby od uživatele, například
destination cílové město.
origin původní město.
travelDate datum rezervace letu.
Po každém zpracování uživatelského vstupu DialogBot uloží aktuální stav obou UserState a ConversationState.
Jakmile se shromáždí všechny požadované informace, ukázka kódování vytvoří ukázkovou rezervaci rezervace letů.
V tomto článku se budeme věnujeme aspektům služby LUIS této ukázky. Obecný tok ukázky je však následující:
onMembersAdded je volána, když je nový uživatel připojen a zobrazí uvítací kartu.
onMessageActivity je volána pro každý přijatý uživatelský vstup.
Modul onMessageActivity spustí příslušné dialogové okno prostřednictvím metody rozšíření dialogového run okna. Potom hlavní dialogové okno zavolá pomocníka služby LUIS, aby zjistil záměr uživatele s nejvyšším skóre. Pokud hlavní záměr pro vstup uživatele vrátí "BookFlight", pomocná rutina vyplní informace od uživatele, který služba LUIS vrátila. Potom se spustí BookingDialoghlavní dialog , který získá další informace podle potřeby od uživatele, například:
Origin původní město
TravelDate datum rezervace letu
Destination cílové město
Po každém zpracování uživatelského vstupu DialogBot uloží aktuální stav obou user_state a conversation_state. Jakmile se shromáždí všechny požadované informace, ukázka kódování vytvoří ukázkovou rezervaci rezervace letů. V tomto článku se budeme věnujeme aspektům služby LUIS této ukázky. Obecný tok ukázky je však následující:
on_members_added_activity je volána, když je nový uživatel připojen a zobrazí uvítací kartu.
on_message_activity je volána pro každý přijatý uživatelský vstup.
Modul on_message_activity spustí příslušné dialogové okno prostřednictvím metody rozšíření dialogového run_dialog okna. Pak hlavní dialogová volání LuisHelper vyhledá záměr uživatele s nejvyšším skóre. Pokud hlavní záměr pro vstup uživatele vrátí "BookFlight", pomocná funkce vyplní informace od uživatele, který služba LUIS vrátila. Potom se spustí BookingDialoghlavní dialog , který získá další informace podle potřeby od uživatele, například:
Na stránce Aplikace konverzace ve službě LUIS vyberte Importovat a pak importujte jako JSON.
V dialogovém okně Importovat novou aplikaci :
Zvolte soubor FlightBooking.json ve složce CognitiveModels ukázky.
Zadejte FlightBooking jako volitelný název aplikace a vyberte Hotovo.
Web může zobrazit , jak vytvořit efektivní aplikaci LUIS a upgradovat dialogové okno složených entit . Tato dialogová okna můžete zavřít a pokračovat.
Vytrénujte aplikaci a pak ji publikujte do produkčního prostředí.
Další informace najdete v dokumentaci služby LUIS o tom, jak vytrénovat a publikovat aplikaci.
Proč používat entity
Entity SLUŽBY LUIS umožňují robotovi porozumět událostem nad rámec standardních záměrů. Díky tomu můžete shromažďovat další informace od uživatelů, aby robot mohl klást otázky a reagovat inteligentněji. Spolu s definicemi tří záměrů LUIS "Rezervovat let", "Zrušit" a "None" obsahuje soubor FlightBooking.json také sadu entit, jako je From.Airport a To.Airport. Tyto entity umožňují službě LUIS zjišťovat a vracet další informace obsažené v původním vstupu uživatele, když požádá o novou cestovní rezervaci.
Získání hodnot pro připojení k aplikaci LUIS
Jakmile je vaše aplikace LUIS publikovaná, můžete k ní přistupovat z robota. Abyste mohli získat přístup k aplikaci LUIS z robota, budete muset zaznamenat několik hodnot. Tuto informaci můžete načíst pomocí portálu LUIS.
Načtení informací o aplikaci z portálu LUIS.ai
Soubor nastavení (appsettings.json.envneboconfig.py) funguje jako místo, kde jsou všechny odkazy na služby na jednom místě. Informace, které načtete, se do tohoto souboru přidají v další části.
Po otevření publikované aplikace LUIS vyberte kartu SPRAVOVAT .
Vyberte kartu Nastavení na levé straně a poznamenejte si hodnotu zobrazenou pro ID aplikace jako <YOUR_APP_ID>.
Vyberte prostředky Azure a pak prediktivní prostředek. Poznamenejte si hodnotu zobrazenou pro umístění jako YOUR_REGION a primární klíč jako <YOUR_AUTHORING_KEY>.> <
Alternativně můžete pro prostředek vytváření použít oblast a primární klíč.
Přidejte do souboru informace potřebné pro přístup k aplikaci LUIS, včetně ID aplikace, klíče pro vytváření obsahu a oblasti appsettings.json . V předchozím kroku jste tyto hodnoty načetli z publikované aplikace LUIS. Název hostitele rozhraní API by měl být ve formátu <your region>.api.cognitive.microsoft.com.
Přidejte do souboru informace potřebné pro přístup k aplikaci LUIS, včetně ID aplikace, klíče pro vytváření obsahu a oblasti .env . V předchozím kroku jste tyto hodnoty načetli z publikované aplikace LUIS. Název hostitele rozhraní API by měl být ve formátu <your region>.api.cognitive.microsoft.com.
Přidejte do souboru informace potřebné pro přístup k aplikaci LUIS, včetně ID aplikace, klíče pro vytváření obsahu a oblasti application.properties . V předchozím kroku jste tyto hodnoty načetli z publikované aplikace LUIS. Název hostitele rozhraní API by měl být ve formátu <your region>.api.cognitive.microsoft.com.
Přidejte do souboru informace potřebné pro přístup k aplikaci LUIS, včetně ID aplikace, klíče pro vytváření obsahu a oblasti config.py . V předchozím kroku jste tyto hodnoty načetli z publikované aplikace LUIS. Název hostitele rozhraní API by měl být ve formátu <your region>.api.cognitive.microsoft.com.
Ujistěte se, že je pro váš projekt nainstalovaný balíček NuGet Microsoft.Bot.Builder.AI.Luis .
Pokud se chcete připojit ke službě LUIS, robot načítá informace, které jste přidali do souboru appsetting.json. Třída FlightBookingRecognizer obsahuje kód s nastavením ze souboru appsetting.json a dotazuje službu LUIS voláním RecognizeAsync metody.
FlightBookingRecognizer.cs
public class FlightBookingRecognizer : IRecognizer
{
private readonly LuisRecognizer _recognizer;
public FlightBookingRecognizer(IConfiguration configuration)
{
var luisIsConfigured = !string.IsNullOrEmpty(configuration["LuisAppId"]) && !string.IsNullOrEmpty(configuration["LuisAPIKey"]) && !string.IsNullOrEmpty(configuration["LuisAPIHostName"]);
if (luisIsConfigured)
{
var luisApplication = new LuisApplication(
configuration["LuisAppId"],
configuration["LuisAPIKey"],
"https://" + configuration["LuisAPIHostName"]);
// Set the recognizer options depending on which endpoint version you want to use.
// More details can be found in https://docs.microsoft.com/en-gb/azure/cognitive-services/luis/luis-migration-api-v3
var recognizerOptions = new LuisRecognizerOptionsV3(luisApplication)
{
PredictionOptions = new Bot.Builder.AI.LuisV3.LuisPredictionOptions
{
IncludeInstanceData = true,
}
};
_recognizer = new LuisRecognizer(recognizerOptions);
}
}
// Returns true if luis is configured in the appsettings.json and initialized.
public virtual bool IsConfigured => _recognizer != null;
public virtual async Task<RecognizerResult> RecognizeAsync(ITurnContext turnContext, CancellationToken cancellationToken)
=> await _recognizer.RecognizeAsync(turnContext, cancellationToken);
public virtual async Task<T> RecognizeAsync<T>(ITurnContext turnContext, CancellationToken cancellationToken)
where T : IRecognizerConvert, new()
=> await _recognizer.RecognizeAsync<T>(turnContext, cancellationToken);
}
Obsahuje FlightBookingEx.cs logiku pro extrakci from, To a TravelDate; rozšiřuje částečnou třídu FlightBooking.cs použitou k ukládání výsledků služby LUIS při volání FlightBookingRecognizer.RecognizeAsync<FlightBooking> z objektu MainDialog.cs.
CognitiveModels\FlightBookingEx.cs
// Extends the partial FlightBooking class with methods and properties that simplify accessing entities in the luis results
public partial class FlightBooking
{
public (string From, string Airport) FromEntities
{
get
{
var fromValue = Entities?._instance?.From?.FirstOrDefault()?.Text;
var fromAirportValue = Entities?.From?.FirstOrDefault()?.Airport?.FirstOrDefault()?.FirstOrDefault();
return (fromValue, fromAirportValue);
}
}
public (string To, string Airport) ToEntities
{
get
{
var toValue = Entities?._instance?.To?.FirstOrDefault()?.Text;
var toAirportValue = Entities?.To?.FirstOrDefault()?.Airport?.FirstOrDefault()?.FirstOrDefault();
return (toValue, toAirportValue);
}
}
// This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part.
// TIMEX is a format that represents DateTime expressions that include some ambiguity. e.g. missing a Year.
public string TravelDate
=> Entities.datetime?.FirstOrDefault()?.Expressions.FirstOrDefault()?.Split('T')[0];
}
Pokud chcete službu LUIS používat, musí váš projekt nainstalovat balíček botbuilder-ai npm.
Robot se ke službě LUIS připojí pomocí informací, které jste do .env souboru přidali. Třída flightBookingRecognizer.js obsahuje kód, který importuje nastavení ze .env souboru a dotazuje službu LUIS voláním recognize() metody.
dialogy/flightBookingRecognizer.js
class FlightBookingRecognizer {
constructor(config) {
const luisIsConfigured = config && config.applicationId && config.endpointKey && config.endpoint;
if (luisIsConfigured) {
// Set the recognizer options depending on which endpoint version you want to use e.g v2 or v3.
// More details can be found in https://docs.microsoft.com/en-gb/azure/cognitive-services/luis/luis-migration-api-v3
const recognizerOptions = {
apiVersion: 'v3'
};
this.recognizer = new LuisRecognizer(config, recognizerOptions);
}
}
get isConfigured() {
return (this.recognizer !== undefined);
}
/**
* Returns an object with preformatted LUIS results for the bot's dialogs to consume.
* @param {TurnContext} context
*/
async executeLuisQuery(context) {
return await this.recognizer.recognize(context);
}
getFromEntities(result) {
let fromValue, fromAirportValue;
if (result.entities.$instance.From) {
fromValue = result.entities.$instance.From[0].text;
}
if (fromValue && result.entities.From[0].Airport) {
fromAirportValue = result.entities.From[0].Airport[0][0];
}
return { from: fromValue, airport: fromAirportValue };
}
getToEntities(result) {
let toValue, toAirportValue;
if (result.entities.$instance.To) {
toValue = result.entities.$instance.To[0].text;
}
if (toValue && result.entities.To[0].Airport) {
toAirportValue = result.entities.To[0].Airport[0][0];
}
return { to: toValue, airport: toAirportValue };
}
/**
* This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part.
* TIMEX is a format that represents DateTime expressions that include some ambiguity. e.g. missing a Year.
*/
getTravelDate(result) {
const datetimeEntity = result.entities.datetime;
if (!datetimeEntity || !datetimeEntity[0]) return undefined;
const timex = datetimeEntity[0].timex;
if (!timex || !timex[0]) return undefined;
const datetime = timex[0].split('T')[0];
return datetime;
}
}
Logika pro extrakci From, To a TravelDate je implementována jako pomocné metody uvnitř flightBookingRecognizer.js. Tyto metody se používají po volání flightBookingRecognizer.executeLuisQuery() z mainDialog.js
Ujistěte se, že je balíček com.microsoft.bot.bot-ai-luis-v3 přidaný do souboru pom.xml.
Pokud se chcete připojit ke službě LUIS, robot načítá informace, které jste přidali do souboru application.properties. Třída FlightBookingRecognizer obsahuje kód s nastavením ze souboru application.properties a dotazuje službu LUIS voláním recognize metody.
FlightBookingRecognizer.java
/**
* The constructor of the FlightBookingRecognizer class.
*
* @param configuration The Configuration object to use.
*/
public FlightBookingRecognizer(Configuration configuration) {
Boolean luisIsConfigured = StringUtils.isNotBlank(configuration.getProperty("LuisAppId"))
&& StringUtils.isNotBlank(configuration.getProperty("LuisAPIKey"))
&& StringUtils.isNotBlank(configuration.getProperty("LuisAPIHostName"));
if (luisIsConfigured) {
LuisApplication luisApplication = new LuisApplication(
configuration.getProperty("LuisAppId"),
configuration.getProperty("LuisAPIKey"),
String.format("https://%s", configuration.getProperty("LuisAPIHostName"))
);
// Set the recognizer options depending on which endpoint version you want to use.
// More details can be found in
// https://docs.microsoft.com/en-gb/azure/cognitive-services/luis/luis-migration-api-v3
LuisRecognizerOptionsV3 recognizerOptions = new LuisRecognizerOptionsV3(luisApplication);
recognizerOptions.setIncludeInstanceData(true);
this.recognizer = new LuisRecognizer(recognizerOptions);
}
}
/**
* Runs an utterance through a recognizer and returns a generic recognizer result.
*
* @param turnContext Turn context.
* @return Analysis of utterance.
*/
@Override
public CompletableFuture<RecognizerResult> recognize(TurnContext turnContext) {
return this.recognizer.recognize(turnContext);
}
Obsahuje FlightBookingRecognizer.cs logiku pro extrakci z, to a TravelDate; a je volána z MainDialog.java dekódování výsledků dotazu Luis.
FlightBookingRecognizer.java
/**
* Gets the From data from the entities which is part of the result.
*
* @param result The recognizer result.
* @return The object node representing the From data.
*/
public ObjectNode getFromEntities(RecognizerResult result) {
String fromValue = "", fromAirportValue = "";
if (result.getEntities().get("$instance").get("From") != null) {
fromValue = result.getEntities().get("$instance").get("From").get(0).get("text")
.asText();
}
if (!fromValue.isEmpty()
&& result.getEntities().get("From").get(0).get("Airport") != null) {
fromAirportValue = result.getEntities().get("From").get(0).get("Airport").get(0).get(0)
.asText();
}
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
ObjectNode entitiesNode = mapper.createObjectNode();
entitiesNode.put("from", fromValue);
entitiesNode.put("airport", fromAirportValue);
return entitiesNode;
}
/**
* Gets the To data from the entities which is part of the result.
*
* @param result The recognizer result.
* @return The object node representing the To data.
*/
public ObjectNode getToEntities(RecognizerResult result) {
String toValue = "", toAirportValue = "";
if (result.getEntities().get("$instance").get("To") != null) {
toValue = result.getEntities().get("$instance").get("To").get(0).get("text").asText();
}
if (!toValue.isEmpty() && result.getEntities().get("To").get(0).get("Airport") != null) {
toAirportValue = result.getEntities().get("To").get(0).get("Airport").get(0).get(0)
.asText();
}
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
ObjectNode entitiesNode = mapper.createObjectNode();
entitiesNode.put("to", toValue);
entitiesNode.put("airport", toAirportValue);
return entitiesNode;
}
/**
* This value will be a TIMEX. And we are only interested in a Date so grab the first result and
* drop the Time part. TIMEX is a format that represents DateTime expressions that include some
* ambiguity. e.g. missing a Year.
*
* @param result A {link RecognizerResult}
* @return The Timex value without the Time model
*/
public String getTravelDate(RecognizerResult result) {
JsonNode datetimeEntity = result.getEntities().get("datetime");
if (datetimeEntity == null || datetimeEntity.get(0) == null) {
return null;
}
JsonNode timex = datetimeEntity.get(0).get("timex");
if (timex == null || timex.get(0) == null) {
return null;
}
String datetime = timex.get(0).asText().split("T")[0];
return datetime;
}
Ujistěte se, že je pro váš projekt nainstalovaný balíček botbuilder-ai PyPI.
Robot se ke službě LUIS připojí pomocí informací, které jste do config.py souboru přidali. Třída FlightBookingRecognizer obsahuje kód, který importuje nastavení ze config.py souboru a dotazuje službu LUIS voláním recognize() metody.
flight_booking_recognizer.py
class FlightBookingRecognizer(Recognizer):
def __init__(self, configuration: DefaultConfig):
self._recognizer = None
luis_is_configured = (
configuration.LUIS_APP_ID
and configuration.LUIS_API_KEY
and configuration.LUIS_API_HOST_NAME
)
if luis_is_configured:
# Set the recognizer options depending on which endpoint version you want to use e.g v2 or v3.
# More details can be found in https://docs.microsoft.com/azure/cognitive-services/luis/luis-migration-api-v3
luis_application = LuisApplication(
configuration.LUIS_APP_ID,
configuration.LUIS_API_KEY,
"https://" + configuration.LUIS_API_HOST_NAME,
)
self._recognizer = LuisRecognizer(luis_application)
@property
def is_configured(self) -> bool:
# Returns true if luis is configured in the config.py and initialized.
return self._recognizer is not None
async def recognize(self, turn_context: TurnContext) -> RecognizerResult:
return await self._recognizer.recognize(turn_context)
Logika pro extrakci From, To a travel_date je implementována jako pomocné metody z LuisHelper třídy uvnitř luis_helper.py. Tyto metody se používají po volání LuisHelper.execute_luis_query() z main_dialog.py
pomocné rutiny/luis_helper.py
class LuisHelper:
@staticmethod
async def execute_luis_query(
luis_recognizer: LuisRecognizer, turn_context: TurnContext
) -> (Intent, object):
"""
Returns an object with preformatted LUIS results for the bot's dialogs to consume.
"""
result = None
intent = None
try:
recognizer_result = await luis_recognizer.recognize(turn_context)
intent = (
sorted(
recognizer_result.intents,
key=recognizer_result.intents.get,
reverse=True,
)[:1][0]
if recognizer_result.intents
else None
)
if intent == Intent.BOOK_FLIGHT.value:
result = BookingDetails()
# We need to get the result from the LUIS JSON which at every level returns an array.
to_entities = recognizer_result.entities.get("$instance", {}).get(
"To", []
)
if len(to_entities) > 0:
if recognizer_result.entities.get("To", [{"$instance": {}}])[0][
"$instance"
]:
result.destination = to_entities[0]["text"].capitalize()
else:
result.unsupported_airports.append(
to_entities[0]["text"].capitalize()
)
from_entities = recognizer_result.entities.get("$instance", {}).get(
"From", []
)
if len(from_entities) > 0:
if recognizer_result.entities.get("From", [{"$instance": {}}])[0][
"$instance"
]:
result.origin = from_entities[0]["text"].capitalize()
else:
result.unsupported_airports.append(
from_entities[0]["text"].capitalize()
)
# This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop
# the Time part. TIMEX is a format that represents DateTime expressions that include some ambiguity.
# e.g. missing a Year.
date_entities = recognizer_result.entities.get("datetime", [])
if date_entities:
timex = date_entities[0]["timex"]
if timex:
datetime = timex[0].split("T")[0]
result.travel_date = datetime
else:
result.travel_date = None
except Exception as exception:
print(exception)
return intent, result
Služba LUIS je teď nakonfigurovaná a připojená pro vašeho robota.
Spusťte ukázku místně na svém počítači. Pokud potřebujete pokyny, projděte si README soubor ukázky jazyka C#, ukázky JS nebo ukázky Pythonu.
V emulátoru zadejte zprávu, například "cesta do paříže" nebo "cesta z paříže do Berlína". K trénování záměru "Rezervovat let" použijte všechny promluvy nalezené v souboru FlightBooking.json.
Pokud se hlavní záměr vrácený ze služby LUIS vyřeší na "Rezervovat let", robot bude klást další otázky, dokud nebude mít dostatek informací uložených k vytvoření cestovní rezervace. V tomto okamžiku vrátí tyto informace o rezervaci zpět uživateli.
V tuto chvíli se logika robota kódu resetuje a můžete pokračovat v vytváření dalších rezervací.
Další informace
Další informace o službě LUIS najdete v dokumentaci ke službě LUIS: