0Pricing
AI Prompt Engineering · Leçon

Au-delà du RAG naïf

Les limites de la récupération de base.

Au-delà du RAG naïf est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Prompt Engineering, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Prompt Engineering comprend 4 leçons au total.

Ce que fait le RAG naïf

RAG naïf est la référence de base : découper les documents en segments, les vectoriser, stocker les vecteurs, vectoriser la requête, récupérer les k premiers selon la similarité cosinus, insérer les segments dans l’invite et générer. C’est un excellent point de départ, qui échoue de manière prévisible à grande échelle.

Comprendre ces modes d’échec est une condition préalable aux techniques avancées (reclassement, compression, réécriture de requête) étudiées dans ce cours.

def naive_rag(query, k=5):
    q = embed(query)
    chunks = vector_store.search(q, k)        # top-k by cosine
    context = '\n\n'.join(c.text for c in chunks)
    return llm('Context:\n' + context + '\n\nQ: ' + query)

Rappel et précision de la récupération

La récupération naïve des k premiers optimise la similarité vectorielle brute, qui confond pertinence et proximité sémantique apparente. Vous êtes confronté à un compromis : une petite valeur de k risque de manquer la réponse (rappel faible) ; une grande valeur de k sature le contexte d’éléments distracteurs (précision faible).

La similarité des représentations vectorielles qui commande la récupération n’est qu’une approximation grossière de la véritable pertinence et se trouve à l’origine de plusieurs problèmes en aval.

# The core dilemma
# small k -> may miss the gold chunk (recall problem)
# large k -> distractors crowd context (precision + cost problem)
# Advanced RAG decouples 'retrieve many' from 'use few'

Le problème de décalage des représentations vectorielles

Les requêtes et les documents appartiennent souvent à des registres linguistiques différents : une question courte face à un long passage déclaratif. Les représentations vectorielles de bi-encodeurs peuvent placer une réponse pertinente loin de la question parce que leur formulation diffère (le problème de décalage du vocabulaire).

C’est ce qui motive des techniques comme la réécriture de requête et HyDE, qui remodèlent la requête pour l’adapter à l’espace des documents avant la récupération.

# Query:  'how do I revoke a token?'
# Doc:    'Token invalidation is performed via the /sessions endpoint.'
# Lexically and semantically distant -> bi-encoder may miss it
sim = cos(embed('how do I revoke a token?'),
          embed('Token invalidation via /sessions'))  # may be low

Perdu au milieu

Même lorsque le bon segment est récupéré, l’insertion de nombreux segments déclenche l’effet du contenu perdu au milieu : le modèle accorde moins d’attention au contenu placé au centre d’un long contexte. Un segment correct enfoui au troisième rang sur dix peut être effectivement ignoré.

Cela motive le reclassement (placer le meilleur segment à l’endroit auquel le modèle prête attention) et la compression (réduire le contexte afin que rien ne soit enfoui).

# Retrieval rank != attention rank
# Place the highest-relevance chunk at the START or END,
# never stranded in the middle of a large concatenation.

Sensibilité aux éléments distracteurs

Les LLM sont sensibles au contexte non pertinent. Ajouter des segments plausibles mais erronés peut détourner la réponse, même lorsque le segment correct est également présent. Davantage de contexte récupéré n’est pas toujours préférable.

C’est pourquoi la précision compte : un contexte resserré, reclassé et compressé surpasse souvent un grand amas de segments vaguement associés.

# Empirically: appending a single highly-similar but WRONG chunk
# can flip a previously-correct answer. RAG quality depends on
# keeping distractors OUT, not just getting the gold chunk IN.

Pathologies du découpage en segments

Le découpage en segments de taille fixe sépare les idées au milieu des phrases, dissocie une affirmation de ses preuves et supprime le contexte structurel (quelle section, quel document). Un segment qui se lit de façon cohérente isolément peut être inutile ou trompeur sans son environnement.

Les chaînes de traitement avancées utilisent un découpage tenant compte de la structure, le chevauchement, l’expansion vers le document parent et les métadonnées pour préserver le sens.

def structure_aware_chunks(doc, max_tokens=400, overlap=50):
    sections = split_by_headings(doc)        # respect document structure
    chunks = []
    for sec in sections:
        for c in sliding_window(sec.text, max_tokens, overlap):
            chunks.append(Chunk(c, meta={'section': sec.title}))
    return chunks

Lacunes de la récupération purement sémantique

La récupération dense pure manque les besoins de correspondance exacte : identifiants, codes d’erreur, noms propres rares et noms d’interfaces de programmation. C’est précisément dans ces cas que les utilisateurs attendent une précision littérale. La récupération hybride combine des signaux denses (sémantiques) et creux (BM25 et mots-clés) pour couvrir les deux aspects.

La fusion réciproque des rangs est une méthode simple et robuste pour combiner les deux listes classées sans régler de poids.

def rrf(dense_ranks, sparse_ranks, k0=60):
    scores = {}
    for ranks in (dense_ranks, sparse_ranks):
        for rank, doc_id in enumerate(ranks):
            scores[doc_id] = scores.get(doc_id, 0) + 1.0 / (k0 + rank)
    return sorted(scores, key=scores.get, reverse=True)

