RAG + Balisage Sémantique

Autres langues : English Español Deutsch 日本語 한국어 Português 中文

L’importance de la documentation varie selon les projets logiciels, mais même la documentation la plus importante joue un rôle intrinsèquement auxiliaire. Ce n’est pas quelque chose sur lequel un programme s’appuie pour fonctionner correctement. Même lorsque la documentation partage des données avec le programme, la connexion reste unidirectionnelle. La documentation destinée aux utilisateurs reflète le produit et ne change pas la façon dont le produit fonctionne.

La raison principale en est purement technologique. Nous pourrions implémenter de nouvelles fonctionnalités et corrections simplement en écrivant de la documentation – si les instructions en langage naturel pouvaient être suffisamment précises, et que les ordinateurs excellaient à les interpréter. Cela vous semble familier, n’est-ce pas ?

Alors que le débat continue sur la possibilité de programmer entièrement en langage naturel, ce changement potentiel concerne en réalité l’accessibilité du développement logiciel, plutôt que l’introduction d’une nouvelle façon de faire fonctionner les programmes. En fin de compte, nous obtiendrions toujours les mêmes binaires, maintenant avec un compilateur supplémentaire, certes remarquable, impliqué.

L’IA peut-elle piloter des fonctionnalités d’une manière différente ? Aujourd’hui, j’aimerais couvrir l’une des fonctionnalités récentes pilotées par l’IA dans les IDE JetBrains, qui exploite directement le traitement du langage naturel, transformant une grande partie de notre documentation en un atout de développement extrêmement utile.

Recherche d’actions

À partir de la version 2024.3, AI Assistant dans les IDE JetBrains a accès aux actions de l’IDE et vous aide à trouver l’action appropriée pour le problème en question. De plus, il peut exécuter cette action pour vous :

L'Assistant IA suggère une fonctionnalité de l'IDE et affiche un bouton pour lancer l'action correspondante L'Assistant IA suggère une fonctionnalité de l'IDE et affiche un bouton pour lancer l'action correspondante

Comme mentionné précédemment, cette fonctionnalité est pilotée par la documentation. Bien que le bon vieux code joue certainement un rôle, la sélection de l’action correcte repose exclusivement sur une forme avancée de RAG (génération augmentée par récupération) – sans avoir besoin de nombreuses fonctions LLM ou de mappages spéciaux.

Avant de passer aux détails, revoyons brièvement le concept de RAG.

RAG

La génération augmentée par récupération (RAG) est une technique couramment utilisée pour améliorer la précision et l’ancrage des réponses des LLM. Elle est particulièrement efficace lorsque les LLM doivent donner des réponses sur des sujets au-delà de leurs données d’entraînement et des faits qui changent fréquemment, rendant le fine-tuning impraticable.

Dans sa forme la plus courante, la technique consiste à maintenir un index sur la documentation. Dans cet index, la clé reflète la signification d’un élément du document, représentée par des embeddings, et la valeur correspond au contenu de l’élément ou à une référence à l’élément lui-même. Grâce à la représentation numérique des clés, les éléments correspondants peuvent être comparés et récupérés sémantiquement en utilisant des méthodes telles que la similarité cosinus ou les k plus proches voisins (KNN).

Le diagramme de l'index sémantique - embeddings comme clé, contenu comme valeur Le diagramme de l'index sémantique - embeddings comme clé, contenu comme valeur

Voici ce qui se passe lorsque vous posez une question dans un chat IA assisté par RAG :

How do I change font size?

Le système recherche d’abord dans l’index, et si cela réussit, ajoute les résultats au prompt. Par exemple :

How do I change font size?
Here's supplementary information that might help you answer the question:
-> the search results are inserted here <-

Avec cette approche, la réponse correcte peut probablement être déduite des informations complémentaires fournies, résultant en une réponse plus informée et précise du LLM. Du point de vue de l’utilisateur final, il peut sembler que le modèle soit devenu plus intelligent, alors qu’en réalité le modèle reste inchangé – la seule différence réside dans le prompt.

Voyons maintenant comment nous pouvons améliorer cette approche.

Balisage sémantique

Si vous écrivez de la documentation technique, vous êtes probablement familier avec le concept de balisage sémantique :

Avec le balisage sémantique, vous spécifiez la “signification” derrière chaque élément

Par exemple, Markdown n’est pas sémantique. En Markdown, vous travaillez avec des éléments de document courants tels que les titres, les paragraphes, les listes, etc., en plus de certaines propriétés typographiques. Cette syntaxe définit une structure de haut niveau et indique au processeur comment rendre le document. Ce qu’elle ne dit pas, c’est le but, ou la signification, des différents éléments dans le document.

