Como reconhecer intenções com padrões correspondentes de entidades personalizadas

O SDK de Fala dos serviços de IA do Azure traz um recurso interno que fornece reconhecimento de intenção com padrões correspondentes de linguagem simples. Uma intenção é algo que o usuário deseja fazer: fechar uma janela, marcar uma caixa de seleção, inserir um texto etc.

Neste guia, você usará o SDK de Fala para desenvolver um aplicativo de console que obtém as intenções de enunciados de fala ditos por meio do microfone do dispositivo. Você aprenderá como:

  • Criar um projeto do Visual Studio que faz referência ao pacote NuGet do SDK de Fala
  • Criar uma configuração de fala e obter um reconhecedor de intenção
  • Adicionar intenções e padrões por meio da API do SDK de Fala
  • Adicionar entidades personalizadas por meio da API do SDK de Fala
  • Usar reconhecimento contínuo, assíncrono e orientado a eventos

Quando usar padrões correspondentes

Use padrões correspondentes se:

  • Você só tiver interesse em encontrar uma correspondência exata para o que o usuário disse. Esses padrões corresponderem mais agressivamente do que a compreensão da linguagem coloquial (CLU).
  • Você não tem acesso a um modelo de CLU, mas ainda desejar obter as intenções.

Para obter mais informações, confira a Visão geral de padrões correspondentes.

Pré-requisitos

Confira se você tem os itens a seguir antes de começar este tutorial:

Criar um projeto

Crie um projeto de aplicativo de console C# no Visual Studio 2019 e instale o SDK de Fala.

Comece com código de texto clichê

Vamos abrir Program.cs e adicionar um código que funciona como um esqueleto para o projeto.

using System;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Intent;

namespace helloworld
{
    class Program
    {
        static void Main(string[] args)
        {
            IntentPatternMatchingWithMicrophoneAsync().Wait();
        }

        private static async Task IntentPatternMatchingWithMicrophoneAsync()
        {
            var config = SpeechConfig.FromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_SUBSCRIPTION_REGION");
        }
    }
}

Criar uma configuração de Fala

Para inicializar um objeto IntentRecognizer, crie uma configuração que use a chave e a região do Azure do recurso de previsão dos serviços de IA do Azure.

  • Substitua "YOUR_SUBSCRIPTION_KEY" pela sua chave de previsão dos Serviços de IA do Azure.
  • Substitua "YOUR_SUBSCRIPTION_REGION" pela região do recurso dos Serviços de IA do Azure.

Esta amostra usa o método FromSubscription() para criar o SpeechConfig. Para ver uma lista completa dos métodos disponíveis, confira a Classe SpeechConfig.

Inicializar um IntentRecognizer

Agora, crie um IntentRecognizer. Insira esse código logo abaixo da configuração de fala.

using (var recognizer = new IntentRecognizer(config))
{
    
}

Adicionar algumas intenções

Você precisa associar alguns padrões a um PatternMatchingModel e aplicá-lo ao IntentRecognizer. Vamos começar criando um PatternMatchingModel e adicionando algumas tentativas a ele.

Observação

É possível adicionar vários padrões a um PatternMatchingIntent.

Insira este código no bloco using:

// Creates a Pattern Matching model and adds specific intents from your model. The
// Id is used to identify this model from others in the collection.
var model = new PatternMatchingModel("YourPatternMatchingModelId");

// Creates a pattern that uses groups of optional words. "[Go | Take me]" will match either "Go", "Take me", or "".
var patternWithOptionalWords = "[Go | Take me] to [floor|level] {floorName}";

// Creates a pattern that uses an optional entity and group that could be used to tie commands together.
var patternWithOptionalEntity = "Go to parking [{parkingLevel}]";

// You can also have multiple entities of the same name in a single pattern by adding appending a unique identifier
// to distinguish between the instances. For example:
var patternWithTwoOfTheSameEntity = "Go to floor {floorName:1} [and then go to floor {floorName:2}]";
// NOTE: Both floorName:1 and floorName:2 are tied to the same list of entries. The identifier can be a string
//       and is separated from the entity name by a ':'

// Creates the pattern matching intents and adds them to the model
model.Intents.Add(new PatternMatchingIntent("ChangeFloors", patternWithOptionalWords, patternWithOptionalEntity, patternWithTwoOfTheSameEntity));
model.Intents.Add(new PatternMatchingIntent("DoorControl", "{action} the doors", "{action} doors", "{action} the door", "{action} door"));

Adicionar algumas entidades personalizadas

Para aproveitar ao máximo a correspondência de padrões, você pode personalizar suas entidades. Vamos fazer com que "floorName" seja uma lista dos andares disponíveis. Também tornaremos "parkingLevel" uma entidade de inteiro.