Contexte obsolète et invérifiable

Le RAG naïf ne tient compte ni de la fraîcheur ni de la provenance. Il peut récupérer des documents obsolètes et n’offre aucun moyen intégré d’attribuer les affirmations à leurs sources, ce qui affaiblit la confiance et rend les hallucinations difficiles à détecter.

Les systèmes avancés associent des métadonnées (horodatage, source, version), filtrent selon ces métadonnées et exigent du générateur qu’il cite les identifiants des segments afin que les réponses soient vérifiables.

def filtered_retrieve(q, after_date):
    cands = vector_store.search(embed(q), k=50)
    fresh = [c for c in cands if c.meta['date'] >= after_date]
    return fresh  # then re-rank; generator must cite c.id

Pas de retour, pas d’adaptation

Le RAG naïf récupère les informations à l’aveugle : il ne peut pas détecter un échec de la récupération, décider qu’aucune récupération n’est nécessaire ni itérer. Les schémas avancés ajoutent une vérification de pertinence, une récupération conditionnelle et une récupération multi-étapes (agentique) qui reformule la requête lorsque les résultats semblent faibles.

La chaîne de traitement devient une boucle dotée d’une auto-évaluation plutôt qu’un unique passage vers l’avant.

def adaptive_rag(q):
    chunks = retrieve(q)
    if relevance_score(q, chunks) < 0.4:
        q2 = rewrite_query(q)            # reformulate and retry
        chunks = retrieve(q2)
    if relevance_score(q, chunks) < 0.4:
        return 'I could not find this in the sources.'
    return generate(q, chunks)

La pile RAG avancée

En regroupant ces échecs, une chaîne de traitement avancée superpose : un découpage tenant compte de la structure avec des métadonnées, une récupération hybride à rappel élevé, un reclasseur fondé sur un cross-encodeur pour la précision, une compression du contexte pour l’adapter et le recentrer, la réécriture de requête ou HyDE pour corriger le décalage, ainsi qu’une porte de pertinence avec des citations.

Les prochaines leçons construisent chaque couche. Le fil conducteur : récupérer un ensemble large, puis filtrer et affiner énergiquement.

def advanced_rag(q):
    cands = hybrid_retrieve(rewrite_query(q), k=50)  # high recall
    top = rerank(q, cands)[:8]                       # precision
    ctx = compress(q, top)                            # focus + fit
    return generate_with_citations(q, ctx)            # verifiable

Mesurer avant d’optimiser

Diagnostiquez le problème réel avant d’ajouter des mécanismes. Mesurez le rappel@k de la récupération (le segment de référence est-il récupéré ?) séparément de l’exactitude de la réponse (le générateur l’utilise-t-il ?). Un problème de rappel et un problème de précision exigent des corrections différentes.

Instrumentez les deux volets ; n’ajoutez pas un reclasseur si votre véritable problème vient du découpage ou du décalage de la requête.

def diagnose(eval_set):
    return {
        'recall@5':  recall_at_k(eval_set, k=5),     # retrieval health
        'recall@50': recall_at_k(eval_set, k=50),    # ceiling with rerank
        'answer_acc': answer_accuracy(eval_set),      # generation health
    }

Vérification rapide

Diagnostiquez un mode d’échec du RAG.

Récapitulatif

À retenir :

  • Le RAG naïf (segmenter, vectoriser, récupérer les k premiers, insérer, générer) constitue une solide référence de base avec des échecs prévisibles.
  • La similarité des bi-encodeurs est une approximation grossière de la pertinence ; le décalage de registre entre la requête et le document nuit au rappel.
  • Davantage de contexte n’est pas préférable : la sensibilité aux éléments distracteurs et le contenu perdu au milieu dégradent les réponses à mesure que k augmente.
  • Les pathologies du découpage, les lacunes de la récupération purement sémantique, l’obsolescence et l’absence de retour limitent tous le RAG naïf.
  • Le RAG avancé récupère largement puis filtre : récupération hybride, reclassement, compression, réécriture de requête et contrôle de pertinence. Mesurez séparément le rappel et l’exactitude des réponses avant d’optimiser.

Questions Fréquemment Posées

La leçon « Au-delà du RAG naïf » est-elle gratuite ?

Oui — le texte complet de « Au-delà du RAG naïf » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Prompt Engineering, passe à CoddyKit PRO. Le cours AI Prompt Engineering comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Au-delà du RAG naïf » ?

Les limites de la récupération de base. Tu pratiques AI Prompt Engineering avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Prompt Engineering ?

Aucune expérience préalable n'est requise. AI Prompt Engineering sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Au-delà du RAG naïf » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Prompt Engineering ?

Oui. Chaque leçon AI Prompt Engineering inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Au-delà du RAG naïf
  2. Réordonner les fragments récupérés
  3. Compression du contexte
  4. Réécriture des requêtes et HyDE
← Retour à AI Prompt Engineering