Python >> Tutoriel Python >  >> Python

Donnez vie à vos compétences d'assistant vocal Mycroft AI avec Python

Dans les deux premiers articles de cette série sur Mycroft, un assistant vocal numérique open source axé sur la confidentialité, j'ai couvert le contexte derrière les assistants vocaux et certains des principes fondamentaux de Mycroft. Dans la partie 3, j'ai commencé à décrire le code Python requis pour fournir certaines fonctionnalités de base à une compétence qui ajoute des articles à OurGroceries, une application de liste de courses. Et dans la partie 4, j'ai parlé des différents types d'analyseurs d'intention (et quand les utiliser) et j'ai développé le code Python afin que Mycroft puisse fournir des commentaires audibles tout en travaillant sur la compétence.

Dans ce cinquième article, je vais parcourir les sections restantes nécessaires pour développer cette compétence. Je parlerai des dépendances du projet, de la journalisation des sorties à des fins de débogage, de l'utilisation de l'interface utilisateur Web Mycroft pour définir des valeurs (telles que les noms d'utilisateur et les mots de passe) et de la manière d'intégrer ces informations dans votre code Python.

Gérer les dépendances du projet

Il existe généralement trois sources de dépendances de projet lors de l'écriture d'une compétence Mycroft :

  • Packages Python de PyPI
  • Packages au niveau du système extraits d'un dépôt
  • Autres compétences Mycroft

Il existe plusieurs façons de gérer les dépendances dans Mycroft. Vous pouvez utiliser les fichiers "requirements", ou vous pouvez utiliser le manifest.yml fichier.

Étant donné que la plupart des compétences de la boutique Mycroft utilisent des fichiers d'exigences, je vais simplement aborder le manifest.yml dossier. Le manifest.yml le fichier est assez simple. Il y a un dependencies: section, et sous celle-ci se trouvent trois options :python: , system: , et skill: . Sous chaque en-tête, vous devez spécifier les noms des dépendances requises. Un exemple de fichier pourrait ressembler à ceci :

dependencies:
  # Pip dependencies on PyPI
   python:
    - requests
     - gensim

   system:
    # For simple packages, this is all that is necessary
     all: pianobar piano-dev

   # Require the installation of other skills before installing this skill
   skill:
    - my-other-skill

Cependant, étant donné que la majorité des compétences utilisent des fichiers d'exigences, j'utiliserai cette option pour ce projet, vous pouvez donc l'utiliser comme exemple pour d'autres compétences que vous souhaitez utiliser ou créer.

En Python, le requirements.txt , qui répertorie toutes les dépendances Python requises par un projet, est très courant. Ce fichier est assez simple; il peut s'agir soit d'une liste de packages, soit d'une liste de versions spécifiques. Je vais spécifier une version minimale avec du code que j'ai soumis au ourgroceries projet. Il y a trois options pour le requirements.txt de ce projet :

  • ourgroceries==1.3.5  :Spécifie que le package doit être en version 1.3.5
  • ourgroceries>=1.3.5 :Spécifie que le package doit être de version 1.3.5 ou supérieure
  • ourgroceries :Autorise n'importe quelle version du paquet

Mon requirements.txt utilise ourgroceries>=1.3.5 pour permettre les futures mises à jour. Suivant cette même logique, votre requirements.txt pourrait répertorier différents packages au lieu de spécifier un seul package.

L'intégralité de mon requirements.txt le fichier est sur une ligne :

ourgroceries>=1.3.5

Vous pouvez également choisir d'utiliser requirements.sh . Il s'agit d'un script shell qui peut être utilisé pour installer des packages, télécharger des modules à partir de Git ou faire un certain nombre de choses. Ce fichier s'exécute lors de l'installation d'une nouvelle compétence. La compétence Zork a un exemple de requirements.sh scénario. Cependant, bien que vous puissiez l'utiliser, si vous souhaitez soumettre votre compétence au magasin, le requirements.sh seront examinés assez attentivement pour atténuer les problèmes de sécurité.

Déboguez votre skill

Il existe plusieurs façons de déboguer votre compétence. Vous pouvez utiliser l'enregistreur Mycroft ou utiliser les outils de débogage Python standard. Les deux méthodes sont disponibles dans l'interface de ligne de commande Mycroft (CLI), ce qui est très pratique pour le débogage.

Utiliser l'enregistreur Mycroft

Pour démarrer avec l'enregistreur Mycroft, il vous suffit d'avoir le MycroftSkill importé car logger fait partie de la classe de base. Cela signifie que tant que vous travaillez dans la classe pour votre compétence, l'enregistreur est disponible. Par exemple, le code suivant montre comment créer une compétence très basique avec une entrée de journal :

from mycroft import MycroftSkill

class MyFakeSkill(MycroftSkill):
                def __init__(self):
                self.log.info("Skill starting up")

def create_skill():
                return MyFakeSkill()

Logger possède tous les niveaux de journalisation auxquels vous pourriez vous attendre :

  • déboguer : Fournit le niveau de détail le plus élevé, mais n'est pas connecté par défaut
  • info : Fournit des informations générales lorsqu'une compétence s'exécute comme prévu ; il est toujours enregistré
  • avertissement : Indique que quelque chose ne va pas, mais ce n'est pas fatal
  • erreur : Problèmes mortels ; ils sont affichés en rouge dans la CLI
  • exception : Semblable aux erreurs, sauf qu'elles incluent des traces de pile

En plus de s'afficher dans la CLI, l'enregistreur écrit dans skills.log . L'emplacement du fichier varie en fonction de la manière dont vous avez installé Mycroft. Les emplacements communs sont /var/log/mycroft/skills.log , ~/snap/mycroft/common/logs/skills.log , et /var/opt/mycroft/skills.log .

Il peut arriver que vous souhaitiez utiliser l'enregistreur Mycroft en dehors de la classe instanciée. Par exemple, si vous avez des fonctions globales définies en dehors de la classe, vous pouvez importer LOG spécifiquement :

from mycroft import MycroftSkill
from mycroft.util import LOG

def my_global_funct():
                LOG.info("This is being logged outside the class")

class MyFakeSkill(MycroftSkill):
                def __init__(self):
                self.log.info("Skill starting up")

def create_skill():
                return MyFakeSkill()

Utiliser les outils de débogage de Python

Si vous voulez quelque chose qui se démarque davantage, vous pouvez utiliser le Python print() intégré déclarations à déboguer. J'ai constaté qu'il y a des occasions où l'enregistreur Mycroft est lent à produire une sortie. D'autres fois, je veux juste quelque chose qui me saute aux yeux visuellement. Dans les deux cas, je préfère utiliser print() lorsque je débogue en dehors d'un IDE.

Prenez le code suivant, par exemple :

if category_name is None:
    self.log.info("---------------> Adding %s to %s" % (item_to_add, list_name))
    print("-------------> Adding %s to %s" % (item_to_add, list_name))

Cela produit la sortie suivante dans le mycroft-cli-client :

~~~~ings:104 | Skill settings successfully saved to /opt/mycroft/skills/fallback-wolfram-alpha.mycroftai/settings.json
~~~~1 | mycroft.skills.mycroft_skill.mycroft_skill:handle_settings_change:272 | Updating settings for skill AlarmSkill
~~~~save_settings:104 | Skill settings successfully saved to /opt/mycroft/skills/mycroft-alarm.mycroftai/settings.json
 10:50:38.528 | INFO     | 51831 | ConfigurationSkill | Remote configuration updated
 10:50:43.862 | INFO     | 51831 | OurGroceriesSkill | ---------------> Adding hot dogs to my shopping
---------------> Adding hot dogs to my shopping
~~~~7.654 | INFO     | 51831 | mycroft.skills.skill_loader:reload:108 | ATTEMPTING TO RELOAD SKILL: ourgroceries-skill
~~~~831 | mycroft.skills.skill_loader:_execute_instance_shutdown:146 | Skill ourgroceries-skill shut down successfully

Je trouve que, au fur et à mesure que le texte défile, il est beaucoup plus facile d'identifier visuellement une déclaration d'impression qui n'a pas l'en-tête uniforme des autres messages. Il s'agit d'une préférence personnelle et non d'une sorte de recommandation pour les meilleures pratiques de programmation.

Obtenir les commentaires des utilisateurs

Maintenant que vous savez comment voir le résultat de votre compétence, il est temps d'obtenir des informations spécifiques à l'environnement de vos utilisateurs. Dans de nombreux cas, votre compétence aura besoin d'informations sur l'utilisateur pour fonctionner correctement. La plupart du temps, il s'agit d'un nom d'utilisateur et d'un mot de passe. Souvent, ces informations sont nécessaires pour que la compétence s'initialise correctement.

Obtenir l'entrée de l'utilisateur avec Mycroft connecté à Internet

Si votre appareil Mycroft dispose d'une connexion à Internet, vous pouvez utiliser l'interface utilisateur Web de Mycroft pour saisir les informations de l'utilisateur. Connectez-vous à https://account.mycroft.ai et accédez à la section des compétences. Une fois que vous avez correctement configuré votre compétence, vous verrez quelque chose comme ceci :

Ici, vous pouvez découvrir sur quels appareils votre compétence est installée. Dans mon cas, il y a deux appareils :Arch Pi4 et Asus . Il existe également des zones de saisie de texte pour obtenir des informations de l'utilisateur.

Cette interface est créée automatiquement si vous avez configuré le fichier de paramètres de Mycroft. Vous avez deux choix pour les types de fichiers :vous pouvez créer un settingsmeta.yaml ou un settingsmeta.json . Je préfère la syntaxe YAML, c'est donc ce que j'ai utilisé pour ce projet. Voici mon settingsmeta.yaml pour cette compétence :

skillMetadata:
  sections:
  - name: OurGroceries Account
    fields:
    - type: label
      label: "Provide your OurGroceries username/password and then Connect with the button below."
    - name: user_name
      type: text
      label: username
      value: ''
    - name: password
      type: password
      label: Ourgroceries password
      value: ''
    - name: default_list
      type: text
      label: Default Shopping List
      value: ''

La structure de ce fichier est assez facile à comprendre. Chaque fichier doit commencer par un skillsMetadata titre. Ensuite, il y a un sections titre. Chaque nouvelle section est désignée par - name: , qui est la syntaxe YAML pour un élément d'une liste. Ci-dessus, il n'y a qu'une seule section appelée OurGroceries Account , mais vous pouvez avoir autant de sections que vous le souhaitez.

Les champs sont utilisés à la fois pour transmettre et stocker des informations. Un champ peut être aussi simple qu'une étiquette, qui peut fournir une instruction à l'utilisateur. Plus intéressants pour cette compétence, cependant, sont les text et password des champs. Les champs de texte permettent à l'utilisateur de voir ce qu'il tape et sont affichés en texte brut. Ceci convient aux informations non sensibles. Les champs de mot de passe ne sont pas spécifiques aux mots de passe mais sont destinés à masquer des informations sensibles. Une fois que les utilisateurs ont saisi leurs informations et cliqué sur le save bouton, Mycroft remplace le settings.json fichier créé la première fois que la compétence s'initialise. Le nouveau fichier contient les valeurs saisies par l'utilisateur dans l'interface utilisateur Web. La compétence utilisera également ce fichier pour rechercher des informations d'identification et d'autres informations. Si vous rencontrez des problèmes pour utiliser les valeurs correctes dans votre compétence, jetez un œil au settings.json fichier pour nommer correctement les variables et si les valeurs sont stockées ou non dans le fichier JSON.

Obtenir l'entrée de l'utilisateur avec Mycroft hors ligne

Comme vous l'avez peut-être deviné, sans connexion Internet, il est plus difficile de recevoir des informations des utilisateurs finaux. Il n'y a que quelques options. Tout d'abord, vous pouvez écrire votre compétence de telle sorte que, lors de la première exécution, elle invite l'utilisateur à fournir les informations requises par votre compétence. Vous pouvez ensuite l'écrire dans settings.json si vous souhaitez utiliser l'analyseur de paramètres intégré, ou vous pouvez l'écrire dans un fichier de votre choix et vos compétences pourraient gérer l'analyse. Sachez que si vous écrivez au settings.json , il est possible que ce fichier soit écrasé si Mycroft réinitialise votre skill.

Une autre méthode consiste à avoir des valeurs statiques dans un settings.json ou un autre fichier stocké avec le projet. Cela a des implications évidentes en matière de sécurité, mais si votre référentiel est sécurisé, c'est une option viable.

La troisième et dernière option consiste à permettre à l'utilisateur de modifier directement le fichier. Cela peut être fait via les protocoles de partage de fichiers NFS (Network File System) ou Samba, ou vous pouvez simplement accorder les autorisations appropriées à un utilisateur Secure Shell (SSH) qui pourrait utiliser n'importe quel éditeur Unix pour apporter des modifications.

Étant donné que ce projet nécessite un accès à Internet, je n'explorerai pas ces options. Si vous avez des questions, vous pouvez toujours contacter la communauté sur Mattermost.

Accéder aux paramètres de votre skill

À condition que les autres parties de la chaîne fonctionnent (c'est-à-dire que les utilisateurs ont mis à jour leurs paramètres via l'interface utilisateur Web et que Mycroft a mis à jour settings.json en fonction de ces paramètres), l'utilisation des paramètres fournis par l'utilisateur est facile à comprendre.

Comme je l'ai mentionné dans le troisième article (où j'ai discuté du __init__ et initialize méthodes), il est impossible de récupérer les valeurs de settings.json avec le __init__(self) méthode. Par conséquent, vous devez utiliser une autre méthode pour gérer les paramètres. Dans mon cas, j'ai créé un _create_initial_grocery_connection bien nommé méthode :

