Entrée vocale et langage naturel pour votre application mobile en utilisant LLMs

Entrée vocale et langage naturel avec LLMs pour app mobile

Comment utiliser les fonctions OpenAI GPT-4 pour naviguer dans votre interface graphique (GUI)

Photo de Kelly Sikkema sur Unsplash

Introduction

Un modèle de langage large (LLM) est un système d’apprentissage automatique capable de traiter efficacement le langage naturel. Le LLM le plus avancé disponible actuellement est GPT-4, qui alimente la version payante de ChatGPT. Dans cet article, vous apprendrez comment donner à votre application une interprétation vocale hautement flexible en utilisant l’appel de fonctions GPT-4, en pleine synergie avec l’interface graphique de votre application (GUI). Il s’adresse aux propriétaires de produits, aux concepteurs UX et aux développeurs mobiles.

Contexte

Les assistants numériques sur les téléphones mobiles (Android et iOS) n’ont pas réussi à s’imposer pour plusieurs raisons, notamment parce qu’ils sont défectueux, limités et souvent fastidieux à utiliser. Les LLM, et maintenant en particulier OpenAI GPT-4, ont le potentiel de faire la différence ici, grâce à leur capacité à comprendre plus profondément l’intention de l’utilisateur au lieu d’essayer de faire correspondre grossièrement une expression verbale.

Android dispose des “actions d’application” de Google Assistant et iOS dispose des “intents SiriKit”. Ils fournissent des modèles simples que vous pouvez utiliser pour enregistrer des requêtes vocales que votre application peut gérer. Google Assistant et Siri ont déjà beaucoup progressé au cours des dernières années, même plus que vous ne le réalisez probablement. Leur couverture est largement déterminée par les applications qui implémentent leur prise en charge. Néanmoins, vous pouvez, par exemple, écouter votre chanson préférée sur Spotify en utilisant la reconnaissance vocale. Cependant, l’interprétation du langage naturel de ces services fournis par le système d’exploitation précède les énormes avancées de ce domaine apportées par les LLM, il est donc temps de tirer parti de la puissance des LLM pour rendre la saisie vocale plus fiable et flexible.

Bien que l’on puisse s’attendre à ce que les services du système d’exploitation (comme Siri et Google Assistant) adaptent bientôt leurs stratégies pour tirer parti des LLM, nous pouvons déjà permettre à nos applications d’utiliser la reconnaissance vocale sans être limitées par ces services. Une fois que vous aurez adopté les concepts de cet article, votre application sera également prête à exploiter de nouveaux assistants, lorsqu’ils seront disponibles.

Le choix de votre LLM (GPT, PaLM, LLama2, MPT, Falcon, etc.) a un impact sur la fiabilité, mais les principes fondamentaux que vous apprendrez ici peuvent être appliqués à n’importe lequel d’entre eux. Nous permettrons à l’utilisateur d’accéder à l’ensemble des fonctionnalités de l’application en disant ce qu’il souhaite dans une seule expression. Le LLM mappe une expression de langage naturel en un appel de fonction sur la structure de navigation et la fonctionnalité de notre application. Et cela ne doit pas être une phrase prononcée comme un robot. Les capacités d’interprétation des LLM permettent aux utilisateurs de parler comme des humains, en utilisant leurs propres mots ou langage, hésitant, faisant des erreurs et les corrigeant. Là où les utilisateurs ont rejeté les assistants vocaux parce qu’ils ne comprennent souvent pas ce qu’ils veulent dire, la flexibilité d’un LLM peut rendre l’interaction beaucoup plus naturelle et fiable, ce qui entraîne une adoption plus élevée par les utilisateurs.

Pourquoi la saisie vocale dans votre application, et pourquoi maintenant ?

Avantages :

  • Naviguer vers un écran et fournir tous les paramètres dans une seule expression vocale
  • Courbe d’apprentissage faible : pas besoin pour l’utilisateur de trouver où se trouvent les données dans votre application ou comment utiliser l’interface graphique
  • Mains libres
  • Complémentaire et non déconnecté (comme dans une interface utilisateur vocale ou VUI) : la parole et l’interface graphique fonctionnent en harmonie
  • Accessibilité pour les personnes malvoyantes
  • Maintenant : parce que l’interprétation du langage naturel a atteint un nouveau niveau grâce aux LLM, les réponses sont beaucoup plus fiables