Voici un bref exemple. Les astérisques indiquent au processeur qu’il doit mettre la phrase en italique, similaire à ce que <i> signifie en HTML :

*Look both ways before crossing the street!*

En revanche, MDX, un sur-ensemble de Markdown, possède des propriétés sémantiques. MDX vous permet de définir des éléments personnalisés, qui représentent souvent des composants d’interface utilisateur et peuvent communiquer l’intention du contenu :

<Warning>
    Look both ways before crossing the street!
</Warning>

Contrairement au Markdown standard, cet exemple MDX spécifique abstrait l’aspect visuel et se concentre sur l’objectif du contenu à la place. En tant qu’auteurs de documentation, nous nous soucions moins de savoir si <Warning> devrait utiliser l’italique ou se distinguer autrement du texte normal. Son style est défini dans un endroit séparé, comme dans le composant lui-même ou une feuille de style CSS. Cette séparation des préoccupations rend le code plus facile à maintenir et vous permet de modifier le style de manière centralisée en fonction de la signification du contenu.

Une correspondance parfaite ?

Chez JetBrains, nous rédigeons notre documentation avec Writerside. Cet outil prend en charge à la fois Markdown et le XML sémantique comme formats source pour la documentation. L’exemple ci-dessous montre une structure de document typique écrite en XML sémantique de Writerside :

<chapter title="Testing" id="testing">

    ... some content ...

    <procedure title="Navigate to tests" type="choices">
        <p>
            When at a symbol declaration, you can navigate to the corresponding
            tests by doing one of the following:
        </p>
        <step>
            From the main menu, select <ui-path>Navigate | Test</ui-path>.
        </step>
        <step>
            Press <shortcut key="GotoTest"/>.
        </step>
    </procedure>

    ... more content ...

</chapter>

Vous remarquerez qu’il y a des méta-informations dans l’extrait fourni. C’est déjà précieux pour les raisons mentionnées ci-dessus, mais rien ne nous empêche de les utiliser à d’autres fins.

Considérez la balise <shortcut> , qui représente une combinaison de touches dépendante de la plateforme. Cette balise fait partie d’une couche d’indirection qui permet de gérer et de valider les mentions de raccourcis de manière centralisée.

Pour insérer un raccourci dans un document, vous utilisez la balise <shortcut> avec l’ID d’action correspondant comme ceci : <shortcut key="CoolAction"> . Pendant le processus de build, l’outil valide et transforme les éléments <shortcut> en combinaisons de touches réelles pour les keymaps disponibles.

Cette approche synchronise les raccourcis entre la documentation et le produit, et donne également aux utilisateurs de la documentation la flexibilité de choisir leur keymap préférée. Pour voir cela en action, visitez l’aide d’IntelliJ IDEA et notez comment les raccourcis changent dans le texte en fonction de la keymap sélectionnée dans le menu Shortcuts :

Page d'aide d'IntelliJ IDEA avec le menu 'Shortcuts' dans l'en-tête de la page Page d'aide d'IntelliJ IDEA avec le menu 'Shortcuts' dans l'en-tête de la page

C’est l’objectif principal de la balise <shortcut> . Comment cette balise peut-elle être bénéfique en termes d’amélioration du RAG ?

L’utilisation la plus directe est d’afficher les raccourcis spécifiques à la plateforme dans le chat IA, tout comme sur la page d’aide :

L'assistant IA affiche le raccourci correct pour la plateforme L'assistant IA affiche le raccourci correct pour la plateforme

Cependant, il y a une partie plus intéressante. Similaire à la construction d’index pour récupérer des faits et des instructions, il est possible de construire des index qui permettent la recherche d’ID d’action.

Dans le scénario RAG plus simple discuté précédemment, nous avons généré les embeddings à partir du même élément destiné à la récupération. Cependant, pour l’index des ID d’action, nous utiliserons la structure suivante :

Le diagramme de l'index des 'ID d'action' – les clés sont des embeddings, les valeurs sont des ID d'action Le diagramme de l'index des 'ID d'action' – les clés sont des embeddings, les valeurs sont des ID d'action

Dans l’exemple, l’élément englobant pour <shortcut key="GotoTest"/> serait <step> ou même l’intégralité de <procedure> :

