3 points par GN⁺ 2024-09-22 | 1 commentaires | Partager sur WhatsApp
  • Le RAG utilisé dans l’IA fondée sur la connaissance métier peut perdre du contexte, comme le nom d’une entreprise ou la période concernée, lors du découpage des documents en petits chunks, et ainsi passer à côté d’informations pertinentes
  • Le Contextual Retrieval d’Anthropic consiste à ajouter, devant chaque chunk, une courte description basée sur l’ensemble du document, puis à créer des embeddings et un index BM25 afin de réduire le taux d’échec de la recherche
  • Dans les expériences, les Contextual Embeddings ont réduit le taux d’échec de recherche des chunks top-20 de 5,7 % à 3,7 %, soit 35 %, et la combinaison Contextual Embeddings + Contextual BM25 l’a réduit à 2,9 %, soit 49 %
  • En ajoutant le reranking, les 150 meilleurs candidats sont rescoring pour ne transmettre au modèle que les 20 meilleurs, ce qui réduit le taux d’échec de recherche de 5,7 % à 1,9 %, soit 67 %
  • Si la base de connaissances fait 200 000 tokens ou moins, il est aussi possible de tout placer dans le prompt, mais pour les bases plus volumineuses, il faut évaluer la combinaison Contextual Retrieval + reranking selon chaque cas d’usage

Le contexte documentaire perdu par le RAG

  • Pour qu’un modèle d’IA soit utile dans une tâche donnée, il doit accéder à des connaissances de contexte
    • Un chatbot de support client a besoin des connaissances propres à l’entreprise
    • Un bot d’analyse juridique a besoin de connaissances sur la jurisprudence passée
  • Les développeurs renforcent généralement les connaissances du modèle avec le Retrieval-Augmented Generation (RAG)
    • Il recherche les informations pertinentes dans une base de connaissances
    • Il ajoute les informations récupérées au prompt utilisateur afin d’améliorer la réponse du modèle
  • Le RAG classique peut ne pas retrouver certaines informations pertinentes, car il supprime le contexte lors du découpage des documents en chunks
  • Contextual Retrieval est une méthode qui améliore l’étape de recherche du RAG et peut utiliser deux techniques complémentaires
    • Contextual Embeddings : générer des embeddings à partir de chunks enrichis de contexte
    • Contextual BM25 : créer un index BM25 à partir de chunks enrichis de contexte
    • Cette combinaison réduit le nombre d’échecs de recherche de 49 %, et jusqu’à 67 % lorsqu’elle est combinée au reranking
  • Un cookbook est disponible pour déployer Contextual Retrieval avec Claude

Les prompts longs sont aussi possibles pour les petites bases de connaissances

  • Si la base de connaissances fait 200 000 tokens ou moins, soit environ moins de 500 pages, il est possible de placer toute la base dans le prompt sans RAG
  • Le prompt caching de Claude rend cette approche plus rapide et plus économique
    • Les prompts fréquemment utilisés peuvent être mis en cache entre les appels API
    • La latence peut être réduite de plus de 2×
    • Les coûts peuvent être réduits jusqu’à 90 %
    • Son fonctionnement est décrit dans le prompt caching cookbook
  • Lorsque la base de connaissances grossit, une méthode de recherche plus scalable devient nécessaire : c’est là qu’intervient Contextual Retrieval

Le rôle du RAG classique et de BM25

  • Quand une grande base de connaissances ne tient pas dans la fenêtre de contexte, la solution habituelle est le RAG
  • Le flux de prétraitement du RAG est le suivant
    • Diviser le corpus de documents en petits chunks de texte, généralement de quelques centaines de tokens ou moins
    • Transformer les chunks en embeddings vectoriels porteurs de sens à l’aide d’un modèle d’embedding
    • Stocker ces embeddings dans une base de données vectorielle permettant la recherche par similarité sémantique
  • Au moment de l’exécution, les chunks les plus proches sémantiquement de la requête utilisateur sont recherchés dans la base vectorielle, puis les chunks pertinents sont ajoutés au prompt du modèle génératif
  • Les modèles d’embedding capturent bien les relations sémantiques, mais peuvent manquer les correspondances exactes de chaînes
  • BM25 (Best Matching 25) est une fonction de classement fondée sur la correspondance lexicale, particulièrement efficace pour les requêtes contenant des identifiants uniques ou des termes techniques
    • BM25 repose sur le concept de TF-IDF
    • TF-IDF mesure l’importance d’un mot donné pour un document au sein d’une collection
    • BM25 tient compte de la longueur des documents et applique une fonction de saturation à la fréquence des termes afin d’éviter que les mots courants dominent les résultats
  • Par exemple, dans une base de support technique, si l’on recherche "Error code TS-999", un modèle d’embedding peut trouver des documents génériques sur les codes d’erreur, mais manquer la correspondance exacte "TS-999"
  • BM25 recherche directement cette chaîne et identifie les documents pertinents