Inconvénients :

  • Confidentialité lors de la parole
  • Précision/mauvaises interprétations
  • Toujours relativement lent
  • Connaissance dans la tête par rapport à la connaissance dans le monde (Que puis-je dire ?) : l’utilisateur ne sait pas quelles expressions verbales le système comprend et auxquelles il a des réponses

Les exemples d’applications qui peuvent bénéficier de la saisie vocale comprennent celles utilisées pour l’assistance à la conduite en voiture ou à vélo. En général, les utilisateurs peuvent ne pas vouloir se concentrer sur la précision de la navigation dans une application par le toucher lorsqu’ils ne peuvent pas utiliser facilement leurs mains, par exemple lorsqu’ils sont en déplacement, portent des gants ou sont occupés à travailler avec leurs mains.

Les applications de shopping peuvent également bénéficier de cette fonctionnalité, car les utilisateurs peuvent verbaliser leurs désirs dans leurs propres mots, plutôt que de naviguer à travers les écrans de shopping et de définir des filtres.

Lors de l’application de cette approche pour améliorer l’accessibilité des personnes malvoyantes, vous voudrez peut-être envisager d’ajouter une sortie en langage naturel et des fonctionnalités de synthèse vocale à l’ensemble.

Votre application

La figure suivante montre la structure de navigation d’une application typique, illustrée par un planificateur de trajets en train avec lequel vous êtes peut-être familier. En haut, vous pouvez voir la structure de navigation par défaut pour la navigation tactile. Cette structure est régie par le composant de navigation. Tous les clics de navigation sont délégués au composant de navigation, qui exécute ensuite l’action de navigation. En bas, nous montrons comment nous pouvons utiliser la saisie vocale pour accéder à cette structure.

activation de la saisie vocale dans votre application en appelant la fonction LLM

Les utilisateurs disent ce qu’ils veulent, puis un reconnaissant vocal transforme la parole en texte. Le système construit une invitation contenant ce texte et l’envoie au LLM. Le LLM répond à l’application avec des données, lui indiquant quelle écran activer avec quels paramètres. Cet objet de données est transformé en un lien profond et donné au composant de navigation. Le composant de navigation active l’écran approprié avec les bons paramètres : dans cet exemple, l’écran “Sorties” avec le paramètre “Amsterdam”. Veuillez noter qu’il s’agit d’une simplification. Nous détaillerons les détails ci-dessous.

De nombreuses applications modernes disposent d’un composant de navigation centralisé en interne. Android dispose de la navigation Jetpack, Flutter dispose du Router, iOS dispose de NavigationStack. Les composants de navigation centralisés permettent les liens profonds, qui est une technique qui permet aux utilisateurs de naviguer directement vers un écran spécifique dans une application mobile, plutôt que de passer par l’écran principal ou le menu de l’application. Pour que les concepts de cet article fonctionnent, un composant de navigation et des liens profonds centralisés ne sont pas nécessaires, mais ils facilitent la mise en œuvre des concepts.

Les liens profonds consistent à créer un chemin unique (URI) qui pointe vers un contenu spécifique ou une section spécifique dans une application. De plus, ce chemin peut contenir des paramètres qui contrôlent les états des éléments de l’interface utilisateur à l’écran vers lequel le lien profond pointe.

Appel de fonction pour votre application

Nous indiquons au LLM de mapper une expression en langage naturel vers un appel de fonction de navigation grâce à des techniques d’ingénierie de l’invitation. Fondamentalement, l’invitation ressemble à ceci : “étant donné les modèles de fonctions suivants avec des paramètres, mappez la question en langage naturel suivante sur l’un de ces modèles de fonctions et renvoyez-le”.

La plupart des LLM sont capables de le faire. LangChain l’a exploité efficacement grâce aux agents Zero Shot ReAct et les fonctions à appeler sont appelées Outils. OpenAI a affiné ses modèles GPT-3.5 et GPT-4 avec des versions spéciales (actuellement gpt-3.5-turbo-0613 et gpt-4–0613) qui sont très performantes dans ce domaine et ils ont créé des entrées API spécifiques à cette fin. Dans cet article, nous utiliserons la notation d’OpenAI, mais les concepts peuvent être appliqués à n’importe quel LLM, par exemple en utilisant le mécanisme ReAct mentionné. De plus, LangChain dispose d’un type d’agent spécifique (AgentType.OPENAI_FUNCTIONS) qui traduit les Outils en modèles de fonctions OpenAI en interne. Pour LLama2, vous pourrez utiliser llama-api avec la même syntaxe qu’OpenAI.

