0Pricing
AI Prompt Engineering · Leçon

Compression du contexte

Réduire le contexte à ce qui compte.

Compression du contexte est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 3 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.

Pourquoi compresser le contexte

Les segments récupérés sont bruités : un segment pertinent peut être principalement constitué de texte standardisé avec une seule phrase essentielle. La compression du contexte réduit le texte récupéré à ce qui répond réellement à la requête avant qu’il n’atteigne le générateur.

Les bénéfices se cumulent : coût réduit des jetons, latence moindre, moins de distracteurs et atténuation de l’effet de perte au milieu grâce à la réduction du contexte que le modèle doit parcourir.

def compress(query, chunks):
    # Goal: keep only spans that bear on the query,
    # dropping boilerplate, navigation, and off-topic sentences.
    return [extract_relevant(query, c) for c in chunks]

Compression extractive ou abstractive

La compression extractive sélectionne des extraits textuels exacts (phrases, passages) pertinents pour la requête, tout en préservant la formulation exacte et la provenance. La compression abstractive paraphrase ou résume le contenu : elle permet une compression plus poussée, mais risque d’entraîner une perte d’informations et d’introduire des erreurs.

Pour un RAG factuel avec citations, préférez la compression extractive afin que les affirmations restent traçables jusqu’à leur source ; n’utilisez la compression abstractive que lorsque la fidélité peut être vérifiée.

def extractive(query, chunk):
    sents = split_sentences(chunk.text)
    scored = [(s, relevance(query, s)) for s in sents]
    kept = [s for s, r in scored if r > TAU]
    return ' '.join(kept) or top1(scored)   # never return empty

Filtrage au niveau des phrases

Il s’agit d’une technique légère et robuste : évaluez chaque phrase de chaque segment par rapport à la requête à l’aide d’un petit encodeur croisé ou de la similarité entre représentations vectorielles, puis supprimez les phrases obtenant un score faible. Vous préserverez ainsi les phrases les plus utiles tout en éliminant le contenu superflu.

Conservez un contexte minimal par segment afin d’éviter de supprimer la phrase environnante qui donne son sens à un fait.

def sentence_filter(query, chunk, keep_ratio=0.4):
    sents = split_sentences(chunk.text)
    scores = embed_sim_batch(query, sents)
    n_keep = max(1, int(len(sents) * keep_ratio))
    idx = sorted(range(len(sents)), key=lambda i: -scores[i])[:n_keep]
    return ' '.join(sents[i] for i in sorted(idx))  # keep original order

Compression contextuelle fondée sur un LLM

Un LLM peut compresser chaque segment : demandez-lui d’extraire uniquement les parties d’un passage pertinentes pour la requête, en renvoyant le segment tronqué tout en conservant sa formulation originale, ou un marqueur vide si rien n’est pertinent.

Il s’agit du modèle ContextualCompressionRetriever de LangChain. Cette méthode est plus précise que les filtres fondés sur les représentations vectorielles, mais elle ajoute un appel à un LLM par segment ; réservez-la donc aux chaînes de traitement à forts enjeux ou traitez les segments par lots.

def llm_compress(query, chunk):
    prompt = (
        'Extract ONLY sentences from the passage relevant to the query. '
        'If none are relevant, output NONE. Do not paraphrase.\n'
        'Query: ' + query + '\nPassage: ' + chunk.text
    )
    out = llm(prompt, temperature=0).strip()
    return None if out == 'NONE' else out

Élagage au niveau des jetons (LLMLingua)

Des méthodes comme LLMLingua compressent au niveau des jetons en utilisant un petit modèle pour estimer la valeur informative de chaque jeton et supprimer ceux qui apportent peu d’informations. Elles peuvent atteindre des ratios de compression élevés tout en préservant le signal nécessaire au grand modèle.

Le compromis est le suivant : le texte compressé devient moins lisible pour un humain. Cette méthode convient donc au contexte destiné uniquement à la machine, et non à un affichage destiné à l’utilisateur.

def token_prune(context, target_ratio=0.3):
    # small LM estimates per-token information (perplexity-based);
    # drop the least informative tokens down to target_ratio length
    scores = small_lm_token_importance(context)
    return keep_top_fraction(context, scores, target_ratio)

Adaptée à la requête ou indépendante de celle-ci

La compression adaptée à la requête conserve ce qui est pertinent pour cette requête et produit le contexte le plus concis, mais elle doit être exécutée pour chaque demande. La compression indépendante de la requête (résumés de segments précalculés) coûte moins cher au moment de la demande, mais ne peut pas se concentrer sur la question précise.

Une approche hybride stocke hors ligne des versions condensées des segments et applique en ligne une légère réduction adaptée à la requête.

# Offline: precompute a dense summary per chunk (query-agnostic)
chunk.summary = summarize(chunk.text)
# Online: query-aware trim over summaries (cheap) then verify on full
ctx = [sentence_filter(query, Chunk(c.summary)) for c in top_chunks]