def _create_initial_grocery_connection(self):
    """
    This gets the username/password from the config file and gets the session cookie
    for any interactions
    :return: None
    """
    self.username = self.settings.get('user_name')
    self.password = self.settings.get('password')
    self.ourgroceries_object = OurGroceries(self.username, self.password)
    asyncio.run(self.ourgroceries_object.login())

Comme vous pouvez le voir, vous pouvez extraire des informations de settings.json en utilisant self.settings.get() . La seule chose à noter est que la valeur que vous transmettez dans doit correspondre au nom dans settingsmeta.yaml . Dans ce cas, comme je n'utilise pas le nom d'utilisateur ou le mot de passe en dehors de cette méthode, j'aurais pu choisir de ne pas intégrer ces variables à la portée de la classe (c'est-à-dire que j'aurais pu les appeler password au lieu de self.password ). C'est parce que je mets le ourgroceries_object à la portée de la classe, et il contient toutes les informations requises pour que le reste de la compétence fonctionne.

Conclusion

Les assistants vocaux se développent pour devenir une entreprise de plusieurs millions (sinon de milliards) de dollars et certains analystes pensent qu'une majorité de foyers dans les prochaines années en auront un (ou plus). Avec Apple, Google, Facebook et d'autres fréquemment dans l'actualité pour les violations de la vie privée, sans parler du flux constant de violations de données signalées, il est important d'avoir une alternative open source et axée sur la confidentialité aux grands acteurs. Mycroft donne la priorité à votre vie privée, et sa petite mais dévouée équipe de contributeurs fait des incursions dans les scénarios les plus courants pour les assistants vocaux.

