Riscrittura delle query e HyDE
Migliorare il recall del recupero.
Riscrittura delle query e HyDE è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 4 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.
La query è l'anello debole
La qualità del recupero è limitata dalla query. Le query grezze degli utenti sono spesso brevi, ambigue, ricche di pronomi o formulate in modo diverso dai documenti. La trasformazione della query la riformula prima del recupero per aumentare recall e precisione.
È uno degli aggiornamenti più economici e con maggiore impatto rispetto a un RAG ingenuo: correggendo la query, ne traggono vantaggio tutte le fasi successive.
def transform_query(raw, history):
# Resolve references, expand, decompose, or hypothesize
# BEFORE embedding and retrieving.
return rewrite(raw, history)Riscrittura della query
La trasformazione più semplice consiste nel chiedere a un LLM di riscrivere la query dell'utente in una forma più chiara, autonoma e adatta al recupero. Corregge gli errori di battitura, espande le abbreviazioni ed elimina il rumore conversazionale.
È particolarmente importante nelle conversazioni a più turni, in cui l'ultimo messaggio è incomprensibile senza il contesto (E il secondo?).
def rewrite_query(raw):
prompt = (
'Rewrite the user question into a clear, standalone search '
'query optimized for document retrieval. Keep key entities.\n'
'Question: ' + raw
)
return llm(prompt, temperature=0).strip()Condensazione conversazionale
Nel RAG conversazionale, condensare il dialogo e il nuovo turno in un'unica domanda autonoma. Senza questo passaggio, pronomi ed ellissi rendono inefficace l'embedding e il recupero collassa.
Passare i turni precedenti, così che il riscrittore possa trasformare riferimenti come questo, quello o il precedente in entità esplicite che il sistema di recupero possa trovare.
def condense(history, follow_up):
prompt = (
'Given the conversation, rewrite the follow-up as a standalone '
'question with all references resolved.\nConversation:\n' +
render(history) + '\nFollow-up: ' + follow_up
)
return llm(prompt, temperature=0).strip()Espansione della query
L'espansione genera sinonimi, termini correlati o formulazioni alternative per ampliare la copertura lessicale e semantica. Contrasta il disallineamento del vocabolario: il documento dice invalidate, l'utente dice revoke.
Espandere ai fini del recupero, quindi eseguire il recupero sull'unione; non mostrare la forma espansa all'utente. Prestare attenzione all'espansione eccessiva, che può attirare risultati fuori tema.
def expand(query, n=3):
prompt = (
'List ' + str(n) + ' alternative phrasings of this query using '
'synonyms and domain terms, one per line.\n' + query
)
variants = parse_lines(llm(prompt, temperature=0.5))
return [query] + variantsRecupero multi-query
Generare diverse riformulazioni, recuperare i risultati per ciascuna e fondere le liste dei risultati (reciprocal rank fusion). Formulazioni diverse portano alla luce chunk rilevanti diversi; la fusione combina i loro punti di forza e stabilizza il recall.
Questo approccio scambia chiamate di recupero aggiuntive con una maggiore robustezza rispetto a una singola formulazione errata.
def multi_query(raw, n=4):
queries = expand(raw, n)
rankings = [dense_retrieve(q, 30) for q in queries]
fused = rrf(*rankings)
return dedup(fused)Decomposizione della query
Le domande complesse e multi-hop richiedono la decomposizione in sotto-domande, con un recupero separato per ciascuna, seguita dalla composizione. Chiedere quale CEO dell'azienda che ha acquisito X sia più anziano di... non è una domanda a cui un singolo recupero possa rispondere.
Decomporre, eseguire il recupero per ogni sotto-domanda e lasciare che il generatore combini le evidenze raccolte.
def decompose_and_retrieve(question):
subs = parse_lines(llm(
'Break this into independent sub-questions, one per line.\n' +
question, temperature=0))
evidence = {s: rerank(s, dense_retrieve(s, 30))[:3] for s in subs}
return evidence # generator synthesizes the final answerHyDE: l'idea di base
HyDE (Hypothetical Document Embeddings, Gao et al., 2022) ribalta il problema. Invece di creare l'embedding della query breve, chiede all'LLM di generare un documento di risposta ipotetico, quindi crea l'embedding di quel documento ed esegue il recupero usandolo.
Il documento ipotetico usa lo stesso registro dei documenti reali, quindi il suo embedding si colloca più vicino alle risposte autentiche, risolvendo il disallineamento tra query e documento.
def hyde(query):
hypo = llm(
'Write a short passage that would answer this question, as if '
'from a reference document.\nQuestion: ' + query,
temperature=0.3)
return dense_retrieve_by_vector(embed(hypo), k=30) # embed the answerPerché HyDE migliora il recall
Una domanda e la sua risposta sono formulate in modo diverso; una domanda e una risposta falsa ma plausibile sono formulate in modo simile alla risposta reale. HyDE sfrutta il prior generativo dell'LLM per colmare questa distanza, anche se il documento ipotetico contiene errori fattuali.
La correttezza del documento ipotetico conta poco: deve soltanto avere il vocabolario e la struttura giusti per collocarsi vicino ai documenti autentici nello spazio degli embedding.
# Robustness: average several hypothetical docs to reduce variance
def hyde_avg(query, n=3):
vecs = [embed(llm(HYDE_PROMPT + query, temperature=0.5))
for _ in range(n)]
centroid = sum(vecs) / n
return dense_retrieve_by_vector(centroid, 30)Compromessi e modalità di errore di HyDE
HyDE aggiunge una generazione LLM prima del recupero, aumentando latenza e costi, e può allucinare un documento ipotetico che si allontana dal tema, riducendo il recall per query di nicchia o fuori distribuzione che il modello non sa gestire.
Mitigare il problema combinando il recupero vettoriale HyDE con quello basato sulla query originale tramite fusione, così che un documento ipotetico errato non possa compromettere completamente il recall.
def hyde_hybrid(query):
a = dense_retrieve_by_vector(embed(hyde_doc(query)), 30)
b = dense_retrieve(query, 30) # raw-query fallback
return dedup(rrf(a, b)) # robust to bad hypotheticalsScegliere e combinare le tecniche
Queste trasformazioni si completano a vicenda. Usare la condensazione per le conversazioni, l'espansione/multi-query per le lacune del vocabolario, la decomposizione per le domande multi-hop e HyDE per il disallineamento di registro tra domanda e documento. Molti sistemi di produzione concatenano la condensazione, poi HyDE, quindi fondono i risultati con la query originale e infine applicano il reranking.
Ogni trasformazione aggiuntiva comporta una chiamata LLM, quindi attivarle in base al tipo di query invece di eseguirle sempre tutte.
def route_transform(query, history, qtype):
q = condense(history, query) if history else query
if qtype == 'multi_hop': return decompose_and_retrieve(q)
if qtype == 'mismatch': return hyde_hybrid(q)
if qtype == 'vocab_gap': return multi_query(q)
return dense_retrieve(q, 30)Valutare le trasformazioni
Misuri ogni trasformazione in base al miglioramento del recall@k del retrieval e dell'accuratezza della risposta finale rispetto alla query grezza, su un set privo di leakage. Tenga traccia della latenza aggiuntiva e del costo LLM, così conserverà solo le trasformazioni che ripagano il loro costo.
Attenzione: una trasformazione che migliora il recall ma aggiunge distrattori può ridurre l'accuratezza della risposta se non viene abbinata a reranking e compressione.
def eval_transform(name, fn, eval_set):
return {
'recall@10': recall_at_k(eval_set, retriever=fn, k=10),
'answer_acc': answer_accuracy(eval_set, retriever=fn),
'extra_latency_ms': transform_latency(fn),
}Verifica rapida
Rifletta sul motivo per cui HyDE funziona nonostante le ipotesi siano imperfette.
Riepilogo
Punti chiave:
- Il retrieval è limitato dalla query; trasformarla è un miglioramento RAG economico e ad alto impatto.
- La riscrittura e la condensazione rendono autonome le query delle conversazioni; l'espansione e le query multiple colmano le lacune di vocabolario.
- La scomposizione gestisce le domande multi-hop recuperando informazioni per ogni sotto-domanda.
- HyDE incorpora una risposta ipotetica per colmare il disallineamento di registro tra domanda e documento; non è necessario che l'ipotesi sia corretta.
- Combini le trasformazioni in base al tipo di query, le fonda con la query grezza per maggiore robustezza e valuti recall, accuratezza della risposta, latenza e costo.
Domande Frequenti
La lezione «Riscrittura delle query e HyDE» è gratuita?
Sì — il testo completo di «Riscrittura delle query e HyDE» è 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 «Riscrittura delle query e HyDE»?
Migliorare il recall del recupero. 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 4 di 4.
Quanto tempo richiede la lezione «Riscrittura delle query e HyDE»?
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