Omskrivning av frågor och HyDE
Förbättra retrieval-recall.
Omskrivning av frågor och HyDE är en gratis lektion i AI-promptteknik på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för AI-promptteknik, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i AI-promptteknik innehåller totalt 4 lektioner.
Frågan är den svaga länken
Retrievalkvaliteten begränsas av frågan. Råa användarfrågor är ofta korta, tvetydiga, fulla av pronomen eller formulerade på ett annat sätt än dokumenten. Frågeomformning ändrar frågan före retrieval för att öka recall och precision.
Det är en av de billigaste uppgraderingarna med störst hävstång jämfört med naiv RAG: åtgärda frågan så drar varje efterföljande steg nytta av det.
def transform_query(raw, history):
# Resolve references, expand, decompose, or hypothesize
# BEFORE embedding and retrieving.
return rewrite(raw, history)Omformulering av frågor
Den enklaste transformeringen är att ett LLM omformulerar användarens fråga till en tydligare, fristående och retrievalvänlig form. Det rättar stavfel, expanderar förkortningar och tar bort samtalsbrus.
Detta är särskilt viktigt i chatt med flera turer, där det senaste meddelandet är obegripligt utan kontext, som i frågan Hur är det med den andra?
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()Kondensering av dialog
I chattbaserad RAG ska dialogen och den nya turen kondenseras till en enda fristående fråga. Utan detta gör pronomen och ellipser embeddingen meningslös och retrieval kollapsar.
Skicka med tidigare turer så att omformuleraren kan lösa vad ‘den’, ‘det’ och ‘den förra’ syftar på och omvandla dem till uttryckliga entiteter som retrievern kan matcha.
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()Frågeexpansion
Expansion genererar synonymer, relaterade termer eller alternativa formuleringar för att bredda den lexikala och semantiska täckningen. Den motverkar vokabulärmismatch: dokumentet säger invalidate, användaren säger revoke.
Expandera för retrieval och hämta sedan med unionen. Visa inte den expanderade formen för användaren. Var uppmärksam på överexpansion, som kan dra in resultat utanför ämnet.
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] + variantsRetrieval med flera frågor
Generera flera olika omformuleringar, hämta resultat för varje och slå samman resultatlistorna (reciprocal rank fusion). Olika formuleringar lyfter fram olika relevanta chunkar; sammanslagningen förenar deras styrkor och stabiliserar recall.
Detta innebär fler retrieval-anrop i utbyte mot robusthet mot en enskild dålig formulering.
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)Dekomponering av frågor
Komplexa frågor med flera hopp kräver dekomponering i underfrågor som hämtas separat och sedan sätts samman. Frågan om vilken vd på företaget som förvärvade X är äldre än … kan inte besvaras med en enda retrieval.
Dekomponera, hämta per underfråga och låt generatorn kombinera den insamlade evidensen.
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: Grundidén
HyDE (Hypothetical Document Embeddings, Gao et al., 2022) vänder på problemet. I stället för att skapa en embedding av den korta frågan ber modellen att generera ett hypotetiskt svarsdokument, skapar sedan en embedding av det och hämtar med hjälp av den.
Det hypotetiska dokumentet använder samma stilnivå som verkliga dokument, så dess embedding hamnar närmare äkta svar och åtgärdar mismatchen mellan fråga och dokument.
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 answerVarför HyDE förbättrar recall
En fråga och dess svar formuleras olika; en fråga och ett falskt men plausibelt svar formuleras på ett sätt som liknar det verkliga svaret. HyDE utnyttjar LLM:ets generativa prior för att överbrygga det gapet, även om det hypotetiska dokumentet innehåller faktafel.
Det hypotetiska dokumentets korrekthet spelar inte så stor roll: det behöver bara ha rätt vokabulär och struktur för att hamna nära verkliga dokument i embeddingrymden.
# 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)HyDE: kompromisser och fellägen
HyDE lägger till en LLM-generering före retrieval, vilket ökar latens och kostnad, och kan hallucinera fram ett hypotetiskt dokument som hamnar utanför ämnet. Det försämrar recall för nischade frågor eller frågor utanför modellens träningsfördelning, som modellen inte känner till något om.
Motverka detta genom att kombinera retrieval med HyDE-vektorer och retrieval med råfrågan via fusion, så att en dålig hypotes inte kan sänka recall helt.
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 hypotheticalsVälj och kombinera tekniker
De här transformeringarna kompletterar varandra. Använd kondensering för chatt, expansion/retrieval med flera frågor för vokabulärluckor, dekomponering för multi-hop och HyDE för skillnader i fråge- och dokumentstil. Många produktionsstackar kedjar kondensering, därefter HyDE, slår sedan samman resultaten med råfrågan och re-rankar slutligen.
Varje tillagd transformering kostar ett LLM-anrop, så aktivera dem villkorligt utifrån frågetyp i stället för att alltid köra alla.
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)Utvärdering av transformeringar
Mät varje transformering utifrån dess lyft i retrieval recall@k och den slutliga svarsträffsäkerheten jämfört med den råa frågan, på en läckagefri uppsättning. Följ den extra latensen och LLM-kostnaden så att ni bara behåller transformeringar som lönar sig.
Var försiktig: en transformering som förbättrar recall men lägger till distraktorer kan sänka svarsträffsäkerheten om den inte kombineras med omrankning och komprimering.
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),
}Snabbkontroll
Resonera kring varför HyDE fungerar trots imperfekta hypotetiska svar.
Sammanfattning
Viktigaste lärdomarna:
- Retrieval begränsas av frågan; att transformera den är en billig RAG-uppgradering med stor hävstång.
- Omskrivning/kondensering gör chattfrågor fristående; expansion och multi-query åtgärdar luckor i vokabulären.
- Dekomponering hanterar frågor med flera hopp genom att hämta per delfråga.
- HyDE bäddar in ett hypotetiskt svar för att överbrygga skillnaden i register mellan fråga och dokument; det hypotetiska svarets korrekthet krävs inte.
- Kombinera transformeringar efter frågetyp, kombinera med råfrågan för robusthet och utvärdera recall, svarsträffsäkerhet, latens och kostnad.
Lär dig AI-promptteknik med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 53
- Lektioner
- 199
Vanliga frågor
Är lektionen ”Omskrivning av frågor och HyDE” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen AI-promptteknik, inklusive ”Omskrivning av frågor och HyDE”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i AI-promptteknik innehåller totalt 4 lektioner.
Vad lär jag mig i ”Omskrivning av frågor och HyDE”?
Förbättra retrieval-recall. Ni övar på AI-promptteknik med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig AI-promptteknik?
Du behöver inga förkunskaper. Utbildningen i AI-promptteknik på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Omskrivning av frågor och HyDE”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här AI-promptteknik-lektionen?
Ja. Varje AI-promptteknik-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Bortom naiv RAG
- Omrankning av hämtade textblock
- Kontextkomprimering
- Omskrivning av frågor och HyDE