검색된 청크 재순위화
교차 인코더 재순위화
검색된 청크 재순위화은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
애초에 왜 재순위화할까요
1단계 검색(밀집 또는 희소)은 규모에 맞는 재현율을 최적화합니다. 즉, 정답 청크가 상위 50개 어딘가에 포함되도록 합니다. 빠르지만 대략적입니다. 그런 다음 2단계 재순위화기가 후보 목록을 다시 정렬하여 정밀도를 높이고, 실제로 관련성이 높은 청크를 위로 올립니다.
폭넓게 검색한 다음 정밀하게 재순위화하는 패턴은 고급 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: 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교차 인코더의 재순위화 단계
재순위화기는 쿼리에 대한 각 후보의 점수를 계산한 다음 내림차순으로 정렬합니다. 교차 인코더는 쿼리와 문서를 함께 처리하므로 이중 인코더가 놓친 미묘한 관련성, 즉 부정 표현, 정확한 일치가 필요한 경우, 답변과 주제의 차이를 판별합니다.
이 단계는 일반적으로 다른 어떤 단일 RAG 개선 방법보다 답변 정확도를 크게 높입니다.
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
학습된 교차 인코더가 분야에 맞지 않을 때는 LLM으로 재순위화할 수 있습니다. 목록 단위 프롬프트는 한 번의 호출로 문단 목록을 관련성 순서대로 정하도록 요청하고, 항목 단위 방식은 각 문단을 독립적으로 평가합니다.
목록 단위 방식은 상대적인 비교를 포착하고 토큰을 효율적으로 사용하지만, 위치 편향에 주의하고 모델이 식별자를 누락하거나 중복하더라도 출력 분석이 견고하게 이루어지도록 하십시오.
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]지연 시간과 후보 목록 크기
재순위 지정 비용은 후보 목록 크기에 따라 증가합니다. 50개의 후보에 교차 인코더를 적용하는 비용은 500개에 적용하는 것보다 훨씬 저렴합니다. 정답 청크를 포착할 수 있을 만큼 첫 단계의 k를 크게 설정하고(재현율@k를 검증하십시오), 지연 시간 예산 내에서 재순위 지정을 수행할 수 있을 만큼 작게 설정하십시오.
쌍별 점수 계산을 일괄 처리하고 가속 하드웨어에서 실행하십시오. 교차 인코더는 여러 쌍에 걸쳐 병렬화가 잘 됩니다.
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}하이브리드 1단계와 재순위화
가장 높은 재현율은 하이브리드 1단계(밀집 검색과 BM25를 융합한 방식)를 사용하고, 중복을 제거한 하나의 후보 목록을 재순위화기에 전달할 때 얻을 수 있습니다. 밀집 검색은 바꿔 말한 표현을 찾아내고, 희소 검색은 정확한 식별자를 찾아내며, 그런 다음 교차 인코더가 두 결과의 합집합을 실제 관련성에 따라 정렬합니다.
이 조합은 자연어 질문부터 문자 그대로 조회하는 경우까지 다양한 질의 유형에서 견고하게 작동합니다.
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]점수 임계값과 기준선
재순위화기 점수는 보정할 수 있습니다. 항상 상위 n개를 선택하는 대신 관련성 임계값을 적용하십시오. 점수 기준을 넘는 청크만 유지하고, 조건을 충족하는 항목이 하나도 없으면 정직하게 답변 없음을 반환하십시오. 이렇게 하면 프롬프트가 관련성이 약한 채우기용 내용으로 가득 차는 것을 막을 수 있습니다.
검증 세트에서 임계값을 조정하여 답변 가능한 범위와 방해 요소 포함 사이의 균형을 맞추십시오.
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재순위화 후의 다양성
관련성만을 기준으로 정렬하면 같은 문서에서 거의 중복되는 청크가 여러 개 반환되어 문맥 예산을 낭비할 수 있습니다. 재순위화 후에 MMR이나 문서별 상한을 적용하여 최종 집합이 서로 다른 측면과 출처를 포함하도록 하십시오.
이는 answer가 여러 문서에 걸쳐 있는 다중 홉 질문에서 중요합니다.
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생성기를 위한 순서 지정
상위 청크를 선택한 후 어텐션을 활용하도록 청크를 배치하십시오. 중간 손실 현상을 고려하면, 점수가 가장 높은 단일 청크를 다른 청크 사이에 묻지 말고 문맥의 시작이나 끝에 배치하십시오.
일부 pipeline에서는 관련성이 낮은 순서로 청크를 배치하여 가장 좋은 청크가 질문에 가장 가까이 오도록 합니다. 이는 몇 개의 예시를 사용하는 최신성 전략과 비슷합니다.
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재순위화기 평가
레이블이 지정된 질의-청크 관련성을 기준으로 순위 평가 지표, 주로 NDCG와 MRR을 측정한 다음 후속 answer 정확도를 측정하십시오. NDCG는 높였지만 answer 정확도는 높이지 못한 재순위화기는 생성기가 이미 처리한 청크의 순서만 바꾼 것일 수 있습니다.
순위 평가 지표뿐 아니라 최종 작업 품질까지 항상 확인하십시오.
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운영 환경의 재순위화 pipeline
처음부터 끝까지의 과정은 다음과 같습니다. 하이브리드 방식으로 50개 후보의 짧은 목록을 검색하고, 중복을 제거한 뒤, 교차 인코더로 재순위화하고, 점수 임계값을 적용하고, 문서별로 다양화하고, 어텐션을 고려해 순서를 지정한 다음, 인용을 포함해 생성합니다. 임계값을 기준으로 조건을 적용하여 정직하게 답변 없음을 반환하십시오.
트래픽이 반복되는 경우 (질의, 청크)별 임베딩과 재순위화기 점수를 캐시하여 비용을 줄이십시오.
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)빠른 확인
올바른 재순위화 아키텍처를 선택하십시오.
요약
핵심 요점:
- 재현율을 위해 폭넓게 검색한 다음, 정밀도를 위해 후보 목록을 재순위화하십시오.
- 교차 인코더는 질의-문서 쌍을 함께 평가하므로 정확하지만 색인화할 수 없습니다. 이중 인코더는 빠르지만 거칠게 평가합니다.
- LLM의 목록 단위/점 단위 재순위화는 대체 수단입니다. 위치 편향과 구문 분석에 주의하십시오.
- 지연 시간 예산 안에서 재현율이 포화되도록 후보 목록의 크기를 조정하고, 하이브리드 1단계 검색과 결합하십시오.
- 점수 임계값을 적용하고, 문서별로 다양화하고, 어텐션을 고려해 청크 순서를 지정하고, NDCG와 후속 answer 정확도로 평가하십시오.
자주 묻는 질문
“검색된 청크 재순위화” 강의는 무료인가요?
네 — “검색된 청크 재순위화” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
“검색된 청크 재순위화”에서 뭘 배우나요?
교차 인코더 재순위화 브라우저에서 직접 실행하는 실습 코드로 AI Prompt Engineering을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Prompt Engineering을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Prompt Engineering은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“검색된 청크 재순위화” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 단순한 RAG를 넘어서
- 검색된 청크 재순위화
- 컨텍스트 압축
- 질의 재작성과 HyDE