ChatGPT peut il m'assister partie 1 ?
Par nature le DSL Ansible n’est pas un langage de programmation, mais permet plutôt de décrire le résultat souhaité. Le code se trouve en fait dans les modules qui eux sont écrits en Python. Alors est-il possible de demander de l’aide à une Intelligence Artificielle comme celle de ChatGPT ?
Dans ce billet, je vais demander à chatGPT
de produire du code Ansible et
nous analyserons le résultat. Nous regarderons s’il respecte surtout les bonnes
pratiques que j’ai définies dans mon précédent
billet.
Utilisation du SDK OpenAI
Je ne vais pas utiliser le chatbot, mais le SDK Python d’OpenAI.
Installation du SDK Python OpenAI
Le SDK est fourni sous la forme d’un package pypi et donc très facilement installable.
pyenv virtualenv 3.10.8 chatgptpyenv shell chatgptpip install openai rich
J’installe aussi la librairie rich
pour rendre les sorties plus sympathiques.
Notre première demande à l’API de ChatGPT
Après avoir créé un compte sur la plateforme OpenAI, il faut demander la création d’un token.
Le code de test de ma demande à ChatGPT
Maintenant le code minimal pour poser une question à chatGPT
:
#!/usr/bin/env python3
import osimport sysimport openaifrom rich.console import Consolefrom rich import printfrom rich.text import Textfrom rich.markdown import Markdown
openai.api_key = os.getenv("OPENAI_KEY")system_message = "Tu es un expert Ansible."system_user = sys.argv[1]print("Demande envoyé à ChatGPT : %s : %s" % (system_message, system_user))response = openai.ChatCompletion.create( model="gpt-3.5-turbo-0301", messages=[ { "role": "system", "content": system_message, }, {"role": "user", "content": system_user}, ])response = response["choices"][0]["message"]["content"].replace("'", '"')console = Console()print("ChatGPT réponds:")md = Markdown(response)console.print(md)print(response["usage"]["total_tokens"])
Quelques explications :
Dans les messages envoyés, on doit indiquer plusieurs rôles accompagnés de leur contexte :
- le rôle
system
permet de définir le comportement de l’assistant. Dans mon cas, je lui indique qu’il est un expert Ansible. - le rôle
user
les questions que vous envoyez à l’API de ChatGPT avec les instructions à fournir à l’assistant. - le rôle
assistant
qui sera utilisé pour garder l’historique d’une conversation.
Ici, je ne tiendrai pas de conversation avec ChatGPT, donc pas d’appel à l’assistant.
On lui pose notre première question
On lui pose la première question :
./test.py "Quelle module Ansible utiliser pour copier un fichier du controler sur la cible avec les droits 755"Demande envoyé à ChatGPT : Tu es un expert Ansible. : Quelle module Ansible utiliser pour copier un fichier du controler sur la cible avec lesdroits 755ChatGPT réponds:Pour copier un fichier du controler sur la cible avec les droits 755, vous pouvez utiliser le module "copy" d"Ansible.
Voici un exemple de tâche Ansible utilisant le module "copy" pour copier un fichier nommé "mon_script.sh" du controler vers la cible :
- name: Copier le script sur la cible avec les droits 755 copy: src: /chemin/vers/mon_script.sh dest: /chemin/vers/mon_script.sh mode: 755
Dans cet exemple, le fichier source est situé sur le controler dans le répertoire "/chemin/vers/" et est nommé "mon_script.sh". Le fichier seracopié vers la cible dans le même chemin et sera défini avec les droits 755 (rwxr-xr-x).Tokens utilisés 236
Sympa la réponse non ?
- Mais il ne respecte pas les bonnes pratiques définies. Comment le guider alors ?
- Et il est bavard non ? Si on commençait par lui demander que la réponse.
Rendre moins bavard
En fait, c’est assez simple. Il suffit d’ajouter dans le contexte `system.
system_message = "Tu es un expert Ansible. Ne commente pas la réponse!"
On relance :
ChatGPT réponds:Le module Ansible à utiliser est copy. Il faut définir les options src, dest et mode pour copier le fichier avec les droits 755. Voici un exemple de tâche Ansible qui utilise le module copy :
- name: Copier un fichier avec les droits 755 copy: src: /chemin/vers/fichier dest: /chemin/vers/destination mode: "0755"Tokens utilisés 154
Mince, il ne peut s’empêcher de parler. Par contre, vous remarquez que du coup, on a utilisé moins de tokens.
Lui demander de répondre en JSON
On peut lui demander de la formater la réponse en JSON, plus simple à
interpréter que du yaml
. On modifie notre contexte system
:
system_message = "Tu es un expert Ansible. Réponds en JSON. Ne commente pas la réponse! JSON:"
On relance :
./test.py "Quelle module Ansible utiliser pour copier un fichier du controler sur la cible avec les droits 755"Demande envoyé à ChatGPT : Tu es un expert Ansible. Réponds en JSON. Ne commente pas la réponse! JSON: : Quelle module Ansible utiliser pour copier un fichier du controler sur la cible avec les droits 755ChatGPT réponds:{"module": "copy", "src": "/chemin/vers/fichier/source", "dest":"/chemin/vers/fichier/destination", "mode":"0755"}Tokens utilisés 94
Cette fois, c’est la bonne. Pas de commentaire juste un JSON, mais inexploitable.
Demander à ChatGPT de respecter les bonnes pratiques
Je suis un adepte de l’utilisation des FQCN Ansible. Le module copy
doit être
invoqué avec ansible.builtin.copy
.
On modifie cette fois notre demande user
:
./test.py "Quelle module Ansible utiliser pour copier un fichier du controler sur la cible avec les droits 755. Utilise les FQCN des modules Ansible "Demande envoyé à ChatGPT : Tu es un expert Ansible. Réponds en JSON. Ne commente pas la réponse! JSON: : Quelle module Ansible utiliser pour copier un fichier du controler sur la cible avec les droits 755. Utilise les FQCN des modules AnsibleChatGPT réponds:{ "module": "ansible.builtin.copy", "args": { "src": "chemin/du/fichier/src", "dest": "chemin/du/fichier/dest", "mode": "755" } }Tokens utilisés 123
Pas génial car inexpoitable : il a mis modules
. C’est de ma faute, il faut lui
dire de créer des taches.
Demander à chatGPT de produire un ensemble de taches
Allez on lui demande d’écrire les taches Ansible pour installer les packages net-tools
et nginx, ensuite de
copier notre fichier :
./test.py "Ecris des taches Ansible pour installer les packages net-tools, nginx avec le module package puis copier un fichier du controler sur la cible avec les droits 755. Utilise les FQCN des modules Ansible "Demande envoyé à ChatGPT : Tu es un expert Ansible. Réponds en JSON en utilisant les FQCN Ansible. Ne commente pas la réponse! JSON: : Ecris destaches Ansible pour installer les packages net-tools, nginx avec le module package puis copier un fichier du controler sur la cible avec les droits755. Utilise les FQCN des modules AnsibleChatGPT réponds:{ "tasks": [ { "name": "Installer net-tools", "package": { "name": "net-tools", "state": "present" } }, { "name": "Installer nginx", "package": { "name": "nginx", "state": "present" } }, { "name": "Copier fichier avec droits 755", "copy": { "src": "/chemin/vers/fichier", "dest": "/destination/fichier", "mode": "755" } } ]}Tokens utilisés 226
Pas mal du tout non ? Mince, il a oublié de respecter ma demande d’utilisation d’un FQCN.
Je relance dés fois que :
{ "hosts": "cible", "tasks": [ { "name": "Installation des packages net-tools et nginx", "package": { "name": ["net-tools", "nginx"], "state": "present" } }, { "name": "Copie du fichier du controler avec les droits 755", "copy": { "src": "/chemin/du/fichier", "dest": "/chemin/de/destination", "mode": "0755" } } ]}
Cette fois, il m’a créé un playbook avec deux taches dont deux installations de
packages avec le module yum
et non plus apt
.
Ajustement de la température
Il existe un réglage qui permet de contrôler le côté créativité de chatGPT, c’est la température. Une température à 0 rend le moteur déterministe, ce qui signifie qu’il retournera toujours la même sortie pour une demande donnée. Tandis qu’avec une valeur de 1, il prendra plus de liberté.
Notre code devient :
response = openai.ChatCompletion.create( model="gpt-3.5-turbo-0301", messages=[ { "role": "system", "content": system_message, }, {"role": "user", "content": system_user}, ], temperature = 0)
On relance plusieurs fois :
./test.py "Ecris des taches Ansible pour installer les packages net-tools, nginx avec le module package puis copier un fichier du controler sur la cible avec les droits 755. Utilise les FQCN des modules Ansible "Demande envoyé à ChatGPT : Tu es un expert Ansible. Réponds en JSON en utilisant les FQCN Ansible. Ne commente pas la réponse! JSON: : Ecris des taches Ansible pour installer lespackages net-tools, nginx avec le module package puis copier un fichier du controler sur la cible avec les droits 755. Utilise les FQCN des modules AnsibleChatGPT réponds:{ "tasks": [ { "name": "Install net-tools package", "package": { "name": "net-tools", "state": "present" } }, { "name": "Install nginx package", "package": { "name": "nginx", "state": "present" } }, { "name": "Copy file with 755 permissions", "copy": { "src": "/path/to/local/file", "dest": "/path/to/remote/file", "mode": "0755" } } ]}Tokens utilisés 228
Je l’ai relancé une dizaine de fois et à chaque fois, il a retourné le même résultat.
Conclusion
Vous remarquez que :
- le code retourné n’est pas forcément le plus optimisé
- qu’il est compliqué de lui demander de respecter les bonnes pratiques Ansible.
Dans tous mes tests, je pensais avoir résolu mon problème pour un cas d’usage, mais si je relance sur une question précédente. Bim ça ne fonctionne plus ?
Mais alors comment l’exploiter pour obtenir des réponses plus fiables ?
C’est à partir de ce constat que je me suis dit. Pourquoi lui demander plusieurs
tâches ? Pourquoi pas lui fournir un template
avec les options attendues ?
Ce sera la seconde partie de ce sujet. Je vais utiliser mon système de
génération de snippets vscode
pour
ajouter à ma demande un template
du module demandé.