Utiliser ensemble embeddings et BM25 dans le RAG

  • Le RAG peut combiner embeddings et BM25 pour récupérer des chunks plus précis
    • Diviser la base de connaissances en petits chunks
    • Générer pour chaque chunk un encodage TF-IDF et un embedding sémantique
    • Utiliser BM25 pour trouver les meilleurs chunks fondés sur une correspondance exacte
    • Utiliser les embeddings pour trouver les meilleurs chunks fondés sur la similarité sémantique
    • Combiner les résultats avec une technique de rank fusion et supprimer les doublons
    • Placer les K meilleurs chunks dans le prompt pour générer la réponse
  • Cette approche équilibre la correspondance exacte des termes et une compréhension sémantique plus large
  • Elle peut s’étendre de manière économique à d’immenses bases de connaissances qui ne tiennent pas dans un seul prompt
  • Mais les systèmes RAG existants ont pour limite de détruire le contexte lorsqu’ils découpent les documents en chunks
  • Un cas typique est une question posée sur une base de connaissances issue de déclarations SEC : "What was the revenue growth for ACME Corp in Q2 2023?"
    • Le chunk pertinent peut ne contenir que "The company's revenue grew by 3% over the previous quarter."
    • Avec ce seul chunk, on ne sait ni de quelle entreprise ni de quelle période il s’agit
    • Il devient difficile d’exploiter la bonne information, aussi bien lors de la recherche que lors de l’utilisation

Le fonctionnement de Contextual Retrieval

  • Contextual Retrieval ajoute en tête de chaque chunk un contexte descriptif propre à ce chunk avant de générer l’embedding et de créer l’index BM25
    • Appliqué aux embeddings, cela donne les Contextual Embeddings
    • Appliqué à l’index BM25, cela donne le Contextual BM25
  • Dans l’exemple de déclaration SEC, le chunk original est le suivant
The company's revenue grew by 3% over the previous quarter.
  • Le chunk contextualisé devient par exemple
This chunk is from an SEC filing on ACME corp's performance in Q2 2023; the previous quarter's revenue was $314 million. The company's revenue grew by 3% over the previous quarter.
  • Des méthodes utilisant le contexte pour améliorer la recherche avaient déjà été proposées
  • Ces méthodes diffèrent de l’approche de Contextual Retrieval, qui ajoute un contexte propre à chaque chunk

Générer le contexte des chunks avec Claude

  • Il n’est pas réaliste de demander à des humains d’annoter manuellement des milliers ou des millions de chunks
  • Anthropic a conçu un prompt demandant à Claude de produire un contexte court et propre à chaque chunk, décrivant chaque chunk à partir du contexte de l’ensemble du document
  • Le prompt utilisé avec Claude 3 Haiku est le suivant
<document>
{{WHOLE_DOCUMENT}}
</document>
Here is the chunk we want to situate within the whole document
<chunk>
{{CHUNK_CONTENT}}
</chunk>
Please give a short succinct context to situate this chunk within the overall document for the purposes of improving search retrieval of the chunk. Answer only with the succinct context and nothing else.
  • Le texte de contexte généré fait généralement 50 à 100 tokens ; il est ajouté devant le chunk, puis utilisé pour la génération des embeddings et de l’index BM25
  • Avec le prompt caching, il n’est pas nécessaire de retransmettre le document de référence pour chaque chunk
    • Le document est mis une fois en cache, puis le contenu déjà mis en cache est référencé
    • En supposant des chunks de 800 tokens, un document de 8k tokens, une instruction de contexte de 50 tokens et un contexte de 100 tokens par chunk, le coût unique de génération des chunks contextualisés est de 1,02 dollar par million de tokens de document

