AI-promptteknik · Lektion

Omrankning av hämtade textblock

Omrankning med cross-encoder.

Lektion 2 av 413 steg

Omrankning av hämtade textblock är en gratis lektion i AI-promptteknik på CoddyKit. Detta är lektion 2 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.

Varför omrangera över huvud taget

Hämtning i första steget (tät eller gles) optimerar för recall i stor skala: det korrekta textblocket ska finnas någonstans bland de 50 främsta. Den är snabb men grov. En omrankare i det andra steget ordnar sedan om kortlistan med fokus på precision och lyfter de verkligt relevanta textblocken till toppen.

Mönstret att först hämta brett och sedan omrangera precist utgör ryggraden i avancerad RAG.

def two_stage(query, k_retrieve=50, k_final=5):
    candidates = first_stage_retrieve(query, k_retrieve)  # high recall
    reranked = rerank(query, candidates)                  # high precision
    return reranked[:k_final]

Bi-Encoder kontra Cross-Encoder

En bi-encoder kodar frågan och dokumentet separat till vektorer och jämför dem med cosinuslikhet. Den är snabb och kan indexeras, men förlorar samspelet mellan fråga och dokument. En cross-encoder skickar frågan och en kandidat tillsammans genom modellen och returnerar ett relevansvärde, vilket fångar finmaskigt samspel.

Cross-encoders är betydligt träffsäkrare men kan inte beräknas i förväg, så de körs endast på kortlistan.

# Bi-encoder: score = cos(enc(q), enc(d))     -> precomputable
# Cross-encoder: score = model(q, d) -> 0..1   -> per-pair, no index
def cross_encode(query, doc):
    return cross_encoder.predict([(query, doc)])[0]  # joint attention

Ett omrankningssteg med Cross-Encoder

Omrankaren poängsätter varje kandidat mot frågan och sorterar sedan i fallande ordning. Eftersom Cross-Encoder-modellen riktar uppmärksamheten mot fråga och dokument gemensamt kan den lösa subtila relevansskillnader som bi-encodern missar: negationer, behov av exakta träffar och skillnaden mellan svar och ämne.

Det här steget förbättrar vanligtvis svarens träffsäkerhet mer än någon annan enskild RAG-förbättring.

def rerank(query, candidates):
    pairs = [(query, c.text) for c in candidates]
    scores = cross_encoder.predict(pairs)        # batched
    for c, s in zip(candidates, scores):
        c.rerank_score = s
    return sorted(candidates, key=lambda c: c.rerank_score, reverse=True)

LLM som omrankare

När ingen tränad cross-encoder passar er domän kan en LLM omrangera resultaten. Listwise-promptning ber modellen rangordna en lista med textstycken efter relevans i ett enda anrop, medan pointwise poängsätter varje textstycke separat.

Listwise fångar relativa jämförelser och är tokeneffektivt, men var uppmärksam på positionsbias och se till att tolkningen av utdata är robust mot att modellen utelämnar eller duplicerar ID:n.

def llm_listwise(query, candidates):
    passages = '\n'.join(
        '[' + str(i) + '] ' + c.text for i, c in enumerate(candidates)
    )
    prompt = (
        'Rank the passages by relevance to the query. '
        'Return only IDs, most relevant first.\nQuery: ' + query +
        '\n' + passages
    )
    order = parse_ids(llm(prompt, temperature=0))
    return [candidates[i] for i in order]

Fördröjning och kortlistans storlek

Omrankningskostnaden skalar med storleken på kandidatlistan. En cross-encoder på 50 kandidater är mycket billigare än på 500. Välj det första stegets k så stort att den korrekta textbiten fångas upp (validera recall@k), men tillräckligt litet för att omrankningen ska rymmas inom er latensbudget.

Batcha poängsättningen av paren och kör den på maskinvara med hårdvaruacceleration; cross-encoders kan parallelliseras effektivt över paren.

def tune_shortlist(eval_set, ks=(20, 50, 100, 200)):
    # find smallest k where recall@k saturates -> rerank fewer pairs
    return {k: (recall_at_k(eval_set, k), rerank_latency(k)) for k in ks}

Hybridiskt första steg plus re-rankning

Den bästa recallen uppnås med ett hybridiskt första steg (dense + BM25 som slås samman), där en enda deduplicerad shortlist skickas vidare till re-rankern. Dense hittar parafraser; sparse hittar exakta identifierare; cross-encodern sorterar sedan unionen efter faktisk relevans.

Den här kombinationen är robust för olika frågetyper, från frågor på naturligt språk till bokstavliga uppslag.

def hybrid_then_rerank(query, k_final=6):
    dense = dense_retrieve(query, 50)
    sparse = bm25_retrieve(query, 50)
    fused = dedup(rrf(dense, sparse))     # reciprocal rank fusion
    return rerank(query, fused)[:k_final]

Poängtrösklar och gränsvärden

