Les LLMs sont très pratiques pour manipuler du langage naturel.
On peut par exemple leur demander de mettre à jour un document à partir d’une nouvelle information disponible.
Le problème de cette démarche, c’est que pour un document de 50 lignes avec une modification sur seulement quelques lignes, le LLM va nous renvoyer l’intégralité du texte modifié.
Cela pose deux problèmes:
- le couts des tokens en sortie est en général 2 fois plus cher que ceux en entrée
- le nombre de tokens généré est beaucoup plus limité que ceux en entrée (4096 pour GPT-4o)
Nous allons donc voir une technique pour économiser de l’argent, limiter la latence et surtout ne pas être limité dans la taille des documents que nous pouvons éditer.
Notre cas d’utilisation concret
Imaginons que nous avons un document listant les différents types de contenus e-learning disponibles sur la plateforme Didask:
Sur la plateforme Didask, les différents types de contenu sont les suivants:
- Mise en situation: contextualisation d'une connaissance dans une situation concrète
- Débat: deux personnes discute de la connaissance
- QCM: un maximum de 3 questions sur la connaissance
- Image interactive: une image avec des zones à découvrir
- Vidéo: vidéo explicative de la connaissance
Suite à une mise à jour de la plateforme, la Product Manager rédige une note de version à destination des équipes et des clients:
Note de mise à jour du 17/05/2024:
- Le type de contenu "Bloc Audio" est maintenant disponible. Il permet d'ajouter un fichier audio qui sera lu à l'apprenant
- Le QCM peut maintenant contenir jusqu'Ã 6 questions
Notre objectif est de modifier le document décrivant les différents types de contenus avec la note de mise à jour.
Modification programmatique
Si l’on demandait à un programme fictif de modifier ce document, il pourrait s’y prendre de la manière suivante:
- Ajouter une ligne pour référencer le type de contenu « Bloc Audio »
- Modifier ligne type de contenu « QCM »
On peut décrire l’ensemble des opérations nécessaires pour modifier un document avec 3 fonctions:
insertLineAfte
r: ajoute une ligne de texte après la ligne sélectionnéereplaceLine
: remplace la ligne sélectionnée avec un nouveau contenudeleteLine
: supprime la ligne sélectionnée
« L’enfer, c’est les lignes »
Le problème des lignes c’est que leur position dans le document change en fonction des actions précédentes.
Si vous avez un document de 50 lignes et que vous voulez:
- insérer une ligne après la ligne 42
- supprimer la ligne 45
Votre programme devra prendre en compte le fait qu’après avoir insérer une ligne après la ligne 42, la ligne 45 que l’on est sensé supprimé est maintenant la ligne 46 !
Rien de bien sorcier avec du code, c’est ce que fait Git assez facilement mais pour un LLM c’est une autre paire de manches.
On va donc transformer notre texte pour que le LLM puisse manipuler facilement les lignes sans effet de bord: on va le convertir dans un format HTML très simplifié.
Chaque ligne sera dans une balise <p>
avec un id
défini.
<p id="line-1">Sur la plateforme Didask, les différents types de contenu sont les suivants:</p>
<p id="line-2"></p>
<p id="line-3">- Mise en situation: contextualisation d'une connaissance dans une situation concrète</p>
<p id="line-4">- Débat: deux personnes discute de la connaissance</p>
<p id="line-5">- QCM: un maximum de 3 questions sur la connaissance</p>
<p id="line-6">- Image interactive: une image avec des zones à découvrir</p>
<p id="line-7">- Vidéo: vidéo explicative de la connaissance</p>
Prompt Engineering
Maintenant que notre texte est facilement compréhensible et manipulable sans effet de bord par un LLM, nous allons rédiger un Prompt pour que le LLM génère les opérations nécessaires.
Ce prompt prendra en paramètre le document original et la nouvelle information.
En sortie, on lui demandera du format YAML définissant les fonctions à utiliser pour modifier le document pour intégrer la nouvelle information.
Tu possède un excellent esprit de synthèse.
À partir d'une nouvelle information sur un sujet, je veux que tu modifie un document.
La document original est le suivant:
# BEGIN ORIGINAL DOCUMENT
${originalDocument}
# END ORIGINAL DOCUMENT
La nouvelle information est la suivante:
# BEGIN NEW INFORMATION
${newInformation}
# END NEW INFORMATION
Tu dois modifier le contenu de la document original pour y inclure la nouvelle information.
Manipule les balises <p> pour modifier le contenu.
Tu peux utiliser les fonctions suivantes pour modifier le contenu:
- insertAfter(lineId: string, newLineId: string, content: string): Ajoute une ligne après une ligne existante
- replaceLine(lineId: string, content: string): Met à jour une ligne
- deleteLine(lineId: string): Supprime une ligne
Utilise le format YAML pour appeler ces fonctions, exemple:
```yaml
functions:
- insertLineAfter: ["line-4", "new-line-id", "Nouveau contenu"]
- deleteLine: ["line-5"]
- replaceLine: ["line-7", "Contenu remplacé"]
```
RÉPOND UNIQUEMENT EN UTILISANT LES FONCTIONS CI-DESSUS.
La sortie du LLM va être beaucoup plus courte car elle ne contiendra que la liste des opérations à appliquer:
functions: - insertLineAfter: ["line-7", "line-7.1", "- Bloc Audio: permet de lire un contenu audio à l'apprenant"] - replaceLine: ["line-5", "- QCM: un maximum de 6 questions sur la connaissance"]
Après avoir parsé la sortie au format YAML, on se retrouve avec un tableau de fonction à appliquer.
Il suffit de modifier le document avec une librairie de manipulation du DOM comme Cheerio.
Voila à quoi ressemblerait l’exécution de la fonction insertLineAfter
par exemple:
function executeInsertAfter( document: cheerio.CheerioAPI, { lineId, newLineId, content, }: { lineId: string; newLineId: string; content: string } ) { const targetParagraph = document(`p[id="${lineId}"]`) if (targetParagraph.length === 0) { console.error( `executeInsertAfter: Line with id ${lineId} not found` ) return } const newParagraph = `<p id="${newLineId}">${content}</p>` targetParagraph.after(newParagraph) }
Pour aller plus loin
Cette technique permet à un LLM de modifier efficacement et à moindre cout un texte existant tout en conservant un historique des modifications.
Ces modifications pourraient par exemple être affichées dans une interface pour permettre aux utilisateurs de comprendre de quelle manière le document original a été modifié.
On peut par exemple utiliser Git et le format diff associé qui est très populaire chez les développeurs (il est « caché » mais chaque commit Git contient un fichier de diff)
Laisser un commentaire