Cette série a plongé dans les détails du développement des compétences, parlant de l'importance de bien réfléchir avant de commencer et d'avoir un bon plan. Savoir où vous allez dans la vue d'ensemble vous aide à organiser votre code. Décomposer les tâches en éléments individuels est également un élément clé de votre stratégie. Parfois, c'est une bonne idée d'écrire des morceaux ou des morceaux significatifs en dehors de l'environnement de compétence Mycroft pour s'assurer que votre code fonctionnera comme prévu. Ce n'est pas nécessaire, mais cela peut être un excellent point de départ pour les personnes qui découvrent le développement des compétences.

La série a également exploré les analyseurs d'intention et comment comprendre quand les utiliser. Les analyseurs Padatious et Adapt ont chacun leurs forces et leurs faiblesses.

  • Les intentions padatious s'appuient sur des phrases et des entités au sein de ces phrases pour comprendre ce que l'utilisateur tente d'accomplir, et elles sont souvent utilisées par défaut pour les compétences Mycroft.
  • D'autre part, Adapt utilise des expressions régulières pour atteindre des objectifs similaires. Lorsque vous avez besoin que Mycroft soit sensible au contexte, Adapt est la seule solution. Il est également extrêmement efficace pour analyser des énoncés complexes. Cependant, vous devez faire très attention lorsque vous utilisez des expressions régulières, sinon vous obtiendrez des résultats inattendus.