Insira este código abaixo das intenções:

// Creates the "floorName" entity and set it to type list.
// Adds acceptable values. NOTE the default entity type is Any and so we do not need
// to declare the "action" entity.
model.Entities.Add(PatternMatchingEntity.CreateListEntity("floorName", EntityMatchMode.Strict, "ground floor", "lobby", "1st", "first", "one", "1", "2nd", "second", "two", "2"));

// Creates the "parkingLevel" entity as a pre-built integer
model.Entities.Add(PatternMatchingEntity.CreateIntegerEntity("parkingLevel"));

Aplicar nosso modelo ao reconhecedor

Agora é necessário aplicar o modelo ao IntentRecognizer. É possível usar vários modelos de uma vez para que a API utilize uma coleção de modelos.

Insira este código abaixo das entidades:

var modelCollection = new LanguageUnderstandingModelCollection();
modelCollection.Add(model);

recognizer.ApplyLanguageModels(modelCollection);

Reconhecer uma intenção

No objeto IntentRecognizer, chame o método RecognizeOnceAsync(). Esse método solicita ao serviço de Fala que reconheça a fala em uma só frase e pare de reconhecer a fala quando a frase é identificada.

Insira este código depois de aplicar os modelos de linguagem:

Console.WriteLine("Say something...");

var result = await recognizer.RecognizeOnceAsync();

Exibir os resultados do reconhecimento (ou os erros)

Quando o resultado do reconhecimento for retornado pelo serviço de Fala, imprimiremos o resultado.

Insira este código abaixo de var result = await recognizer.RecognizeOnceAsync();:

if (result.Reason == ResultReason.RecognizedIntent)
{
    Console.WriteLine($"RECOGNIZED: Text={result.Text}");
    Console.WriteLine($"       Intent Id={result.IntentId}.");

    var entities = result.Entities;
    switch (result.IntentId)
    {
        case "ChangeFloors":
            if (entities.TryGetValue("floorName", out string floorName))
            {
                Console.WriteLine($"       FloorName={floorName}");
            }

            if (entities.TryGetValue("floorName:1", out floorName))
            {
                Console.WriteLine($"     FloorName:1={floorName}");
            }

            if (entities.TryGetValue("floorName:2", out floorName))
            {
                Console.WriteLine($"     FloorName:2={floorName}");
            }

            if (entities.TryGetValue("parkingLevel", out string parkingLevel))
            {
                Console.WriteLine($"    ParkingLevel={parkingLevel}");
            }

            break;

        case "DoorControl":
            if (entities.TryGetValue("action", out string action))
            {
                Console.WriteLine($"          Action={action}");
            }
            break;
    }
}
else if (result.Reason == ResultReason.RecognizedSpeech)
{
    Console.WriteLine($"RECOGNIZED: Text={result.Text}");
    Console.WriteLine($"    Intent not recognized.");
}
else if (result.Reason == ResultReason.NoMatch)
{
    Console.WriteLine($"NOMATCH: Speech could not be recognized.");
}
else if (result.Reason == ResultReason.Canceled)
{
    var cancellation = CancellationDetails.FromResult(result);
    Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

    if (cancellation.Reason == CancellationReason.Error)
    {
        Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
        Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
        Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
    }
}

Verificar o código

Neste momento, seu código deverá ter a seguinte aparência:

using System;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Intent;

namespace helloworld
{
    class Program
    {
        static void Main(string[] args)
        {
            IntentPatternMatchingWithMicrophoneAsync().Wait();
        }

