Creëer een conversationele interface voor Android met Dialogflow

Wat je gaat creëren

De opkomst van kunstmatige intelligentie veroorzaakt een paradigmaverschuiving op het gebied van de ontwikkeling van gebruikersinterfaces. Dankzij de toename van intelligente stemgestuurde assistenten zoals Google Home, Siri en Alexa, beginnen gebruikers te voelen dat het indrukken van meerdere knoppen op een scherm of het handmatig invullen van formulieren niet alleen inefficiënt en traag is, maar ook ouderwets.

Gelukkig zijn er tegenwoordig veel cloudgebaseerde services die het voor ontwikkelaars gemakkelijk maken om conversationele gebruikersinterfaces aan hun apps toe te voegen. Google Dialoglow Standard Edition is zo'n service. Het is gratis, zeer krachtig, meertalig en wordt geleverd met een groot aantal goed ontworpen sjablonen.

In deze zelfstudie laat ik u zien hoe u met Dialogflow een eenvoudige op tekst gebaseerde conversationele gebruikersinterface voor Android kunt maken.

voorwaarden

Zorg voordat u verdergaat dat u toegang heeft tot:

  • de nieuwste versie van Android Studio
  • een apparaat of emulator met Android 5.0 of hoger

1. Een agent maken

Tijdens het gebruik van Dialogflow, zult u altijd met een agent werken, een natuurlijk taalbegripssysteem dat is getraind om een ​​specifieke reeks gebruikersinvoer aan te kunnen.

Om uw eerste agent te maken, gebruikt u een Google-account om u aan te melden bij de Dialogflow-console en drukt u op Agent maken knop.

In de vorm die verschijnt, geeft u de agent een logische naam en drukt u op creëren knop.

Na een paar seconden heb je een geheel nieuwe agent.

2. Een intentie creëren

Terwijl visuele interfaces knoppen hebben die gebruikers kunnen indrukken om hun intenties te uiten, hebben conversationele interfaces intenties. Als zodanig is in een goed ontworpen conversationele interface alles wat een gebruiker kan zeggen toegewezen aan een intentie. De taak van een agent is alleen om nauwkeurig te bepalen welke intentie moet worden geactiveerd wanneer een gebruiker een zin of zin uitspreken of typen.

Laten we, om dingen eenvoudig te houden, slechts één intentie voor onze agent maken: een intentie met de naam GEWICHT, waarmee gebruikers gewichten in kilogrammen naar ponden kunnen omzetten en omgekeerd.

Als u de intentie wilt maken, drukt u op Maak intentie knop in de console.

Typ in het volgende scherm de naam van de intentie en druk op Trainingszinnen toevoegen knop. U kunt nu meerdere zinsdelen opgeven die de agent kan gebruiken om zichzelf te trainen. Bijvoorbeeld, de zin "wat is 32 kilo in ponden" zou een goede trainingszin zijn voor de GEWICHT voornemen.

Nadat je de zin hebt getypt en op de invoeren sleutel, zult u zien dat Dialogflow correct raadt dat de frase "32 kilogram" variabel is. Het zal ook automatisch een programmatisch toegankelijke parameter maken met de naam gewichtseenheid ervoor en stel het type in op @ Sys.unit gewicht.

Evenzo, het veronderstelt dat het woord "pond" ook variabel is en creëert een parameter voor de naam eenheid gewicht namen, van wie type is @ Sys.unit-weight-naam.

Ik stel voor dat je een paar meer vergelijkbare trainingszinnen invoert, waarbij je er altijd voor zorgt dat de gewichtseenheid en eenheid gewicht namen parameters zijn omgezet naar de juiste waarden.

Druk vervolgens op Reacties toevoegen om een ​​paar algemene antwoorden in te voeren. Begrijp wel dat deze voor de gebruiker letterlijk worden getoond.

Als je tevreden bent met de trainingszinnen en antwoorden die je hebt gegeven, ga je gang en druk je op de Opslaan om de intentie op te slaan en het trainingsproces te starten, dat meestal minder dan een minuut duurt.

Zoals ik al eerder zei, moet een goede gespreksinterface in staat zijn om alles wat de gebruiker zegt te verwerken. Dat betekent dat onze agent ook beleefdheden en zinnen moet kunnen in kaart brengen die het niet begrijpt als geldige bedoelingen. Omdat dit een veel voorkomende vereiste is, genereert Dialogflow automatisch dergelijke intenties voor ons, toepasselijk genoemd Standaard welkomstintentie en Standaard Terugvalintentie. Hoewel de laatste geen wijzigingen nodig heeft, doet de eerste dat wel.

De Standaard welkomstintentie heeft geen trainingszinnen, dus je moet er een paar opgeven. Bovendien zullen we niet werken met evenementen in deze zelfstudie, dus je kunt het verwijderen Welkom evenement geassocieerd met het. 