<procedure title="Navigate to tests" type="choices">
    <p>
        When at a symbol declaration, you can navigate to the corresponding
        tests by doing one of the following:
    </p>
    <step>
        From the main menu, select <ui-path>Navigate | Test</ui-path>.
    </step>
    <step>
        Press <shortcut key="GotoTest"/>.
    </step>
</procedure>

Le contexte est important

Pour démontrer l’importance d’indexer le contenu de l’élément englobant, utilisons la fonctionnalité Set Value d’IntelliJ IDEA comme exemple. Cette fonctionnalité vous permet de mettre à jour les variables pendant que le programme est suspendu en mode débogage.

L’ID de l’action correspondante est SetValue . Cependant, cet ID isolé n’est pas particulièrement descriptif. Étant donné que SetValue et de nombreux autres ID sont des combinaisons de mots plutôt génériques en programmation, une recherche sémantique basée uniquement sur ces ID entraînera une part inacceptable de faux positifs et de faux négatifs. Sans inclure de contexte supplémentaire dans l’index, la tâche devient pratiquement impossible.

En revanche, en établissant la relation entre l’ID d’action et le contenu environnant, nous fournissons à AI Assistant des détails sur la fonctionnalité exacte, ses cas d’utilisation courants et ses limitations. Ces informations augmentent considérablement la précision de la récupération :

L'assistant IA suggère la fonction correcte (Set Value) pour une demande concernant la « Mise à jour d'une variable » L'assistant IA suggère la fonction correcte (Set Value) pour une demande concernant la « Mise à jour d'une variable »

La partie client

Enfin, une fois qu’AI Assistant dispose du bon ID d’action, il peut suggérer cette action et même afficher un bouton pour l’invoquer directement depuis le chat :

L'assistant IA affiche un bouton qui vous permet d'exécuter l'action directement depuis le chat L'assistant IA affiche un bouton qui vous permet d'exécuter l'action directement depuis le chat

Bien sûr, cette partie est légèrement plus complexe que simplement ajouter un bouton à l’interface. Étant donné que les actions de l’IDE dépendent du contexte, des vérifications supplémentaires doivent être implémentées, mais ce sujet est très spécifique au développement de la plateforme IntelliJ et mérite une discussion séparée.

Autres éléments de balisage

Dans cet article, nous nous sommes principalement concentrés sur la fonctionnalité de « recherche d’actions », qui fonctionne en récupérant les ID d’action à partir de la balise <shortcut> de Writerside. Cependant, vous pouvez appliquer les mêmes principes à de nombreux autres types d’éléments dans le balisage sémantique.

Juste un rapide exemple utilisant l’élément ui-path. Cet élément désigne des séries d’éléments d’interface utilisateur, tels que des éléments de menu, qu’il faut parcourir pour accéder à la fonctionnalité décrite.

<step>
    Open the IDE settings (<shortcut key="ShowSettings"/>),
    then navigate to <ui-path>Tools | Terminal</ui-path>.
</step>

Il est tout à fait logique de fournir de longs chemins dans l’aide web, car la navigation directe d’une page web vers le produit n’est généralement pas pratique. D’un autre côté, lorsqu’un utilisateur pose une question à ce sujet dans le produit, il n’y a aucune raison de ne pas afficher la page de paramètres correspondante immédiatement :

L'assistant IA affiche un bouton qui vous permet de naviguer directement vers le menu référencé dans la documentation L'assistant IA affiche un bouton qui vous permet de naviguer directement vers le menu référencé dans la documentation

Résumé

Il y a quelque temps, beaucoup ont imaginé le concept du Web 3.0. L’idée était de faire passer tout le web au balisage sémantique, afin que les machines puissent l’utiliser tout comme les humains. Bien que cela ne se soit pas produit, il est intéressant de voir comment les mêmes idées redeviennent pertinentes, maintenant du point de vue des outils et techniques modernes.

La fonctionnalité que j’ai couverte dans cet article n’est qu’un exemple de la façon dont vous pouvez exploiter vos bonnes pratiques existantes, comme le balisage sémantique, avec les systèmes Gen AI. Il y en a bien d’autres à explorer. Si vous êtes particulièrement intéressé par le RAG, voici une excellente collection de tutoriels sur la génération augmentée par récupération.

Avez-vous apprécié l’article ? Aimez-vous expérimenter avec Gen AI ? Même si mon blog n’a pas de section de commentaires, je serais toujours heureux d’entendre votre point de vue et vos cas d’utilisation, alors n’hésitez pas à me contacter en utilisant les coordonnées dans le pied de page.

À bientôt !

all posts ->