        private static async Task IntentPatternMatchingWithMicrophoneAsync()
        {
            var config = SpeechConfig.FromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_SUBSCRIPTION_REGION");

            using (var recognizer = new IntentRecognizer(config))
            {
                // Creates a Pattern Matching model and adds specific intents from your model. The
                // Id is used to identify this model from others in the collection.
                var model = new PatternMatchingModel("YourPatternMatchingModelId");

                // Creates a pattern that uses groups of optional words. "[Go | Take me]" will match either "Go", "Take me", or "".
                var patternWithOptionalWords = "[Go | Take me] to [floor|level] {floorName}";

                // Creates a pattern that uses an optional entity and group that could be used to tie commands together.
                var patternWithOptionalEntity = "Go to parking [{parkingLevel}]";

                // You can also have multiple entities of the same name in a single pattern by adding appending a unique identifier
                // to distinguish between the instances. For example:
                var patternWithTwoOfTheSameEntity = "Go to floor {floorName:1} [and then go to floor {floorName:2}]";
                // NOTE: Both floorName:1 and floorName:2 are tied to the same list of entries. The identifier can be a string
                //       and is separated from the entity name by a ':'

                // Adds some intents to look for specific patterns.
                model.Intents.Add(new PatternMatchingIntent("ChangeFloors", patternWithOptionalWords, patternWithOptionalEntity, patternWithTwoOfTheSameEntity));
                model.Intents.Add(new PatternMatchingIntent("DoorControl", "{action} the doors", "{action} doors", "{action} the door", "{action} door"));

                // Creates the "floorName" entity and set it to type list.
                // Adds acceptable values. NOTE the default entity type is Any and so we do not need
                // to declare the "action" entity.
                model.Entities.Add(PatternMatchingEntity.CreateListEntity("floorName", EntityMatchMode.Strict, "ground floor", "lobby", "1st", "first", "one", "1", "2nd", "second", "two", "2"));

                // Creates the "parkingLevel" entity as a pre-built integer
                model.Entities.Add(PatternMatchingEntity.CreateIntegerEntity("parkingLevel"));

                var modelCollection = new LanguageUnderstandingModelCollection();
                modelCollection.Add(model);

                recognizer.ApplyLanguageModels(modelCollection);

                Console.WriteLine("Say something...");

                var result = await recognizer.RecognizeOnceAsync();

                if (result.Reason == ResultReason.RecognizedIntent)
                {
                    Console.WriteLine($"RECOGNIZED: Text={result.Text}");
                    Console.WriteLine($"       Intent Id={result.IntentId}.");

                    var entities = result.Entities;
                    switch (result.IntentId)
                    {
                        case "ChangeFloors":
                            if (entities.TryGetValue("floorName", out string floorName))
                            {
                                Console.WriteLine($"       FloorName={floorName}");
                            }

                            if (entities.TryGetValue("floorName:1", out floorName))
                            {
                                Console.WriteLine($"     FloorName:1={floorName}");
                            }

                            if (entities.TryGetValue("floorName:2", out floorName))
                            {
                                Console.WriteLine($"     FloorName:2={floorName}");
                            }

                            if (entities.TryGetValue("parkingLevel", out string parkingLevel))
                            {
                                Console.WriteLine($"    ParkingLevel={parkingLevel}");
                            }

                            break;

                        case "DoorControl":
                            if (entities.TryGetValue("action", out string action))
                            {
                                Console.WriteLine($"          Action={action}");
                            }
                            break;
                    }
                }
                else if (result.Reason == ResultReason.RecognizedSpeech)
                {
                    Console.WriteLine($"RECOGNIZED: Text={result.Text}");
                    Console.WriteLine($"    Intent not recognized.");
                }
                else if (result.Reason == ResultReason.NoMatch)
                {
                    Console.WriteLine($"NOMATCH: Speech could not be recognized.");
                }
                else if (result.Reason == ResultReason.Canceled)
                {
                    var cancellation = CancellationDetails.FromResult(result);
                    Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

                    if (cancellation.Reason == CancellationReason.Error)
                    {
                        Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                        Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
                        Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
                    }
                }
            }
        }
    }
}

Compilar e executar o aplicativo

Agora está tudo pronto para você compilar o aplicativo e testar o reconhecimento de fala usando o serviço de fala.

  1. Compilar o código: na barra de menus do Visual Studio, escolha Compilar>Compilar Solução.
  2. Iniciar o aplicativo: na barra de menus, escolha Depurar>Iniciar Depuração ou pressione F5.
  3. Iniciar reconhecimento: você precisará dizer algo. O idioma padrão é inglês. Sua fala é enviada ao Serviço de Fala, transcrita como texto e renderizada no console.

Por exemplo, se você disser "Leve-me ao 2º andar", esta será a saída:

Say something...
RECOGNIZED: Text=Take me to floor 2.
       Intent Id=ChangeFloors.
       FloorName=2

Outro exemplo, se você disser "Leve-me ao 7º andar", esta será a saída:

Say something...
RECOGNIZED: Text=Take me to floor 7.
    Intent not recognized.

Nenhuma intenção foi reconhecida porque 7 não estava em nossa lista de valores válidos para floorNamer.

Criar um projeto

Crie um projeto de aplicativo de console C++ no Visual Studio 2019 e instale o SDK de Fala.

Comece com código de texto clichê

Vamos abrir helloworld.cpp e adicionar um código que funciona como um esqueleto para o projeto.

#include <iostream>
#include <speechapi_cxx.h>

using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Intent;

int main()
{
    std::cout << "Hello World!\n";

    auto config = SpeechConfig::FromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_SUBSCRIPTION_REGION");
}

Criar uma configuração de Fala

Para inicializar um objeto IntentRecognizer, crie uma configuração que use a chave e a região do Azure do recurso de previsão dos serviços de IA do Azure.

  • Substitua "YOUR_SUBSCRIPTION_KEY" pela sua chave de previsão dos Serviços de IA do Azure.
  • Substitua "YOUR_SUBSCRIPTION_REGION" pela região do recurso dos Serviços de IA do Azure.