druk de Opslaan knop na het aanbrengen van de wijzigingen.

3. Kleine gesprekken inschakelen

Het is onwaarschijnlijk dat de meeste gebruikers zich beperken tot de GEWICHT bedoeling die je hebt gecreëerd. Hoewel de fallback intent in staat zal zijn om alle ongeldige vragen af ​​te handelen, is het altijd een goed idee om de agent op te leiden zodat deze in gesprek kan gaan. Hierdoor zal het menselijker lijken.

In de Dialogflow-console is het toevoegen van kleine-spraakvaardigheden aan de agent heel eenvoudig. Het enige dat u hoeft te doen is het openen van Koetjes en kalfjes tab en druk op de in staat stellen knop.

Op dit punt kan de agent standaardantwoorden genereren voor veel algemene vragen. Optioneel kun je die reacties aanpassen om het een unieke persoonlijkheid te geven. Voor nu, stel ik voor dat je een paar vragen beantwoordt in de Over agent sectie en druk op de Opslaan knop.

4. Een toegangstoken krijgen

Je Android-app heeft een clienttoegangstoken nodig tijdens het communiceren met de Dialogflow-agent. Om het te krijgen, klikt u op het tandwielpictogram naast de naam van de agent en opent u de Algemeen tab. Scrollen omlaag naar de API-sleutels sectie, kunt u het token zien. Noteer het zodat je het later kunt gebruiken.

5. Projectafhankelijkheden toevoegen

We zullen de Fuel networking-bibliotheek gebruiken tijdens de interactie met de webservice van Dialogflow, dus voeg het volgende toe implementatie afhankelijkheid in de app module build.gradle het dossier:

implementatie 'com.github.kittinunf.fuel: fuel-android: 1.12.1'

Dialogflow kan zowel tekst als audio verwerken. In deze zelfstudie werken we echter alleen met tekst. Bijgevolg zal onze app een chat-app-achtige gebruikersinterface hebben. Dus voeg de ChatMessageView-bibliotheek toe als een andere afhankelijkheid.

implementatie 'com.github.bassaer: chatmessageview: 1.10.0'

Zorg er ten slotte voor dat uw app verbinding met internet kan maken door de volgende toestemming aan te vragen in de AndroidManifest.xml het dossier:

6. De lay-out definiëren

De ChatMessageView-bibliotheek ChatView widget biedt een volwaardige chat-gebruikersinterface die zowel chatberichten kan weergeven als gebruikersinvoer kan accepteren. Door het in onze lay-out te gebruiken, kunnen we veel tijd en moeite besparen. Plaats de widget dus in een FrameLayout widget en voeg het toe aan uw lay-out XML-bestand.

   

Als Kotlin Android Extensions is ingeschakeld in uw project, is een verwijzing naar de widget beschikbaar als extensie-eigenschap binnen uw activiteit.

Ik raad u aan uw app nu uit te voeren om de lay-out te bekijken die u zojuist hebt gemaakt.

7. Brandstof configureren

U kunt uw netwerkcode veel beknopter maken door de Fuel-client specifiek te configureren om de Dialogflow-webservice te gebruiken. Voeg voordat u dit doet echter eerst het clienttoken toe dat u eerder hebt verkregen als een constante bij het compileren van uw activiteit.

metgezel-object private const val ACCESS_TOKEN = "1234567890abcdef"

Alle HTTP-verzoeken die u aan de Dialogflow-webservice doet, moeten een machtiging header gebaseerd op het token. Om te voorkomen dat u handmatig de koptekst maakt telkens wanneer u een aanvraag doet, gebruikt u de baseHeaders eigendom van de FuelManager klasse.

FuelManager.instance.baseHeaders = mapOf ("Autorisatie" bij "Bearer $ ACCESS_TOKEN")

Stel vervolgens de basePath eigendom van de FuelManager class naar de basis-URL van de Dialogflow-webservice.

FuelManager.instance.basePath = "https://api.dialogflow.com/v1/"

Ten slotte moeten al uw HTTP-aanvragen altijd de volgende configuratieparameters hebben: v parameter die de protocolversie aangeeft die u wilt gebruiken, a LANG parameter die de taal specificeert waarin u de antwoorden van de agent wilt hebben, en een sessionId parameter waarvan de waarde een willekeurige tekenreeks kan zijn.

De volgende code laat zien hoe u de baseParams eigenschap om alle parameters in te stellen:

