Bouwen, koppelen en printen
De spraakketen werkt van microfoon tot speaker, een gescript gesprek bouwt op de achtergrond het profiel op en de bonnenprinter print het uit zonder dat er iets op schijf komt. Op 6 november gedemonstreerd aan de product owner en getest op Society 5.0.
In deze week kwam alles samen.
De spraakketen
Ik heb de onderdelen aan elkaar geknoopt: microfoon, Whisper, antwoord, Piper, speaker. Opnemen gaat met een knop (push-to-talk). Automatisch detecteren wanneer iemand praat klinkt mooier, maar op een drukke expo is een knop veel betrouwbaarder. Als eerste test gaf de booth gewoon je eigen zin terug. Je drukte op de knop, praatte, en hoorde jezelf terug in de stem van de robot.
Daarna heb ik foutafhandeling toegevoegd en een reset die op elk moment werkt. Op een expo loopt iemand gewoon weg midden in een zin, en de volgende bezoeker moet dan schoon kunnen beginnen.
Ook liep ik tegen een privacyprobleem aan. Twee bibliotheken die we gebruiken (Piper en de WebSocket-verbinding) schreven op het gedetailleerde logniveau wel tekst weg. Daar zou dus kunnen staan wat een bezoeker zei. Ik heb dat dichtgezet en tests geschreven die bij elk gesprek controleren dat er niets naar schijf gaat en dat er geen tekst van bezoekers in de logs staat.
Een gesprek zonder taalmodel
Welk taalmodel we gaan gebruiken lag nog open. Ik wilde daar niet op wachten, dus ik heb eerst een gescript gesprek gebouwd. Mijn team had per persona de vragensets geschreven, en ook de rest van de vragen. Ik heb die in de backend geïmplementeerd. Alle teksten staan in één bestand: de begroeting, de vragen en een lijst thema's met trefwoorden. Zo kan het team de teksten aanpassen zonder dat iemand de code hoeft aan te raken. Noemt een bezoeker "voetbal", dan vraagt de AI daarop door en komt "Sport: voetbal" op het profiel, met aannames die vooraf geschreven zijn.
Het gesprek en het profiel heb ik bewust gescheiden. De chat blijft onschuldig en vriendelijk, een aparte profiler bouwt op de achtergrond het profiel op. Precies zoals de installatie het straks ook moet laten zien. Later kan het taalmodel de plek van het script innemen, achter dezelfde interface. Het script is dus eigenlijk de fake van het taalmodel.
Twee keuzes die ik interessant vond:
- Op het profiel staan alleen woorden uit ons eigen script, nooit wat de bezoeker letterlijk zei. Zegt iemand "ik voetbal bij VV Diemen sinds mijn achtste", dan komt er alleen "Sport: voetbal" op.
- De trefwoorden snappen geen ontkenning. "Ik haat sport" zet ook Sport op je profiel. Dat hebben we zo gelaten, want het laat goed zien hoe snel een AI conclusies trekt.
Sommige vragensets van het team beginnen met een ja-nee-vraag. Dat sluit aan bij wat de testpersoon in de guerrilla test zei. Ik heb het zo gebouwd dat de AI bij een nee de rest van die set overslaat.
Daarna heb ik de frontend van de creative technologists aan de backend gekoppeld. De robot praat, de tekstballon loopt gelijk met de stem, en bij de onthulling van het profiel wordt het gezicht rood.
De printer: het lastigste stukje
Mijn teamgenoot had de bonnenprinter al los getest. Mijn taak was hem aan de applicatie te koppelen, zodat het profiel na het gesprek automatisch uitgeprint wordt. Dat bleek lastiger dan ik dacht, door drie dingen.
1. Het ontwerp van de bon paste niet bij de data. Op het voorbeeld van de bon stonden naam, leeftijd en opleiding. Maar daar vraagt de AI niet naar. Ik heb die velden niet verzonnen, maar weggelaten of vervangen door iets wat we wel weten, zoals het aantal besproken onderwerpen.
2. Het logo werd een zwart blok. Het logo heeft een donkere sterrenhemel als achtergrond. Een thermische printer kent alleen zwart en wit, dus dat werd een groot zwart vlak. De backend maakt die achtergrond nu wit voordat hij print.
3. Hoe praat je met de printer? De normale manier is via de printwachtrij van Windows. Maar die schrijft elke printopdracht even naar de harde schijf, en op een bon staat iemands profiel. Dat botst met onze regel dat er niets van bezoekers wordt opgeslagen. Er bestaat ook een manier met een andere driver (Zadig), maar dan werkt de printer niet meer als gewone Windows-printer. Uiteindelijk schrijft de backend nu rechtstreeks naar de USB-printpoort van Windows. Geen wachtrij, geen extra driver. Het nadeel is dat dit alleen op Windows werkt, maar de booth draait toch op Windows.
Daarnaast heb ik de opmaak van de bon losgehaald van het printen zelf. Zo kan ik de bon testen en bekijken in de terminal zonder dat er een printer aan hangt. Staat de printer uit, dan krijgt het scherm een foutmelding en loopt het gesprek gewoon door. Opnieuw printen kan, maar alleen na een fout en alleen voor dezelfde bezoeker. Zo komt er nooit een extra kopie van iemands profiel uit.
Wat ik leerde: hardware aansluiten is meer dan "werkt het of niet". Elke keuze, zelfs welke route je naar de printer neemt, heeft gevolgen voor privacy.
Sprint review en Society 5.0
Op 6 november lieten we alles zien aan onze product owner. De spraak, het gesprek, het profiel en de bon werkten. De image recognition van mijn teamgenoot werkte als losse demo, maar is nog niet gekoppeld. Ook hebben we het op Society 5.0 getest met echte bezoekers.
Daar zag ik iets wat ik met mijn metingen op de laptop niet had gezien. Bij veel achtergrondgeluid had de spraakherkenning af en toe nog moeite. En soms dacht Whisper dat iemand Engels sprak terwijl diegene Nederlands praatte. Mijn metingen had ik gedaan met rustige opnames. Een expo is iets heel anders.
De feedback van de PO was eerlijk. Technisch zit het goed. Maar de persona's die we hadden toegevoegd, waren volgens haar een beetje afgedwaald van de kern. Ze miste de ruwe testdata van Society 5.0 en wat we daarmee doen. Ook wil ze een Nederlandse en een Engelse modus, zodat iedereen mee kan doen en niet alleen mensen die Nederlands spreken. En de belangrijkste vraag: waarom zou iemand überhaupt met de installatie gaan praten? Die vraag hoorden we op Society 5.0 ook van bezoekers.