Méthode expérimentale et performances de recherche

  • Les expériences ont été menées sur plusieurs domaines de connaissances, modèles d’embedding, stratégies de recherche et métriques d’évaluation
    • Codebases
    • Romans
    • Articles ArXiv
    • Articles scientifiques
  • Des exemples de questions-réponses pour chaque domaine figurent dans l’Appendix II
  • Le graphique montre les performances moyennes sur tous les domaines de connaissances, avec la meilleure configuration d’embedding, Gemini Text 004, et une recherche top-20 de chunks
  • La métrique d’évaluation est 1 - recall@20
    • Elle mesure la proportion de cas où le document pertinent n’a pas été récupéré parmi les 20 meilleurs chunks
  • Dans l’ensemble des résultats, toutes les combinaisons embedding-source évaluées ont amélioré leurs performances avec la contextualisation
  • Les gains de performance sont les suivants
    • Contextual Embeddings : réduction du taux d’échec de recherche des chunks top-20 de 5,7 % → 3,7 %, soit 35 %
    • Contextual Embeddings + Contextual BM25 : réduction du taux d’échec de recherche de 5,7 % → 2,9 %, soit 49 %

Points à prendre en compte pour l’implémentation

  • Les frontières de chunks peuvent influencer les performances de recherche
    • Taille des chunks
    • Frontières des chunks
    • Chevauchement des chunks
  • Contextual Retrieval a amélioré les performances avec tous les modèles d’embedding testés, mais l’ampleur du gain peut varier selon le modèle
    • Les embeddings Gemini et Voyage se sont révélés particulièrement efficaces
  • Le prompt générique fourni fonctionne bien, mais un prompt contextualizer personnalisé adapté au domaine ou au cas d’usage peut donner de meilleurs résultats
    • Exemple : inclure un glossary des termes clés définis uniquement dans d’autres documents de la base de connaissances
  • Ajouter davantage de chunks dans la fenêtre de contexte augmente la probabilité d’inclure l’information pertinente
    • Mais plus il y a d’informations, plus le modèle peut se disperser, ce qui pose une limite
    • Lors de tests avec 5, 10 et 20 chunks transmis, 20 chunks ont donné les meilleures performances
    • Dans les cas d’usage réels, des expérimentations sont nécessaires
  • Pour la génération de réponse, transmettre les chunks contextualisés et distinguer ce qui relève du contexte de ce qui relève du chunk original peut améliorer les résultats
  • Il faut toujours lancer une évaluation

Améliorer encore avec le reranking

  • Le reranking est une technique de filtrage qui, dans les grandes bases de connaissances, ne transmet au modèle que les chunks les plus pertinents parmi les candidats récupérés lors de la première recherche
  • Cette étape réduit la quantité d’informations traitée par le modèle et peut donc affecter la qualité de réponse, le coût et la latence
  • La procédure est la suivante
    • Récupérer avec la recherche initiale les meilleurs chunks potentiellement pertinents
    • Dans les expériences, top 150 a été utilisé
    • Transmettre les N meilleurs chunks et la requête utilisateur au modèle de reranking
    • Le modèle de reranking attribue à chaque chunk un score de pertinence et d’importance
    • Sélectionner les K meilleurs chunks
    • Dans les expériences, top 20 a été utilisé
    • Placer les chunks sélectionnés dans le contexte du modèle pour générer le résultat final
  • Les expériences ont été menées avec le reranker de Cohere
  • Il existe aussi le reranker de Voyage, mais il n’a pas pu être testé faute de temps
  • L’ajout d’une étape de reranking dans différents domaines optimise davantage la recherche
  • Reranked Contextual Embedding + Contextual BM25 réduit le taux d’échec de recherche des chunks top-20 de 5,7 % → 1,9 %, soit 67 %

Équilibrer coût et latence

  • Le reranking ajoute une étape à l’exécution, et introduit donc inévitablement une légère latence supplémentaire
  • Même si le modèle de reranking score tous les chunks en parallèle, l’impact sur la latence et le coût doit être pris en compte
  • Reranker davantage de chunks peut améliorer les performances, mais augmente le coût et la latence
  • Reranker moins de chunks réduit le coût et la latence, mais peut diminuer les gains de performance
  • Le bon équilibre doit être trouvé en expérimentant plusieurs configurations pour chaque cas d’usage