L’appel de fonction pour les LLM fonctionne comme suit :

  1. Vous insérez un schéma JSON de modèles de fonctions dans votre invitation, ainsi que l’expression en langage naturel de l’utilisateur en tant que message de l’utilisateur.
  2. Le LLM tente de mapper l’expression en langage naturel de l’utilisateur sur l’un de ces modèles.
  3. Le LLM renvoie l’objet JSON résultant afin que votre code puisse effectuer un appel de fonction.

Dans cet article, les définitions de fonctions sont des correspondances directes de l’interface utilisateur graphique (GUI) d’une application (mobile), où chaque fonction correspond à un écran et chaque paramètre à un élément de l’interface utilisateur sur cet écran. Une expression en langage naturel envoyée au LLM renvoie un objet JSON contenant un nom de fonction et ses paramètres que vous pouvez utiliser pour naviguer vers l’écran approprié et déclencher la bonne fonction dans votre modèle de vue, de sorte que les bonnes données soient récupérées et la valeur des éléments de l’interface utilisateur pertinents sur cet écran soit définie en fonction des paramètres.

Ceci est illustré dans la figure suivante :

mapping des fonctions LLM sur l'interface utilisateur de votre application mobile

Il montre une version simplifiée des modèles de fonction ajoutés à la demande de LLM. Pour voir la demande complète pour le message de l’utilisateur : ‘Que puis-je faire à Amsterdam ?’, cliquez ici (Github Gist). Il contient une demande curl complète que vous pouvez utiliser depuis la ligne de commande ou importer dans Postman. Vous devez mettre votre propre clé OpenAI dans l’espace réservé pour l’exécuter.

Écrans sans paramètres

Certains écrans de votre application n’ont pas de paramètres, ou du moins pas ceux dont le LLM a besoin de connaître. Afin de réduire l’utilisation des jetons et le désordre, nous pouvons regrouper un certain nombre de ces déclencheurs d’écran dans une seule fonction avec un paramètre : l’écran à ouvrir

{    "name": "afficher_écran",    "description": "Déterminer quel écran l'utilisateur veut voir",    "parameters": {        "type": "object",        "properties": {            "écran_à_afficher": {                "description": "type d'écran à afficher. Soit                     'compte' : 'toutes les données personnelles de l'utilisateur',                     'paramètres' : 'si l'utilisateur souhaite modifier les paramètres de                                 l'application'",                "enum": [                    "compte",                    "paramètres"                ],                "type": "string"            }        },        "required": [            "écran_à_afficher"        ]    }},

Le critère permettant de déterminer si une fonction de déclenchement a besoin de paramètres est de savoir si l’utilisateur a le choix : s’il y a une forme de recherche ou de navigation sur l’écran, c’est-à-dire s’il y a des champs de recherche (comme) ou des onglets à choisir.

Si ce n’est pas le cas, alors le LLM n’a pas besoin de le savoir, et le déclenchement de l’écran peut être ajouté à la fonction de déclenchement d’écran générique de votre application. C’est principalement une question d’expérimentation avec les descriptions du but de l’écran. Si vous avez besoin d’une description plus longue, vous pouvez envisager de lui donner sa propre définition de fonction, afin de mettre davantage l’accent sur sa description que sur l’énumération du paramètre générique.

Guidage et réparation des instructions de la demande :

Dans le message système de votre demande, vous donnez des informations génériques de direction. Dans notre exemple, il peut être important pour le LLM de savoir quelle date et quelle heure il est maintenant, par exemple si vous voulez planifier un voyage pour demain. Une autre chose importante est de guider son présomptueux. Souvent, nous préférons que le LLM soit trop confiant plutôt que de déranger l’utilisateur avec son incertitude. Un bon message système pour notre application exemple est le suivant :

