La recherche en IA te passionne ?
Les papers et avancées qui comptent, expliqués simplement, chaque soir. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
Récupération Adaptative : Une Nouvelle Approche pour les LLM
Dans le domaine de l'intelligence artificielle, la génération augmentée par récupération, ou RAG, s'impose comme une architecture clé pour les applications en production. Contrairement à une approche qui s'appuierait uniquement sur les données d'entraînement d'un modèle, le RAG intègre des informations pertinentes issues de bases de connaissances externes pour enrichir les réponses générées. L'objectif est de fournir au modèle un contexte pertinent, augmentant ainsi la précision des réponses.
Cependant, un défi majeur se pose : déterminer la quantité exacte de contexte à récupérer pour chaque requête.
Le Coût Caché d'une Récupération Fixe
Prenons l'exemple d'un chatbot interne conçu pour une entreprise. Lorsqu'un utilisateur pose une question simple comme « Quels sont vos horaires d'ouverture ? », le système récupère 10 documents à partir d'une base de données vectorielle, car le pipeline est configuré ainsi :
documents = vectorstore.similarity_search(query, k=10)
Ces documents peuvent inclure des informations variées telles que le manuel de l'employé, les politiques RH, ou encore les directives de sécurité. Pourtant, seule une phrase est nécessaire pour répondre à la question. Imaginez que ce processus se répète pour 50 000 requêtes par jour. La plupart des tokens récupérés sont inutiles pour la réponse finale, mais ils sont néanmoins facturés.
Adapter la Taille de la Récupération à Chaque Requête
Toutes les questions ne nécessitent pas la même quantité de contexte. Considérons deux requêtes différentes :
- Requête 1 : « Quels sont vos horaires d'ouverture ? » Un nombre limité de documents pertinents suffit.
- Requête 2 : « Comparez notre politique de remboursement des soins de santé avec les directives financières de l'année dernière. » Cette demande nécessite plusieurs documents provenant de diverses sources.
Bien que les deux requêtes soient importantes, elles ne devraient pas entraîner la récupération du même volume d'informations.
Vers une Récupération Adaptative
Plutôt que de traiter chaque requête de manière uniforme, les systèmes de production évaluent d'abord la complexité de la question. Les questions simples récupèrent un contexte limité, tandis que les questions plus complexes nécessitent davantage de données. Voici une implémentation simplifiée :
if query_type == "simple":
top_k = 2
elif query_type == "medium":
top_k = 5
else:
top_k = 10
documents = vectorstore.similarity_search(query, k=top_k)
Bien que cette logique soit simple, elle peut réduire considérablement le nombre de tokens inutiles traités sur des millions de requêtes.
Reranking : Prioriser la Qualité
Récupérer davantage de documents ne garantit pas une meilleure qualité de réponse. Les systèmes de production intègrent souvent une étape de reranking, qui filtre les documents récupérés pour ne transmettre que les plus pertinents au modèle :
- Récupérateur → Top 10 Documents → Reranker → Top 3 Documents Pertinents → LLM
Le reranker évalue la pertinence de chaque document et ne transmet que les meilleures correspondances. Cela présente deux avantages majeurs :
- Le modèle traite un nombre réduit de tokens.
- Il reçoit un contexte de meilleure qualité.
Dans de nombreux cas, un nombre réduit de documents améliore la qualité des réponses, car le modèle est moins distrait par des informations non pertinentes.
Insight de Production
De nombreuses équipes investissent du temps à expérimenter avec des modèles d'embedding plus performants. Pourtant, une amélioration significative peut résulter d'une approche plus simple : éviter d'envoyer des documents superflus au modèle. Un contexte plus restreint et plus clair peut souvent améliorer la précision et réduire les coûts.
Inférence par Lots : Optimiser le Traitement des Requêtes
Jusqu'à présent, l'optimisation s'est concentrée sur ce qui est envoyé au modèle de langage. Cependant, l'efficacité du traitement des requêtes est tout aussi cruciale. Cela est particulièrement vrai lorsque votre application d'IA doit gérer un volume élevé de documents, d'e-mails, de descriptions de produits ou d'avis clients chaque heure. À cette échelle, traiter les demandes une par une peut s'avérer coûteux.
Le Coût Caché du Traitement Séquentiel
Imaginons un système de recherche de documents. Avant que les utilisateurs puissent effectuer des recherches, chaque document doit être converti en embedding et stocké dans une base de données vectorielle. Supposons que vous ayez 1 000 documents PDF à indexer. Une approche simple pourrait être :
for document in documents:
embedding = embedding_model.embed(document)
vector_db.insert(embedding)
Bien que cela fonctionne, cela entraîne 1 000 appels API distincts. Chaque demande implique :
- Latence réseau
- Surcharge d'authentification
- Initialisation de la demande
- Traitement de la réponse
Le modèle passe presque autant de temps à gérer les demandes qu'à générer des embeddings.
Une Approche Plus Efficace
Plutôt que d'envoyer les documents individuellement, les systèmes de production les traitent par lots :
batch_size = 100
for i in range(0, len(documents), batch_size):
batch = documents[i:i + batch_size]
embeddings = embedding_model.embed(batch)
vector_db.insert(embeddings)
Ainsi, au lieu de réaliser 1 000 appels API, vous n'en faites que 10. Le nombre de tokens reste quasiment identique, mais l'infrastructure devient bien plus efficace.
Pourquoi le Batching Améliore la Performance
Imaginez commander du café pour votre équipe. Préféreriez-vous faire vingt allers-retours pour commander un café à chaque fois, ou rassembler toutes les commandes et faire une seule visite ? Les deux approches aboutissent au même résultat, mais l'une gaspille beaucoup moins de temps. L'inférence par lots fonctionne de manière similaire. En traitant plusieurs entrées ensemble, le système réduit les frais généraux et améliore le débit.
Où l'Inférence par Lots est la Plus Efficace
Le batching est particulièrement efficace pour les tâches qui ne nécessitent pas de réponse immédiate. Quelques exemples incluent :
- Génération d'embeddings pour de grandes collections de documents
- Indexation de bases de connaissances
- Classification des retours clients
- Résumé hors ligne
- Traitement des tickets de support
- Modération de contenu
Ces tâches se déroulent en arrière-plan, où la rapidité de traitement est plus importante que l'interaction instantanée avec l'utilisateur. Pour les chatbots en temps réel, cependant, le batching est souvent moins adapté, car les utilisateurs s'attendent à des réponses immédiates.