FuelManager.instance.baseParams = listOf ("v" tot "20170712", // laatste protocol "sessionId" voor UUID.randomUUID (), // willekeurige ID "lang" voor "en" // Engelse taal)

8. Configuratie van de chat-interface

De ChatView widget heeft er twee nodig ChatUser objecten: één voor de gebruiker en één voor de agent. Deze objecten zijn bedoeld voor het opslaan van gegevens, zoals de namen en profielafbeeldingen die samen met de chatberichten moeten worden weergegeven. Bovendien elk ChatUser object moet een unieke ID hebben die eraan is gekoppeld.

De volgende code laat zien hoe je de objecten maakt:

val human = ChatUser (1, "You", BitmapFactory.decodeResource (resources, R.drawable.ic_account_circle)) val agent = ChatUser (2, "Agent", BitmapFactory.decodeResource (resources, R.drawable.ic_account_circle))

Merk op dat de code een ingebouwde bron gebruikt met de naam ic_account_circle als de avatar voor beide objecten. Voel je vrij om elke andere bruikbare bron te gebruiken als je dat wilt.

9. Berichten verzenden en ontvangen

Telkens wanneer gebruikers op de verzendknop van de ChatView widget, moet je maken Bericht objecten op basis van de tekst die ze hebben ingetypt. Hiertoe kunt u de Message.Builder klasse. Terwijl u het object maakt, moet u ervoor zorgen dat het bij de menselijke gebruiker hoort door het te gebruiken setUser () methode.

Zodra de Bericht object is klaar, je kunt het doorgeven aan de sturen() methode van de ChatView widget om het weer te geven. De volgende code laat zien hoe je dit in de setOnClickSendButtonListener () methode van de ChatView widget.

my_chat_view.setOnClickSendButtonListener (View.OnClickListener my_chat_view.send (Message.Builder () .setUser (human) .setText (my_chat_view.inputText) .build ()) // Meer code hier)

Als u het bericht van de gebruiker daadwerkelijk naar uw agent wilt verzenden, moet u nu een HTTP GET-verzoek indienen bij de / vraag eindpunt van de Dialogflow-webservice. Als een input verwacht het een vraag parameter, waarvan de waarde elke zin of zin kan zijn die de gebruiker heeft ingevoerd.

Als HTTP-antwoord krijgt u een JSON-document waarvan resultaat / fulfilment / speech waarde bevat het antwoord van de agent.

Fuel.get ("/ query", listOf ("query" naar my_chat_view.inputText)) .responseJson _, _, result -> val reply = result.get (). Obj () .getJSONObject ("result"). getJSONObject ("fulfillment") .getString ("speech") // Meer code hier

Om het antwoord binnen de ChatView widget, je moet opnieuw een nieuwe bouwen Bericht voorwerp. Dit keer moet de eigenaar echter de agent zijn. Bovendien moet u slagen om het bericht aan de rechterkant weer te geven waar naar zijn rechtzetten() methode.

my_chat_view.send (Message.Builder () .setRight (true) .setUser (agent) .setText (reply) .build ())

Als u de app nu uitvoert, kunt u met de agent chatten.

Als u de app vraagt ​​een gewicht in kilogram in pond om te zetten, geeft dit echter alleen een algemeen antwoord. Om de conversie daadwerkelijk uit te voeren, moet u eerst bepalen of de GEWICHT intentie is geactiveerd. Om dit te doen, kunt u de waarde van de resultaat / metadata / intentName sleutel.

val opzet: String? = result.get (). obj () .getJSONObject ("result") .optJSONObject ("metadata") .optString ("intentName") if (intent !! == "WEIGHT") // Meer code hier

Zodra je zeker weet dat het GEWICHT intentie is geactiveerd, kunt u de waarden van de eenheid gewicht namen en gewichtseenheid parameters, die aanwezig zijn in de resultaat / parameters voorwerp.

// Converteer naar wat val unitWeightName = result.get (). Obj () .getJSONObject ("result") .getJSONObject ("parameters") .getString ("unit-weight-name") // Het gewicht dat moet zijn convert val unitWeight = result.get (). obj () .getJSONObject ("result") .getJSONObject ("parameters") .getJSONObject ("unit-weight") .getDouble ("amount")

Met de bovenstaande waarden is alles wat je nodig hebt eenvoudige wiskunde en een if-else verklaring om de conversie uit te voeren. Om het resultaat weer te geven, hebt u een ander resultaat nodig Bericht voorwerp. De eigenaar moet ook de agent zijn.

// Voer resultaat omrekeningsval uit = if (unitWeightName == "lb") unitWeight * 2.20462 else unitWeight / 2.20462 // Resultaat weergeven my_chat_view.send (Message.Builder () .setRight (true) .setUser (agent) .setText ("Dat is $ "%. 2f ".format (resultaat) $ unitWeightName") .build ())

Onze app is klaar. U zou het nu moeten kunnen uitvoeren om te zien dat het alle conversies correct uitvoert.

Conclusie

U weet nu hoe u een vriendelijke en nuttige agent kunt maken met Google Dialogflow. In deze zelfstudie hebt u ook geleerd hoe u een aantrekkelijke interface kunt maken die mensen kunnen gebruiken tijdens de communicatie met de agent.

Raadpleeg de officiële documentatie voor meer informatie over Dialogflow.