J'ai également abordé les bases de la gestion d'un projet. C'est une étape importante dans le développement de compétences complexes pour s'assurer qu'une compétence a toutes les dépendances appropriées pour fonctionner. Assurer une portabilité maximale est primordial pour une compétence, et la résolution des dépendances en est un élément clé, car votre compétence peut ne pas fonctionner correctement avec des dépendances non satisfaites.

Enfin, j'ai expliqué comment obtenir des paramètres spécifiques aux compétences des utilisateurs, que l'appareil soit connecté à Internet ou non. La méthode que vous choisissez dépend vraiment de votre cas d'utilisation.

Bien que mon objectif ne soit pas de fournir une encyclopédie du développement des compétences de Mycroft, en travaillant sur cette série, vous devriez avoir une base très solide pour développer la plupart des compétences que vous souhaitez créer. J'espère que les exemples concrets de cette série vous montreront comment gérer la majorité des tâches que vous voudrez peut-être accomplir pendant le développement des compétences. Je n'ai pas parcouru toute la compétence ligne par ligne, mais le code est hébergé sur GitLab si vous souhaitez l'explorer davantage. Les commentaires et les questions sont toujours les bienvenus. Je continue d'apprendre et de grandir en tant que jeune développeur Mycroft, alors contactez-moi sur Twitter ou sur l'instance Mycroft Mattermost, et apprenons ensemble !