Compressione del contesto
Ridurre il contesto a ciò che conta.
Compressione del contesto è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.
Perché comprimere il contesto
I chunk recuperati sono rumorosi: un chunk rilevante può essere costituito quasi interamente da testo standard, con una sola frase essenziale. La compressione del contesto riduce il testo recuperato alle sole parti che rispondono effettivamente alla query, prima che raggiunga il generatore.
I vantaggi si sommano: minori costi per i token, latenza ridotta, meno elementi fuorvianti e un effetto meno marcato della perdita nel mezzo, grazie alla riduzione del contesto che il modello deve attraversare.
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]Compressione estrattiva e astrattiva
La compressione estrattiva seleziona intervalli testuali letterali (frasi, passaggi) rilevanti per la query, preservando la formulazione esatta e la provenienza. La compressione astrattiva parafrasa o riassume, ottenendo una compressione maggiore, ma rischiando perdita di informazioni e introduzione di errori.
Per un RAG fattuale con citazioni, preferire l'estrattiva per mantenere le affermazioni riconducibili alla fonte; usare l'astrattiva solo quando è possibile verificarne la fedeltà.
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 emptyFiltraggio a livello di frase
Una tecnica leggera e robusta consiste nel valutare ogni frase di ciascun chunk rispetto alla query, usando un cross-encoder di piccole dimensioni o la similarità tra embedding, e nell'eliminare le frasi con punteggio basso. In questo modo si conservano le frasi ad alto valore e si scarta il testo superfluo.
Mantenere un contesto minimo per ogni chunk, per evitare di eliminare la frase circostante che dà significato al fatto riportato.
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 orderCompressione contestuale basata su LLM
Un LLM può comprimere ogni chunk: richiedergli di estrarre solo le parti di un passaggio rilevanti per la query, restituendo il chunk con il testo originale ma ritagliato, oppure un indicatore vuoto se non contiene nulla di rilevante.
Questo è il pattern LangChain ContextualCompressionRetriever. È più accurato dei filtri basati sugli embedding, ma aggiunge una chiamata LLM per ogni chunk; pertanto, riservarlo alle pipeline ad alta criticità oppure elaborare i chunk in batch.
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 outPruning a livello di token (LLMLingua)
Metodi come LLMLingua comprimono a livello di token usando un modello di piccole dimensioni per stimare l'informatività dei token ed eliminare quelli con poche informazioni. Possono raggiungere elevati rapporti di compressione preservando al contempo il segnale di cui il modello più grande ha bisogno.
Il compromesso è una minore leggibilità per le persone del testo compresso; questa tecnica è quindi adatta al contesto usato esclusivamente dalle macchine, non alla visualizzazione per l'utente.
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)Compressione sensibile alla query e indipendente dalla query
La compressione sensibile alla query conserva ciò che è rilevante per questa query e produce il contesto più circoscritto, ma deve essere eseguita a ogni richiesta. La compressione indipendente dalla query (con riassunti dei chunk precalcolati) è più economica al momento della richiesta, ma non può concentrarsi sulla domanda specifica.
Un approccio ibrido memorizza offline versioni condensate dei chunk e applica online un leggero ritaglio sensibile alla query.
# 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]Prevenire la perdita di informazioni
Una compressione aggressiva può eliminare proprio la clausola essenziale. Proteggersi con una verifica del recall: verificare che il contesto compresso implichi ancora la risposta, oppure mantenere un fallback al chunk non compresso quando il compressore restituisce una quantità di testo sospettosamente ridotta.
Non lasciare mai che la compressione riduca a vuoto un chunk che il reranker ha valutato altamente rilevante: questo indica un errore del compressore, non un'irrilevanza.
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.textPreservare la provenienza
La compressione deve mantenere intatta l'attribuzione della fonte. Contrassegnare ogni intervallo conservato con l'ID del chunk e del documento, così che il generatore possa citarlo. Se si elimina dai metadati ciò che viene compresso, si perdono la verificabilità e la possibilità di rilevare le allucinazioni.
Trasportare gli ID nella pipeline come campi strutturati, mai come testo libero che la compressione potrebbe eliminare.
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 preservedCompressione e budget di token
La compressione consente di recuperare più candidati per aumentare il recall, mantenendo al contempo ridotte le dimensioni del prompt finale. Impostare un budget di token per la finestra di contesto e inserire avidamente gli intervalli compressi di maggior valore fino a raggiungere il limite.
In questo modo si disaccoppia la quantità recuperata dalla quantità spesa per la generazione: una leva fondamentale per l'efficienza.
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 packedMisurare la qualità della compressione
Monitorare tre valori: il rapporto di compressione (token risparmiati), l'accuratezza della risposta (la qualità è rimasta invariata?) e la fedeltà (il compressore ha evitato di alterare i fatti?). L'obiettivo è ottenere il rapporto più elevato senza modificare l'accuratezza della risposta.
Valutare diversi livelli di aggressività della compressione e scegliere il punto Pareto che soddisfa l'obiettivo di costo senza perdita di 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
}Una pipeline con compressione
Dall'inizio alla fine: recuperare ampiamente, applicare il reranking, comprimere ogni chunk rimasto (con metodo estrattivo o basato su LLM) mantenendone la provenienza, proteggersi da un ritaglio eccessivo, inserire i contenuti entro un budget di token e generare la risposta con le citazioni.
La compressione è il livello che rende economicamente sostenibile il recupero ad alto recall e mantiene il generatore concentrato su ciò che conta.
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)Verifica rapida
Scegliere l'approccio di compressione corretto per un sistema RAG fattuale con citazioni.
Riepilogo
Punti chiave:
- La compressione riduce i chunk recuperati al contenuto rilevante per la query, tagliando costi, latenza ed elementi fuorvianti.
- Per un RAG fattuale con citazioni, preferire la compressione estrattiva (testo invariato e tracciabile) a quella astrattiva; il pruning a livello di token è adatto al contesto usato esclusivamente dalle macchine.
- La compressione sensibile alla query è la più circoscritta, ma va eseguita a ogni richiesta; combinarla con riassunti offline per maggiore efficienza.
- Proteggersi dalla perdita di informazioni e preservare la provenienza di chunk e documenti per le citazioni.
- Usare la compressione per recuperare ampiamente mantenendo ridotte le dimensioni dei prompt; regolarla per massimizzare il rapporto senza perdere accuratezza nella risposta.
Domande Frequenti
La lezione «Compressione del contesto» è gratuita?
Sì — il testo completo di «Compressione del contesto» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.
Cosa imparerò in «Compressione del contesto»?
Ridurre il contesto a ciò che conta. Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Prompt Engineering?
Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Compressione del contesto»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?
Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Oltre il RAG ingenuo
- Riordinamento dei chunk recuperati
- Compressione del contesto
- Riscrittura delle query e HyDE