Esta amostra usa o método FromSubscription() para criar o SpeechConfig. Para ver uma lista completa dos métodos disponíveis, confira a Classe SpeechConfig.

Inicializar um IntentRecognizer

Agora, crie um IntentRecognizer. Insira esse código logo abaixo da configuração de fala.

    auto intentRecognizer = IntentRecognizer::FromConfig(config);

Adicionar algumas intenções

Você precisa associar alguns padrões a um PatternMatchingModel e aplicá-lo ao IntentRecognizer. Vamos começar criando um PatternMatchingModel e adicionando algumas tentativas a ele. Um PatternMatchingIntent é um struct, portanto, vamos usar apenas a sintaxe em linha.

Observação

É possível adicionar vários padrões a um PatternMatchingIntent.

auto model = PatternMatchingModel::FromId("myNewModel");

model->Intents.push_back({"Take me to floor {floorName}.", "Go to floor {floorName}."} , "ChangeFloors");
model->Intents.push_back({"{action} the door."}, "OpenCloseDoor");

Adicionar algumas entidades personalizadas

Para aproveitar ao máximo a correspondência de padrões, você pode personalizar suas entidades. Vamos fazer com que "floorName" seja uma lista dos andares disponíveis.

model->Entities.push_back({ "floorName" , Intent::EntityType::List, Intent::EntityMatchMode::Strict, {"one", "1", "two", "2", "lobby", "ground floor"} });

Aplicar nosso modelo ao reconhecedor

Agora é necessário aplicar o modelo ao IntentRecognizer. É possível usar vários modelos de uma vez para que a API utilize uma coleção de modelos.

std::vector<std::shared_ptr<LanguageUnderstandingModel>> collection;

collection.push_back(model);
intentRecognizer->ApplyLanguageModels(collection);

Reconhecer uma intenção

No objeto IntentRecognizer, chame o método RecognizeOnceAsync(). Esse método solicita ao serviço de Fala que reconheça a fala em uma só frase e pare de reconhecer a fala quando a frase é identificada. Para simplificar, aguardaremos os resultados futuros retornarem para concluir.

Insira este código abaixo das intenções:

std::cout << "Say something ..." << std::endl;
auto result = intentRecognizer->RecognizeOnceAsync().get();

Exibir os resultados do reconhecimento (ou os erros)

Quando o resultado do reconhecimento for retornado pelo serviço de Fala, imprimiremos o resultado.

Insira este código abaixo de auto result = intentRecognizer->RecognizeOnceAsync().get();:

switch (result->Reason)
{
case ResultReason::RecognizedSpeech:
        std::cout << "RECOGNIZED: Text = " << result->Text.c_str() << std::endl;
        std::cout << "NO INTENT RECOGNIZED!" << std::endl;
        break;
case ResultReason::RecognizedIntent:
    std::cout << "RECOGNIZED: Text = " << result->Text.c_str() << std::endl;
    std::cout << "  Intent Id = " << result->IntentId.c_str() << std::endl;
    auto entities = result->GetEntities();
    if (entities.find("floorName") != entities.end())
    {
        std::cout << "  Floor name: = " << entities["floorName"].c_str() << std::endl;
    }

    if (entities.find("action") != entities.end())
    {
        std::cout << "  Action: = " << entities["action"].c_str() << std::endl;
    }

    break;
case ResultReason::NoMatch:
{
    auto noMatch = NoMatchDetails::FromResult(result);
    switch (noMatch->Reason)
    {
    case NoMatchReason::NotRecognized:
        std::cout << "NOMATCH: Speech was detected, but not recognized." << std::endl;
        break;
    case NoMatchReason::InitialSilenceTimeout:
        std::cout << "NOMATCH: The start of the audio stream contains only silence, and the service timed out waiting for speech." << std::endl;
        break;
    case NoMatchReason::InitialBabbleTimeout:
        std::cout << "NOMATCH: The start of the audio stream contains only noise, and the service timed out waiting for speech." << std::endl;
        break;
    case NoMatchReason::KeywordNotRecognized:
        std::cout << "NOMATCH: Keyword not recognized" << std::endl;
        break;
    }
    break;
}
case ResultReason::Canceled:
{
    auto cancellation = CancellationDetails::FromResult(result);

    if (!cancellation->ErrorDetails.empty())
    {
        std::cout << "CANCELED: ErrorDetails=" << cancellation->ErrorDetails.c_str() << std::endl;
        std::cout << "CANCELED: Did you set the speech resource key and region values?" << std::endl;
    }
}
default:
    break;
}

Verificar o código

Neste momento, seu código deverá ter a seguinte aparência:

#include <iostream>
#include <speechapi_cxx.h>

using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Intent;