Se prémunir contre la perte d’informations

Une compression trop agressive peut supprimer l’unique proposition importante. Ajoutez une vérification du rappel : vérifiez que le contexte compressé implique toujours la réponse, ou prévoyez une solution de repli vers le segment non compressé lorsque le compresseur en renvoie une quantité suspectement faible.

Ne laissez jamais la compression réduire à vide un segment que le réordonnanceur a jugé hautement pertinent ; cela indique une défaillance du compresseur, et non une absence de pertinence.

def safe_compress(query, chunk):
    out = llm_compress(query, chunk)
    if out is None and chunk.rerank_score > 0.7:
        return chunk.text          # trust re-ranker over compressor
    return out or chunk.text

Préserver la provenance

La compression doit préserver l’attribution de la source. Marquez chaque extrait conservé avec son segment et l’ID du document afin que le générateur puisse le citer. Si vous supprimez les métadonnées lors de la compression, vous perdez la possibilité de vérifier les informations et de détecter les hallucinations.

Faites circuler les identifiants dans la chaîne de traitement sous forme de champs structurés, jamais sous forme de texte libre que la compression pourrait supprimer.

def compress_with_ids(query, chunks):
    out = []
    for c in chunks:
        span = safe_compress(query, c)
        out.append({'id': c.id, 'doc': c.meta['doc_id'], 'text': span})
    return out   # generator cites id; provenance preserved

Compression et budget de jetons

La compression vous permet de récupérer davantage de candidats pour maximiser le rappel tout en conservant une petite invite finale. Définissez un budget de jetons pour la fenêtre de contexte et regroupez progressivement les extraits compressés ayant la plus grande valeur jusqu’à atteindre ce budget.

Vous dissociez ainsi la quantité récupérée de la quantité dépensée pour la génération, ce qui constitue un levier d’efficacité essentiel.

def pack(spans, budget_tokens, tok):
    spans = sorted(spans, key=lambda s: -s['score'])
    used, packed = 0, []
    for s in spans:
        t = tok(s['text'])
        if used + t > budget_tokens:
            continue
        packed.append(s); used += t
    return packed

Mesurer la qualité de la compression

Suivez trois valeurs : le ratio de compression (jetons économisés), la justesse des réponses (la qualité a-t-elle été préservée ?) et la fidélité (le compresseur a-t-il évité de modifier les faits ?). L’objectif est d’obtenir le ratio le plus élevé possible sans dégrader la justesse des réponses.

Faites varier l’agressivité de la compression et choisissez le point de Pareto qui respecte votre objectif de coût sans perte de qualité.

def eval_compression(eval_set, levels):
    return {
        lvl: {
            'ratio': mean_ratio(eval_set, lvl),
            'acc':   answer_accuracy(eval_set, lvl),
            'faith': faithfulness(eval_set, lvl),
        } for lvl in levels
    }

Une chaîne de traitement adaptée à la compression

De bout en bout : récupérez largement, réordonnez, compressez chaque segment restant (avec une méthode extractive ou fondée sur un LLM) en préservant sa provenance, évitez les suppressions excessives, regroupez les éléments dans les limites d’un budget de jetons, puis générez avec des citations.

La compression est la couche qui rend abordable une récupération à rappel élevé et permet au générateur de rester concentré sur l’essentiel.

def pipeline(query):
    top = rerank(query, hybrid_retrieve(query, 50))[:12]
    spans = compress_with_ids(query, top)
    spans = [s for s in spans if s['text']]
    packed = pack(spans, budget_tokens=2000, tok=count_tokens)
    return generate_with_citations(query, packed)

Vérification rapide

Choisissez la bonne approche de compression pour un système RAG factuel avec citations.

Récapitulatif

Points clés à retenir :

  • La compression réduit les segments récupérés à leur contenu pertinent pour la requête, ce qui diminue les coûts, la latence et les distracteurs.
  • Pour un RAG factuel avec citations, préférez la méthode extractive (formulation originale et traçable) à la méthode abstractive ; l’élagage au niveau des jetons convient au contexte destiné uniquement à la machine.
  • La compression adaptée à la requête est la plus concise, mais doit être exécutée pour chaque demande ; combinez-la avec des résumés hors ligne pour gagner en efficacité.
  • Prémunissez-vous contre la perte d’informations et préservez la provenance des segments et des documents pour les citations.
  • Utilisez la compression pour récupérer largement tout en conservant de petites invites ; maximisez le ratio sans perdre en justesse des réponses.

Questions Fréquemment Posées

La leçon « Compression du contexte » est-elle gratuite ?

Oui — le texte complet de « Compression du contexte » 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 « Compression du contexte » ?

Réduire le contexte à ce qui compte. 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 3 sur 4.

Combien de temps prend la leçon « Compression du contexte » ?

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