Re-rankerns poäng kan kalibreras. I stället för att alltid välja top-n kan en relevanströskel tillämpas: behåll chunkar över en viss poäng och returnera, om ingen kvalificerar sig, ärligt att inget svar finns. Detta förhindrar att prompten fylls med svagt relevanta utfyllnader.

Justera tröskeln på en valideringsmängd för att balansera täckningen av besvarbara frågor mot inkluderingen av distraktioner.

def threshold_select(reranked, tau=0.3, max_n=8):
    kept = [c for c in reranked if c.rerank_score >= tau][:max_n]
    if not kept:
        return None        # signal: no sufficiently relevant context
    return kept

Mångfald efter re-rankning

En ren relevanssortering kan returnera flera nästan identiska chunkar från samma dokument, vilket slösar på kontextbudgeten. Tillämpa MMR eller tak per dokument efter re-rankningen för att säkerställa att den slutliga mängden täcker olika aspekter och källor.

Detta är viktigt för multi-hop-frågor där svaret sträcker sig över flera dokument.

def diversify(reranked, max_per_doc=2, k=6):
    out, per_doc = [], {}
    for c in reranked:
        d = c.meta['doc_id']
        if per_doc.get(d, 0) < max_per_doc:
            out.append(c)
            per_doc[d] = per_doc.get(d, 0) + 1
        if len(out) == k:
            break
    return out

Ordning för generatorn

Efter att de bästa chunkarna har valts ska de placeras så att attention utnyttjas. Med tanke på lost-in-the-middle bör den enda chunk som fått högst poäng placeras i början eller slutet av kontexten, inte begravas bland de andra.

Vissa pipelines ordnar chunkar efter stigande relevans så att den bästa hamnar närmast frågan, vilket speglar recency-strategin för few-shot.

def order_for_llm(chunks):
    chunks = sorted(chunks, key=lambda c: c.rerank_score)  # ascending
    return chunks                 # most relevant chunk ends up last,
                                  # nearest the trailing question

Utvärdering av re-rankern

Mät re-rankern med rankingmått, främst NDCG och MRR, på märkta relevansbedömningar för fråga–chunk-par och därefter med den efterföljande svarsträffsäkerheten. En re-ranker som förbättrar NDCG men inte svaren kan omordna chunkar som generatorn redan hanterade.

Följ alltid upp kvaliteten på slutuppgiften, inte bara rankingmåtten.

import math

def ndcg_at_k(relevances, k):
    dcg = sum(r / math.log2(i + 2) for i, r in enumerate(relevances[:k]))
    ideal = sorted(relevances, reverse=True)
    idcg = sum(r / math.log2(i + 2) for i, r in enumerate(ideal[:k]))
    return dcg / idcg if idcg else 0.0

En produktionspipeline för re-rankning

Från början till slut: hämta hybridiskt en shortlist med 50 kandidater, deduplicera, re-ranka med en cross-encoder, tillämpa en poängtröskel, skapa mångfald per dokument, ordna innehållet för attention och generera med citeringar. Låt tröskeln styra om ett ärligt svar om att inget svar finns ska returneras.

Cacha embeddings och re-rankerns poäng per (fråga, chunk) när trafiken upprepar sig, så minskar kostnaden.

def pipeline(query):
    shortlist = hybrid_then_rerank(query, k_final=20)
    kept = threshold_select(shortlist, tau=0.3, max_n=8)
    if kept is None:
        return 'No relevant information found.'
    ctx = order_for_llm(diversify(kept))
    return generate_with_citations(query, ctx)

Snabbtest

Välj rätt arkitektur för re-rankning.

Sammanfattning

Viktiga slutsatser:

  • Hämta brett för hög recall och re-ranka sedan shortlistan för hög precision.
  • Cross-encoders poängsätter fråge-dokument-par gemensamt (träffsäkra, men inte indexerbara); bi-encoders är snabba men grova.
  • LLM-baserad listwise/pointwise-re-rankning är en reservlösning; var uppmärksam på positionsbias och parsning.
  • Justera shortlistens storlek tills recall mättas inom latensbudgeten och kombinera med hybridisk retrieval i det första steget.
  • Tillämpa poängtrösklar, skapa mångfald per dokument, ordna chunkar för attention och utvärdera med NDCG samt efterföljande svarsträffsäkerhet.
Gratis att börja

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 ”Omrankning av hämtade textblock” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen AI-promptteknik, inklusive ”Omrankning av hämtade textblock”, 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 ”Omrankning av hämtade textblock”?

Omrankning med cross-encoder. 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 2 av 4.

Hur lång tid tar lektionen ”Omrankning av hämtade textblock”?

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

  1. Bortom naiv RAG
  2. Omrankning av hämtade textblock
  3. Kontextkomprimering
  4. Omskrivning av frågor och HyDE
← Tillbaka till AI-promptteknik