int main()
{
    auto config = SpeechConfig::FromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_SUBSCRIPTION_REGION");
    auto intentRecognizer = IntentRecognizer::FromConfig(config);

    auto model = PatternMatchingModel::FromId("myNewModel");

    model->Intents.push_back({"Take me to floor {floorName}.", "Go to floor {floorName}."} , "ChangeFloors");
    model->Intents.push_back({"{action} the door."}, "OpenCloseDoor");

    model->Entities.push_back({ "floorName" , Intent::EntityType::List, Intent::EntityMatchMode::Strict, {"one", "1", "two", "2", "lobby", "ground floor"} });

    std::vector<std::shared_ptr<LanguageUnderstandingModel>> collection;

    collection.push_back(model);
    intentRecognizer->ApplyLanguageModels(collection);

    std::cout << "Say something ..." << std::endl;

    auto result = intentRecognizer->RecognizeOnceAsync().get();

    switch (result->Reason)
    {
    case ResultReason::RecognizedSpeech:
        std::cout << "RECOGNIZED: Text = " << result->Text.c_str() << std::endl;
        std::cout << "NO INTENT RECOGNIZED!" << std::endl;
        break;
    case ResultReason::RecognizedIntent:
        std::cout << "RECOGNIZED: Text = " << result->Text.c_str() << std::endl;
        std::cout << "  Intent Id = " << result->IntentId.c_str() << std::endl;
        auto entities = result->GetEntities();
        if (entities.find("floorName") != entities.end())
        {
            std::cout << "  Floor name: = " << entities["floorName"].c_str() << std::endl;
        }

        if (entities.find("action") != entities.end())
        {
            std::cout << "  Action: = " << entities["action"].c_str() << std::endl;
        }

        break;
    case ResultReason::NoMatch:
    {
        auto noMatch = NoMatchDetails::FromResult(result);
        switch (noMatch->Reason)
        {
        case NoMatchReason::NotRecognized:
            std::cout << "NOMATCH: Speech was detected, but not recognized." << std::endl;
            break;
        case NoMatchReason::InitialSilenceTimeout:
            std::cout << "NOMATCH: The start of the audio stream contains only silence, and the service timed out waiting for speech." << std::endl;
            break;
        case NoMatchReason::InitialBabbleTimeout:
            std::cout << "NOMATCH: The start of the audio stream contains only noise, and the service timed out waiting for speech." << std::endl;
            break;
        case NoMatchReason::KeywordNotRecognized:
            std::cout << "NOMATCH: Keyword not recognized." << std::endl;
            break;
        }
        break;
    }
    case ResultReason::Canceled:
    {
        auto cancellation = CancellationDetails::FromResult(result);

        if (!cancellation->ErrorDetails.empty())
        {
            std::cout << "CANCELED: ErrorDetails=" << cancellation->ErrorDetails.c_str() << std::endl;
            std::cout << "CANCELED: Did you set the speech resource key and region values?" << std::endl;
        }
    }
    default:
        break;
    }
}

Compilar e executar o aplicativo

Agora está tudo pronto para você compilar o aplicativo e testar o reconhecimento de fala usando o serviço de fala.

  1. Compilar o código: na barra de menus do Visual Studio, escolha Compilar>Compilar Solução.
  2. Iniciar o aplicativo: na barra de menus, escolha Depurar>Iniciar Depuração ou pressione F5.
  3. Iniciar reconhecimento: você precisará dizer algo. O idioma padrão é inglês. Sua fala é enviada ao Serviço de Fala, transcrita como texto e renderizada no console.

Por exemplo, se você disser "Leve-me ao 2º andar", esta será a saída:

Say something ...
RECOGNIZED: Text = Take me to floor 2.
  Intent Id = ChangeFloors
  Floor name: = 2

Outro exemplo, se você disser "Leve-me ao 7º andar", esta será a saída:

Say something ...
RECOGNIZED: Text = Take me to floor 7.
NO INTENT RECOGNIZED!

A ID da intenção está vazia porque sete não estava em nossa lista.

Documentação de referência | Amostras adicionais no GitHub

Neste início rápido, você instalará o SDK de Fala para Java.

Requisitos de plataforma

Escolha o ambiente de destino:

O SDK de Fala para Java é compatível com Windows, Linux e macOS.

No Windows, você precisa usar a arquitetura de destino de 64 bits. Windows 10 ou posterior é necessário.

Instale os Pacotes Redistribuíveis do Visual C++ para Visual Studio 2015, 2017, 2019 e 2022 na sua plataforma. Quando você instalar esse pacote pela primeira vez, poderá ser necessária uma reinicialização.

O SDK de Fala para Java não dá suporte ao Windows no ARM64.