"messages": [        {            "role": "système",            "content": "La date et l'heure actuelles sont le 2023-07-13T08:21:16+02:00.                       Soyez très présomptueux en devinant les valeurs des                        paramètres de fonction."        },

Les descriptions des paramètres de fonction peuvent nécessiter un réglage assez précis. Un exemple est la trip_date_time lors de la planification d’un voyage en train. Une description raisonnable du paramètre est la suivante :

"trip_date_time": {      "description": "DateTime demandée pour le départ ou l'arrivée du voyage                       au format 'AAAA-MM-JJTHH:MM:SS+02:00'.                      L'utilisateur utilisera une heure dans un système de 12 heures, faites une                       supposition intelligente sur ce que l'utilisateur est le plus susceptible de                       vouloir dire en termes de système de 24 heures, par exemple ne pas planifier                       pour le passé.",                      "type": "string"                  },

Ainsi, s’il est actuellement 15:00 et que les utilisateurs disent qu’ils veulent partir à 8 heures, ils veulent dire 20:00 à moins qu’ils ne mentionnent spécifiquement l’heure de la journée. L’instruction ci-dessus fonctionne raisonnablement bien pour GPT-4. Mais dans certains cas particuliers, elle échoue toujours. Nous pouvons alors par exemple ajouter des paramètres supplémentaires au modèle de fonction que nous pouvons utiliser pour effectuer d’autres réparations dans notre propre code. Par exemple, nous pouvons ajouter :

"explicit_day_part_reference": {          "description": "Préférez toujours None ! None si la demande se réfère                         à la journée actuelle, sinon la partie de la journée à                         laquelle la demande se réfère."          "enum": ["aucun", "matin", "après-midi", "soir", "nuit"],                            }

Dans votre application, vous allez probablement trouver des paramètres qui nécessitent un post-traitement pour améliorer leur taux de réussite.

Demandes du système pour clarification

Parfois, la demande de l’utilisateur manque d’informations pour continuer. Il peut ne pas y avoir de fonction adaptée pour traiter la demande de l’utilisateur. Dans ce cas, LLM répondra en langage naturel que vous pouvez montrer à l’utilisateur, par exemple au moyen d’un Toast.

Il se peut également que LLM reconnaisse une fonction potentielle à appeler, mais qu’il manque des informations pour remplir tous les paramètres de fonction requis. Dans ce cas, envisagez de rendre les paramètres facultatifs, si possible. Mais si cela n’est pas possible, LLM peut envoyer une demande, en langage naturel, pour les paramètres manquants, dans la langue de l’utilisateur. Vous devez afficher ce texte aux utilisateurs, par exemple par le biais d’un Toast ou de la synthèse vocale, afin qu’ils puissent fournir les informations manquantes (à l’oral). Par exemple, lorsque l’utilisateur dit “Je veux aller à Amsterdam” (et votre application n’a pas fourni d’emplacement par défaut ou actuel via le message système), LLM pourrait répondre “Je comprends que vous voulez faire un voyage en train, d’où voulez-vous partir ?”.

Cela soulève la question de l’historique de la conversation. Je vous recommande toujours d’inclure les 4 derniers messages de l’utilisateur dans la demande, afin qu’une demande d’informations puisse être répartie sur plusieurs tours. Pour simplifier les choses, omettez simplement les réponses du système de l’historique, car dans ce cas d’utilisation, elles ont tendance à faire plus de mal que de bien.

Reconnaissance vocale

La reconnaissance vocale est une partie cruciale de la transformation de la parole en une action de navigation paramétrée dans l’application. Lorsque la qualité de l’interprétation est élevée, une mauvaise reconnaissance vocale peut très bien être le maillon faible. Les téléphones mobiles disposent d’une reconnaissance vocale embarquée, d’une qualité raisonnable, mais la reconnaissance vocale basée sur LLM comme Whisper, Google Chirp/USM, Meta MMS ou DeepGram tend à donner de meilleurs résultats.

Architecture

Il est probablement préférable de stocker les définitions de fonction sur le serveur, mais elles peuvent également être gérées par l’application et envoyées avec chaque demande. Les deux ont leurs avantages et leurs inconvénients. Les envoyer avec chaque demande est plus flexible et l’alignement des fonctions et des écrans peut être plus facile à maintenir. Cependant, les modèles de fonction contiennent non seulement le nom de la fonction et les paramètres, mais aussi leurs descriptions que nous pourrions vouloir mettre à jour plus rapidement que le flux de mise à jour dans les boutiques d’applications. Ces descriptions dépendent plus ou moins de LLM et sont conçues pour ce qui fonctionne. Il n’est pas improbable que vous souhaitiez remplacer LLM par un meilleur ou moins cher, voire le remplacer dynamiquement à un moment donné. Avoir les modèles de fonction sur le serveur peut également avoir l’avantage de les maintenir en un seul endroit si votre application est native sur iOS et Android. Si vous utilisez les services OpenAI à la fois pour la reconnaissance vocale et le traitement du langage naturel, le schéma technique global du flux ressemble à ceci :

architecture pour activer la parole dans votre application mobile en utilisant Whisper et l'appel de fonction OpenAI

Les utilisateurs expriment leur demande, elle est enregistrée dans un tampon/fichier m4a (ou mp3 si vous le préférez), qui est envoyé à votre serveur, qui le transmet à Whisper. Whisper répond avec la transcription, et votre serveur la combine avec votre message système et les modèles de fonction dans une demande pour LLM. Votre serveur reçoit en retour l’appel de fonction brut au format JSON, qu’il traite ensuite en un objet JSON d’appel de fonction pour votre application.

Pour illustrer comment un appel de fonction se traduit par un lien profond, nous prenons la réponse de l’appel de fonction de l’exemple initial :

"function_call": {                    "name": "outings",                    "arguments": "{\n  \"area\": \"Amsterdam\"\n}"                }

Cela est traité de manière assez différente sur différentes plateformes, et au fil du temps, de nombreux mécanismes de navigation différents ont été utilisés, et sont souvent encore utilisés. Il est hors de portée de cet article d’entrer dans les détails de mise en œuvre, mais en gros, les plates-formes dans leur incarnation la plus récente peuvent utiliser le lien profond comme suit :

Sur Android :

navController.navigate("outings/?area=Amsterdam")

Sur Flutter :

Navigator.pushNamed(      context,      '/outings',      arguments: ScreenArguments(        area: 'Amsterdam',      ),    );

Sur iOS, les choses sont un peu moins standardisées, mais en utilisant NavigationStack :

NavigationStack(path: $router.path) {            ...}

Et ensuite, en émettant :

router.path.append("outing?area=Amsterdam")

Vous pouvez trouver plus d’informations sur le deep linking ici : pour Android, pour Flutter, pour iOS

Champ de texte libre pour les applications

Il y a deux modes de saisie de texte libre : la voix et la frappe. Nous avons principalement parlé de la parole, mais un champ de texte pour la saisie est également une option. Le langage naturel est généralement assez long, il peut donc être difficile de rivaliser avec l’interaction graphique. Cependant, GPT-4 a tendance à être assez bon pour deviner les paramètres à partir des abréviations, il est donc souvent possible d’interpréter correctement même une frappe très courte et abrégée.

L’utilisation de fonctions avec des paramètres dans l’invite réduit souvent considérablement le contexte d’interprétation pour un LLM. Par conséquent, il a besoin de très peu d’informations, et encore moins si vous lui demandez d’être présomptueux. Il s’agit d’un phénomène nouveau qui offre des perspectives pour l’interaction mobile. Dans le cas du planificateur de gare à gare, le LLM a effectué les interprétations suivantes lorsqu’il était utilisé avec la structure d’invite exemplaire dans cet article. Vous pouvez l’essayer vous-même en utilisant le lien d’invite mentionné ci-dessus.

Exemples :

‘ams utr’ : montrez-moi une liste d’itinéraires de train de la gare centrale d’Amsterdam à la gare centrale d’Utrecht partant maintenant

‘utr ams arr 9’ : (Étant donné qu’il est 13h00 en ce moment). Montrez-moi une liste d’itinéraires de train de la gare centrale d’Utrecht à la gare centrale d’Amsterdam arrivant avant 21h00

Interaction de suivi

Tout comme dans ChatGPT, vous pouvez affiner votre requête si vous envoyez un court extrait de l’historique de l’interaction :

En utilisant la fonction d’historique, cela fonctionne également très bien (supposons qu’il soit 9h00 du matin maintenant) :

Tapez : ‘ams utr’ et obtenez la réponse comme ci-dessus. Ensuite, tapez ‘arr 7’ dans le prochain tour. Et oui, il peut effectivement traduire cela en un voyage planifié d’Amsterdam Central à Utrecht Central arrivant avant 19h00. J’ai créé une application web d’exemple à ce sujet que vous pouvez trouver une vidéo à ce sujet. Le lien vers l’application réelle se trouve dans la description.

Futur

Vous pouvez vous attendre à ce que cette structure de deep linking gère les fonctions de votre application et devienne une partie intégrante du système d’exploitation de votre téléphone (Android ou iOS). Un assistant global sur le téléphone gérera les demandes vocales et les applications pourront exposer leurs fonctions au système d’exploitation, de manière à ce qu’elles puissent être déclenchées de manière profonde. Cela est similaire à la façon dont les plugins sont disponibles pour ChatGPT. De toute évidence, une forme grossière de cela est déjà disponible via les intentions dans AndroidManifest et les actions d’application sur Android, et via SiriKit intents sur iOS. Vous avez un contrôle limité sur ceux-ci, et l’utilisateur doit parler comme un robot pour les activer de manière fiable. Indéniablement, cela s’améliorera avec le temps, lorsque les assistants alimentés par LLM prendront le relais.

La réalité virtuelle et augmentée (XR) offre de grandes opportunités pour la reconnaissance vocale, car les mains des utilisateurs sont souvent occupées par d’autres activités.

Il ne faudra probablement pas longtemps avant que n’importe qui puisse exécuter son propre LLM de haute qualité. Les coûts diminueront et la vitesse augmentera rapidement au cours de l’année prochaine. Bientôt, des LLM LoRA seront disponibles sur les smartphones, de sorte que l’inférence puisse avoir lieu sur votre téléphone, réduisant ainsi les coûts et la vitesse. De plus en plus de concurrence arrivera, à la fois en open source comme Llama2, et en source fermée comme PaLM.

Enfin, la synergie des modalités peut être poussée plus loin que la simple possibilité d’accéder de manière aléatoire à l’interface graphique de votre application entière. C’est le pouvoir des LLMs de combiner plusieurs sources qui permet d’espérer une meilleure assistance. Quelques articles intéressants : dialogue multimodal, blog de Google sur les interfaces graphiques et les LLM, interprétation de l’interaction graphique comme du langage.

Conclusion

Dans cet article, vous avez appris comment appliquer l’appel de fonctions pour permettre la parole dans votre application. En utilisant le Gist fourni comme point de départ, vous pouvez expérimenter dans Postman ou en ligne de commande pour vous faire une idée de la puissance de l’appel de fonctions. Si vous souhaitez exécuter une POC pour permettre la parole dans votre application, je vous recommande de mettre immédiatement la partie serveur, de la section architecture, directement dans votre application. Tout se résume à 2 appels HTTP, à la construction de l’invite et à la mise en œuvre de l’enregistrement du microphone. En fonction de vos compétences et de votre base de code, vous aurez votre POC opérationnelle en quelques jours.

Heureux de coder !

Suivez-moi sur LinkedIn

Toutes les images de cet article, sauf indication contraire, sont de l’auteur

We will continue to update IPGirl; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AI

Comment devrions-nous voir les données cliniques biaisées en apprentissage automatique médical ? Un appel à une perspective archéologique

Des chercheurs du MIT, de l’Université Johns Hopkins et de l’Institut Alan Turing soutiennent que traiter...

AI

Meilleurs outils de confidentialité DNS en 2023

Le monde en ligne peut avoir rendu disponibles des quantités de données auparavant inimaginables, mais il a également...

AI

La prochaine frontière de l'efficacité de la messagerie électronique avec les LLM

Introduction L’intelligence artificielle (IA) a considérablement progressé ces dernières années, principalement...

AI

Question-réponse visuelle modulaire via la génération de code

Publié par Sanjay Subramanian, doctorant en informatique, UC Berkeley, et Arsha Nagrani, chercheur scientifique, Goog...

AI

Quatre technologies du laboratoire Lincoln remportent cinq prix R&D 100 en 2023

Les inventions en imagerie médicale, en planification des équipages de vol, en sécurité des données et en réseautage ...