Résultats une fois les techniques combinées

  • Plusieurs combinaisons ont été comparées sur différents types de jeux de données : modèle d’embedding, utilisation ou non de BM25, utilisation ou non de Contextual Retrieval, utilisation ou non du reranking, et nombre top-K de résultats récupérés
  • Le résumé des résultats est le suivant
    • Embeddings + BM25 fait mieux que les embeddings seuls
    • Parmi les embeddings testés, Voyage et Gemini sont les meilleurs
    • Transmettre les chunks top-20 au modèle est plus efficace que top-10 ou top-5
    • Ajouter du contexte aux chunks améliore fortement la précision de recherche
    • Le reranking donne de meilleurs résultats que l’absence de reranking
    • Pour maximiser les gains de performance, on peut combiner des Contextual Embeddings fondés sur Voyage ou Gemini, Contextual BM25, une étape de reranking et l’ajout de 20 chunks au prompt
  • Les développeurs peuvent expérimenter cette approche avec le Contextual Retrieval cookbook

1 commentaires

 
GN⁺ 2024-09-22
Avis sur Hacker News
  • Nous construisons un RAG d’entreprise pour des organismes publics. Après des tests A/B expérimentaux avec les métriques RAGAS, sur la base de questions d’évaluation synthétiques, ajouter un reranking basé sur un LLM après une recherche hybride (recherche sémantique + vecteurs) n’a pas beaucoup changé les résultats, et HyDE a fortement dégradé la qualité des réponses comme celle de la recherche.
    Il nous reste encore à faire davantage d’évaluations RAGAS avec des questions d’experts et de vraies questions d’utilisateurs.
    Donc, dans un RAG de production/entreprise, dire que la recherche hybride est toujours préférable n’est pas vraiment nouveau, mais aucune méthode ne gagne systématiquement. Dans notre cas, en complément de la similarité vectorielle, la recherche sémantique d’Azure AI Search suffisait comme seconde méthode. Ailleurs, BM25 ou un petit modèle de langage affiné pour le post-traitement des requêtes peut être préférable ; au final, il faut continuer à tester selon chaque cas d’usage.
    Ensuite, nous prévoyons d’essayer RAPTOR, SelfRAG, le RAG agentique, l’amélioration des requêtes (expansion et sous-requêtes) et GraphRAG.
    La leçon jusqu’ici est qu’il faut définir une base de référence et un groupe expérimental, chercher à réfuter l’hypothèse nulle avec des métriques comme RAGAS, et utiliser trois types de questions/réponses d’évaluation : des Q&A rédigées par des experts, de vraies questions d’utilisateurs issues des logs, et des Q&A synthétiques générées à partir des documents sources.

    • Pourrais-tu expliquer les acronymes que tu as utilisés dans ton commentaire, ou donner des liens qui les expliquent ?
    • Je me demande ce que tu penses de HippoRAG. L’as-tu déjà essayé, ou comptes-tu le faire ?
  • Ce que je préfère dans cette approche, c’est qu’elle exploite bien le prompt caching.
    Les prompts mis en cache coûtent généralement environ 1/10 du prix habituel ; auparavant, une astuce consistant à traiter tous les chunks avec l’intégralité du document source n’avait aucun sens économiquement, mais elle devient désormais possible.
    Grâce à la réduction des coûts liée au caching, je pense que davantage de techniques intéressantes de ce genre vont devenir viables.
    Note sur la recherche contextuelle : https://simonwillison.net/2024/Sep/20/introducing-contextual... et note sur le prompt caching : https://simonwillison.net/2024/Aug/14/prompt-caching-with-cl...

    • Je suis ton blog et je lis quasiment tous tes articles liés aux LLM. Je me demande à combien s’élève le coût mensuel pour explorer plusieurs LLM et leurs fonctionnalités.
      Ce serait un contexte utile pour se faire une idée de ce qu’il faut dépenser afin de suivre les modèles et fonctionnalités les plus récents.
    • On peut pré-calculer beaucoup de choses pour les embeddings. Pas besoin de les mettre en cache : il suffit de les pré-calculer, ce qui permet d’importer beaucoup de techniques classiques d’ETL.
      Vu depuis un contexte de recherche traditionnelle, limiter le RAG aux seuls modèles d’embedding prêts à l’emploi et à la recherche vectorielle semble être une stratégie assez naïve. La recherche vectorielle n’est pas si bonne en elle-même, et il faut des stratégies supplémentaires de recherche d’information pour améliorer le contexte fourni au LLM. C’est essentiellement ce qui est fait ici.
      Microsoft a publié il y a quelque temps un article sur Graph RAG, qui combine RAG et recherche vectorielle à partir d’un graphe conceptuel construit par extraction d’entités dans les données indexées. Cela permet de faire remonter des informations contextuellement liées aux chunks correspondants.
      J’ai l’impression qu’on peut aller assez loin sans recherche vectorielle. Le coût devient aussi nettement plus faible. Il suffit d’utiliser un moteur de recherche traditionnel et des requêtes bien ajustées. Bien sûr, le point clé est le réglage des requêtes, et cela peut mal convenir aux cas génériques, mais fonctionner pour des cas plus spécialisés.
    • Le coût est un aspect, mais qu’en est-il du temps d’ingestion ? Cette méthode n’ajoute-t-elle pas un temps de traitement considérable au pipeline ?
  • Pour donner un peu de contexte, cette approche n’est pas si nouvelle. L’une des méthodes courantes pour améliorer les résultats d’un RAG consiste à « étendre » les chunks de base avec un LLM afin d’augmenter la surface sémantique susceptible de correspondre.
    On peut encore améliorer les choses en faisant de l’expansion de requête avec HyDE[1], mais comme ce n’est pas toujours meilleur, je l’utilise comme chemin alternatif.
    Je ne vois pas très bien ce qu’Anthropic apporte de nouveau ici. En regardant le code du cookbook, il montre seulement le processus de création de ce contexte, et rien n’a vraiment changé dans l’API pour la « recherche contextuelle ».
    Ce qui a changé, c’est le prompt caching introduit il y a un mois, qui permet de fournir l’ensemble d’un long document comme contexte afin d’ajouter, à très bas coût, un meilleur contexte à chaque chunk individuel. Le caching est une excellente fonctionnalité à mettre à disposition des développeurs, et j’en reconnais la valeur.
    Mais à part cela, il me semble que ce n’est qu’un cookbook montrant un workflow RAG précis.
    À propos, Cohere fait partie des API que j’ai le plus appréciées. Je n’y suis pas affilié, et la Cohere RAG API était vraiment très bonne par rapport aux autres fournisseurs. Je la recommande vivement.
    1: https://arxiv.org/abs/2212.10496

    • L’innovation semble résider dans l’utilisation du caching pour rendre le coût de cette approche supportable. L’implémentation consiste à demander au LLM, à chaque création de chunk, de produire un chunk atomique à partir de l’ensemble du contexte.
      Si les données contiennent des dizaines de milliers de chunks, il faut faire cela pour chacun, ce qui coûte cher. Mettre le document en cache permet de réduire ce coût.
    • Il y a environ un mois, j’ai voulu faire cela avec Prompt Caching, mais j’ai découvert que la durée de vie maximale d’un prompt mis en cache était de 5 minutes.
      Cela ne correspond pas bien à mes besoins en RAG, et c’est probablement pareil pour la plupart des usages. Une requête peut être exécutée le mois suivant ou un an plus tard. Cette politique ne semble pas avoir changé, donc je trouve un peu surprenant qu’on parle de Prompt Caching à propos du RAG.
  • Nous faisons quelque chose de similaire. Nous commençons par découper les documents en chunks selon les titres h1, h2 et h3, puis nous ajoutons les en-têtes au début du chunk comme contexte
    À titre d’exemple fictif, si le chunk d’origine était « La posologie habituelle chez l’adulte est de 1 à 2 comprimés ou gélules de 200 mg, trois fois par jour », il devient quelque chose comme # Fever, ## Treatment, puis, après une ligne de séparation, le même contenu
    Cela semble plutôt bien fonctionner, et il n’y a même pas besoin de LLM lors de l’indexation des documents

    • Je me suis toujours demandé comment un LLM pouvait savoir qu’un long texte ou la transcription d’un audio avait été écrit par Alan Watts. Ce genre d’annotations de métadonnées devait être courant lors de la préparation des données d’entraînement de modèles comme Llama
      C’est peut-être aussi l’origine de la polémique selon laquelle « ChatGPT est devenu plus lent en décembre » : cette métadonnée de « date » aurait pu indiquer à ChatGPT d’être moins utile
    • Je travaille sur de la question-réponse basée sur de longs documents de plus de 100 pages ou des lots de documents, et j’ai adopté une approche similaire
      Je commence par résumer chaque page, lui donner un titre et extraire la liste des sous-sections. Ensuite, je combine tous les résumés et je demande au modèle de créer un index hiérarchique. Le modèle organise l’ensemble du lot sous forme d’arbre, puis, au moment de la requête, les chemins dans l’arbre sont combinés comme contexte supplémentaire
    • Je serais curieux de savoir si vous avez expérimenté plusieurs formats pour insérer les en-têtes inclus. Je demande parce que je fais quelque chose de similaire
  • Je n’aime pas vraiment cette technique. Je suis d’accord pour dire que le scénario présenté est un problème courant, mais la solution proposée me paraît maladroite
    Les embeddings vectoriels ont une propriété de type compression en sac de mots, et peuvent être surindexés sur le premier bloc de texte avant le saut de ligne. Résultat : certains indices du vecteur se retrouvent beaucoup plus proches de 0 qu’ils ne devraient l’être. Après quantification, ils finissent par devenir 0, ce qui peut faire perdre beaucoup de précision au vecteur dense. La recherche IDF compense dans une certaine mesure, mais pas suffisamment
    Si l’on « booste sémantiquement » les embeddings pour les rapprocher du titre, du résumé, de l’abstract, etc. du document, on peut obtenir le gain en rappel de ce préfixe de « contexte » sans polluer le vecteur de base. Côté implémentation, c’est une somme pondérée. À l’étape d’augmentation, lorsqu’on place le contenu dans la fenêtre de contexte, si le document correspond, on peut aussi injecter le chunk de résumé avec lui. Personnellement, je trouve que c’est une solution beaucoup plus propre
    Description du « semantic boost » dans l’API Trieve[1] :
    semantic_boost : utile pour déplacer le vecteur d’embedding d’un chunk dans la direction d’une expression de distance. Par exemple, si chunk_html vaut iphone, on peut utiliser flagship comme distance_phrase et 0.25 comme distance_factor pour pousser le chunk 25 % plus près du terme « flagship ». Conceptuellement, cela revient à tracer une ligne de distance euclidienne/L2 entre le vecteur innerText de chunk_html et le vecteur de distance_phrase, puis à déplacer le vecteur chunk_html le long de cette ligne, vers le vecteur ou à l’écart de celui-ci, de distance_factorL2Distance
    [1]:https://docs.trieve.ai/api-reference/chunk/create-or-upsert-...

    • Question un peu sortie de nulle part, mais les bases de données vectorielles sont-elles compatibles d’un modèle à l’autre ? D’après ce que je comprends, les embeddings sont propres à chaque modèle, donc j’imagine que non
      Dans ce cas, cela veut-il dire qu’une base vectorielle est liée à un seul LLM, voire à une seule version comme Claude-3.5 Sonnet, qu’on ne peut pas la déplacer vers 3.5 Haiku ou Opus, et qu’il faut réindexer pour passer à ChatGPT ou Llama ?
  • La technique que je trouve la plus utile consiste à implémenter une stratégie de liste chaînée, où un chunk possède plusieurs pointeurs vers des éléments qui le référencent. Je fais cela manuellement, mais cela augmente fortement la diversité des façons de référencer un nœud donné
    Vu autrement, c’est comme les commentaires. Tous les commentaires sous cet article peuvent être considérés comme des pointeurs vers le billet d’origine. Certains commentaires sont sémantiquement proches du billet, d’autres s’en éloignent à cause de la perception de leur auteur. Mais si l’on attribue un parent_id à chaque commentaire, on multiplie les chemins permettant d’accéder au billet d’origine
    On peut voir un exemple de cette technique ici [1]. Il ne s’agit pas d’essayer de deviner quelle requête l’utilisateur final va formuler : on laisse simplement l’utilisateur s’exprimer, puis on indexe cela comme un pointeur. Les options pour représenter un objet sont finies, mais certaines représentations sont très, très, très éloignées du sens de l’objet central
    [1] - https://x.com/yourcommonbase/status/1833262865194557505

  • Pour les petits jeux de données, l’idée selon laquelle il suffit de mettre 200 000 tokens dans le prompt pour obtenir la meilleure réponse ne correspond pas à mon expérience
    Je constate souvent que plus le prompt grossit, plus la cohérence de la sortie diminue, et plus le suivi des instructions se dégrade. Cela semble même se produire avec des longueurs nettement inférieures à 25k tokens. Je serais curieux de savoir si d’autres rencontrent le même problème, et s’il existe des méthodes bien connues pour l’éviter

  • Intéressant. Le problème que je rencontre, ce n’est pas de rechercher des blocs de connaissances avec RAG, mais des règles applicables. Il ne faut injecter dans le contexte que les règles qui peuvent s’appliquer au contexte
    Je n’ai pas encore expérimenté, mais je pense qu’une approche consistant à entraîner un petit classificateur pour déterminer si une règle donnée peut s’appliquer pourrait fonctionner. Le LLM principal aurait alors pour rôle de décider si cette règle s’applique réellement dans le contexte actuel
    Par exemple, supposons qu’on joue à un jeu de donjon multi-utilisateur avec un LLM. Imaginons qu’auparavant, un personnage ait mal agi en lien avec un taxi, et que le jeu ait créé la règle suivante : « chaque fois qu’il essaie de monter dans un taxi, il en est expulsé. “Nous savons qui vous êtes, et nous ne vous accepterons pas comme client tant que vous n’aurez pas présenté des excuses officielles au directeur de la compagnie de taxis.” » Si le personnage s’excuse, la règle est supprimée. Le directeur de la compagnie de taxis pourrait être un autre joueur, ou la personne qui a déclenché en premier la règle que sa flotte de taxis NPC doit faire respecter
    Je me demande dans quelle mesure cela passerait à l’échelle en fonction du nombre de règles actives, et jusqu’où on pourrait appliquer le RAG traditionnel. Déterminer si une règle s’applique semble être un problème plus abstrait et plus difficile que de déterminer si un bloc de connaissances est pertinent
    Ce qui rend la chose particulièrement plus difficile, c’est une boucle de dépendance qu’on ne trouve pas dans la recherche de connaissances. Pour identifier si une règle s’applique, il faut d’abord récupérer cette règle. Comment pourrait-on résoudre ce problème ?

    • Si le contexte en jeu est correctement décrit dans la requête, la recherche vectorielle traditionnelle utilisée dans le RAG semble convenir aussi dans ce cas
      Une requête d’exemple, rédigée avec l’aide de LLama 3.1 8B, pourrait être suffisamment détaillée : l’armée des elfes noirs approche, Grimgold Ironfist se trouve dans une situation désespérée, il était autrefois un fier membre de la milice naine mais n’a plus que 35 % de points de vie, son inventaire contient une vieille pioche, un seau d’eau, du pain rassis et 17 pièces d’or, et malgré son « passé problématique » avec la guilde des taxis, il essaie d’arrêter un taxi sur la route
      L’exemple de règle à récupérer depuis la base vectorielle le serait grâce à la proximité vectorielle créée par le nom/les attributs du personnage ainsi que par les mentions de taxi et de Taxi Guild
      Ce serait une règle du type : « La Taxi Guild a imposé une sanction stricte à Grimgold. Chaque fois qu’il tente d’arrêter un taxi, il est immédiatement expulsé du véhicule. L’édit de la Guild stipule : “Grimgold Ironfist, nain barbu de mauvaise réputation, n’est autorisé à monter dans aucun taxi exploité par nos membres tant qu’il n’aura pas présenté des excuses officielles à Thorgrim Stonebeard, directeur de la Golden Horse Cab Company. Tout manquement à cette règle entraînera son exclusion définitive de nos services.” »
  • Il est écrit « si la base de connaissances fait moins de 200 000 tokens (environ 500 pages) » ; j’aimerais qu’Anthropic publie simplement son tokenizer, pour qu’on n’ait pas à deviner

    • Comme les réponses sont streamées token par token, est-ce qu’on ne pourrait pas faire de la rétro-ingénierie ?
  • J’attends le jour où toute l’industrie de l’IA aura fait un tour complet pour finalement revenir à TF-IDF

    • Oui, ça m’a aussi fait un peu sourire. Des produits comme elasticsearch prennent de toute façon en charge par défaut les algorithmes classiques de correspondance de texte, non ?