Instalar um Kit de Desenvolvimento do Java, como o Azul Zulu OpenJDK. O Build da Microsoft do OpenJDK ou seu JDK preferencial também devem funcionar.

Instalar o SDK de Fala para Java

Algumas das instruções usam uma versão específica do SDK, como 1.24.2. Para verificar a versão mais recente, pesquise nosso repositório do GitHub.

Escolha o ambiente de destino:

Este guia mostra como instalar o SDK de Fala para Java no Java Runtime.

Sistemas operacionais compatíveis

O pacote do SDK de Fala para Java está disponível para estes sistemas operacionais:

Siga estas etapas para instalar o SDK de Fala para Java usando o Apache Maven:

  1. Instale o Apache Maven.

  2. Abra um prompt de comando onde você deseja o novo projeto e crie um novo arquivo chamado pom.xml.

  3. Copie o conteúdo XML a seguir em pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.microsoft.cognitiveservices.speech.samples</groupId>
        <artifactId>quickstart-eclipse</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <build>
            <sourceDirectory>src</sourceDirectory>
            <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                <source>1.8</source>
                <target>1.8</target>
                </configuration>
            </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
            <groupId>com.microsoft.cognitiveservices.speech</groupId>
            <artifactId>client-sdk</artifactId>
            <version>1.37.0</version>
            </dependency>
        </dependencies>
    </project>
    
  4. Execute o comando Maven a seguir para instalar o SDK de Fala e as dependências.

    mvn clean dependency:copy-dependencies
    

Comece com código de texto clichê

  1. Abra Main.java no src dir.

  2. Substitua o conteúdo do arquivo pelo seguinte:

import java.util.ArrayList;
import java.util.Dictionary;
import java.util.concurrent.ExecutionException;


import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.intent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        IntentPatternMatchingWithMicrophone();
    }

    public static void IntentPatternMatchingWithMicrophone() throws InterruptedException, ExecutionException {
        SpeechConfig config = SpeechConfig.fromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_SUBSCRIPTION_REGION");
    }
}

Criar uma configuração de Fala

Para inicializar um objeto IntentRecognizer, crie uma configuração que use a chave e a região do Azure do recurso de previsão dos serviços de IA do Azure.

  • Substitua "YOUR_SUBSCRIPTION_KEY" pela sua chave de previsão dos Serviços de IA do Azure.
  • Substitua "YOUR_SUBSCRIPTION_REGION" pela região do recurso dos Serviços de IA do Azure.

Esta amostra usa o método fromSubscription() para criar o SpeechConfig. Para ver uma lista completa dos métodos disponíveis, confira a Classe SpeechConfig.

Inicializar um IntentRecognizer

Agora, crie um IntentRecognizer. Insira esse código logo abaixo da configuração de fala. Fazemos isso como uma tentativa de aproveitarmos a interface de fechamento automático.

try (IntentRecognizer recognizer = new IntentRecognizer(config)) {

}

Adicionar algumas intenções

Você precisa associar alguns padrões a um PatternMatchingModel e aplicá-lo ao IntentRecognizer. Vamos começar criando um PatternMatchingModel e adicionando algumas tentativas a ele.

Observação

É possível adicionar vários padrões a um PatternMatchingIntent.

Insira este código no bloco try:

// Creates a Pattern Matching model and adds specific intents from your model. The
// Id is used to identify this model from others in the collection.
PatternMatchingModel model = new PatternMatchingModel("YourPatternMatchingModelId");

// Creates a pattern that uses groups of optional words. "[Go | Take me]" will match either "Go", "Take me", or "".
String patternWithOptionalWords = "[Go | Take me] to [floor|level] {floorName}";

// Creates a pattern that uses an optional entity and group that could be used to tie commands together.
String patternWithOptionalEntity = "Go to parking [{parkingLevel}]";

// You can also have multiple entities of the same name in a single pattern by adding appending a unique identifier
// to distinguish between the instances. For example:
String patternWithTwoOfTheSameEntity = "Go to floor {floorName:1} [and then go to floor {floorName:2}]";
// NOTE: Both floorName:1 and floorName:2 are tied to the same list of entries. The identifier can be a string
//       and is separated from the entity name by a ':'

// Creates the pattern matching intents and adds them to the model
model.getIntents().put(new PatternMatchingIntent("ChangeFloors", patternWithOptionalWords, patternWithOptionalEntity, patternWithTwoOfTheSameEntity));
model.getIntents().put(new PatternMatchingIntent("DoorControl", "{action} the doors", "{action} doors", "{action} the door", "{action} door"));

Adicionar algumas entidades personalizadas

Para aproveitar ao máximo a correspondência de padrões, você pode personalizar suas entidades. Vamos fazer com que "floorName" seja uma lista dos andares disponíveis. Também tornaremos "parkingLevel" uma entidade de inteiro.

Insira este código abaixo das intenções:

// Creates the "floorName" entity and set it to type list.
// Adds acceptable values. NOTE the default entity type is Any and so we do not need
// to declare the "action" entity.
model.getEntities().put(PatternMatchingEntity.CreateListEntity("floorName", PatternMatchingEntity.EntityMatchMode.Strict, "ground floor", "lobby", "1st", "first", "one", "1", "2nd", "second", "two", "2"));

// Creates the "parkingLevel" entity as a pre-built integer
model.getEntities().put(PatternMatchingEntity.CreateIntegerEntity("parkingLevel"));

Aplicar nosso modelo ao reconhecedor

Agora é necessário aplicar o modelo ao IntentRecognizer. É possível usar vários modelos de uma vez para que a API utilize uma coleção de modelos.

Insira este código abaixo das entidades:

ArrayList<LanguageUnderstandingModel> modelCollection = new ArrayList<LanguageUnderstandingModel>();
modelCollection.add(model);

recognizer.applyLanguageModels(modelCollection);

Reconhecer uma intenção

No objeto IntentRecognizer, chame o método RecognizeOnceAsync(). Esse método solicita ao serviço de Fala que reconheça a fala em uma só frase e pare de reconhecer a fala quando a frase é identificada.

Insira este código depois de aplicar os modelos de linguagem:

System.out.println("Say something...");

IntentRecognitionResult result = recognizer.recognizeOnceAsync().get();

Exibir os resultados do reconhecimento (ou os erros)

Quando o resultado do reconhecimento for retornado pelo serviço de Fala, imprimiremos o resultado.

Insira este código abaixo de IntentRecognitionResult result = recognizer.recognizeOnceAsync.get();:

if (result.getReason() == ResultReason.RecognizedSpeech) {
    System.out.println("RECOGNIZED: Text= " + result.getText());
    System.out.println(String.format("%17s", "Intent not recognized."));
}
else if (result.getReason() == ResultReason.RecognizedIntent)
{
    System.out.println("RECOGNIZED: Text= " + result.getText());
    System.out.println(String.format("%17s %s", "Intent Id=", result.getIntentId() + "."));
    Dictionary<String, String> entities = result.getEntities();

    switch (result.getIntentId())
    {
        case "ChangeFloors":
            if (entities.get("floorName") != null) {
                System.out.println(String.format("%17s %s", "FloorName=", entities.get("floorName")));
            }
            if (entities.get("floorName:1") != null) {
                System.out.println(String.format("%17s %s", "FloorName:1=", entities.get("floorName:1")));
            }
            if (entities.get("floorName:2") != null) {
                System.out.println(String.format("%17s %s", "FloorName:2=", entities.get("floorName:2")));
            }
            if (entities.get("parkingLevel") != null) {
                System.out.println(String.format("%17s %s", "ParkingLevel=", entities.get("parkingLevel")));
            }
            break;
        case "DoorControl":
            if (entities.get("action") != null) {
                System.out.println(String.format("%17s %s", "Action=", entities.get("action")));
            }
            break;
    }
}
else if (result.getReason() == ResultReason.NoMatch) {
    System.out.println("NOMATCH: Speech could not be recognized.");
}
else if (result.getReason() == ResultReason.Canceled) {
    CancellationDetails cancellation = CancellationDetails.fromResult(result);
    System.out.println("CANCELED: Reason=" + cancellation.getReason());

    if (cancellation.getReason() == CancellationReason.Error)
    {
        System.out.println("CANCELED: ErrorCode=" + cancellation.getErrorCode());
        System.out.println("CANCELED: ErrorDetails=" + cancellation.getErrorDetails());
        System.out.println("CANCELED: Did you update the subscription info?");
    }
}

Verificar o código

Neste momento, seu código deverá ter a seguinte aparência:

package quickstart;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.Dictionary;

import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.intent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        IntentPatternMatchingWithMicrophone();
    }

    public static void IntentPatternMatchingWithMicrophone() throws InterruptedException, ExecutionException {
        SpeechConfig config = SpeechConfig.fromSubscription("YOUR_SUBSCRIPTION_KEY", "YOUR_SUBSCRIPTION_REGION");
        try (IntentRecognizer recognizer = new IntentRecognizer(config)) {
            // Creates a Pattern Matching model and adds specific intents from your model. The
            // Id is used to identify this model from others in the collection.
            PatternMatchingModel model = new PatternMatchingModel("YourPatternMatchingModelId");

            // Creates a pattern that uses groups of optional words. "[Go | Take me]" will match either "Go", "Take me", or "".
            String patternWithOptionalWords = "[Go | Take me] to [floor|level] {floorName}";

            // Creates a pattern that uses an optional entity and group that could be used to tie commands together.
            String patternWithOptionalEntity = "Go to parking [{parkingLevel}]";

            // You can also have multiple entities of the same name in a single pattern by adding appending a unique identifier
            // to distinguish between the instances. For example:
            String patternWithTwoOfTheSameEntity = "Go to floor {floorName:1} [and then go to floor {floorName:2}]";
            // NOTE: Both floorName:1 and floorName:2 are tied to the same list of entries. The identifier can be a string
            // and is separated from the entity name by a ':'

            // Creates the pattern matching intents and adds them to the model
            model.getIntents().put(new PatternMatchingIntent("ChangeFloors", patternWithOptionalWords, patternWithOptionalEntity, patternWithTwoOfTheSameEntity));
            model.getIntents().put(new PatternMatchingIntent("DoorControl", "{action} the doors", "{action} doors", "{action} the door", "{action} door"));

            // Creates the "floorName" entity and set it to type list.
            // Adds acceptable values. NOTE the default entity type is Any and so we do not need
            // to declare the "action" entity.
            model.getEntities().put(PatternMatchingEntity.CreateListEntity("floorName", PatternMatchingEntity.EntityMatchMode.Strict, "ground floor", "lobby", "1st", "first", "one", "1", "2nd", "second", "two", "2"));

            // Creates the "parkingLevel" entity as a pre-built integer
            model.getEntities().put(PatternMatchingEntity.CreateIntegerEntity("parkingLevel"));

            ArrayList<LanguageUnderstandingModel> modelCollection = new ArrayList<LanguageUnderstandingModel>();
            modelCollection.add(model);

            recognizer.applyLanguageModels(modelCollection);

            System.out.println("Say something...");

            IntentRecognitionResult result = recognizer.recognizeOnceAsync().get();

            if (result.getReason() == ResultReason.RecognizedSpeech) {
                System.out.println("RECOGNIZED: Text= " + result.getText());
                System.out.println(String.format("%17s", "Intent not recognized."));
            }
            else if (result.getReason() == ResultReason.RecognizedIntent)
            {
                System.out.println("RECOGNIZED: Text= " + result.getText());
                System.out.println(String.format("%17s %s", "Intent Id=", result.getIntentId() + "."));
                Dictionary<String, String> entities = result.getEntities();

                switch (result.getIntentId())
                {
                    case "ChangeFloors":
                        if (entities.get("floorName") != null) {
                            System.out.println(String.format("%17s %s", "FloorName=", entities.get("floorName")));
                        }
                        if (entities.get("floorName:1") != null) {
                            System.out.println(String.format("%17s %s", "FloorName:1=", entities.get("floorName:1")));
                        }
                        if (entities.get("floorName:2") != null) {
                            System.out.println(String.format("%17s %s", "FloorName:2=", entities.get("floorName:2")));
                        }
                        if (entities.get("parkingLevel") != null) {
                            System.out.println(String.format("%17s %s", "ParkingLevel=", entities.get("parkingLevel")));
                        }
                        break;

                    case "DoorControl":
                        if (entities.get("action") != null) {
                            System.out.println(String.format("%17s %s", "Action=", entities.get("action")));
                        }
                        break;
                }
            }
            else if (result.getReason() == ResultReason.NoMatch) {
                System.out.println("NOMATCH: Speech could not be recognized.");
            }
            else if (result.getReason() == ResultReason.Canceled) {
                CancellationDetails cancellation = CancellationDetails.fromResult(result);
                System.out.println("CANCELED: Reason=" + cancellation.getReason());

                if (cancellation.getReason() == CancellationReason.Error)
                {
                    System.out.println("CANCELED: ErrorCode=" + cancellation.getErrorCode());
                    System.out.println("CANCELED: ErrorDetails=" + cancellation.getErrorDetails());
                    System.out.println("CANCELED: Did you update the subscription info?");
                }
            }
        }
    }
}

Compilar e executar o aplicativo

Agora você está pronto para criar seu aplicativo e testar nosso reconhecimento de intenção usando o serviço de fala e o verificador de padrões incorporado.

Clique no botão Executar no Eclipse ou pressione ctrl+F11, depois observe a saída para o prompt "Diga alguma coisa...". Quando aparecer, diga seu enunciado e observe a saída.

Por exemplo, se você disser "Leve-me ao 2º andar", esta será a saída:

Say something...
RECOGNIZED: Text=Take me to floor 2.
       Intent Id=ChangeFloors.
       FloorName=2

Outro exemplo, se você disser "Leve-me ao 7º andar", esta será a saída:

Say something...
RECOGNIZED: Text=Take me to floor 7.
    Intent not recognized.

Nenhuma intenção foi reconhecida porque 7 não estava em nossa lista de valores válidos para floorNamer.