고급 RAG 기법
RAG 성능을 극대화하는 고급 기법들
고급 RAG 기법
기본 RAG를 넘어 성능과 정확도를 높이는 고급 기법들을 알아봅니다.
1. 청킹 전략
시맨틱 청킹
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 의미 단위로 분할
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["
", "
", ".", "!", "?", ",", " "],
length_function=len
)
chunks = splitter.split_documents(documents)
문서 구조 기반 청킹
from langchain.text_splitter import MarkdownHeaderTextSplitter
headers_to_split = [
("#", "header1"),
("##", "header2"),
("###", "header3"),
]
splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=headers_to_split
)
chunks = splitter.split_text(markdown_document)
2. 하이브리드 검색
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
# 키워드 기반 검색
bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 4
# 벡터 기반 검색
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# 앙상블
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.4, 0.6]
)
3. 재순위화 (Re-ranking)
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
reranker = CohereRerank(model="rerank-multilingual-v3.0")
compression_retriever = ContextualCompressionRetriever(
base_compressor=reranker,
base_retriever=vector_retriever
)
# 더 관련성 높은 문서 반환
docs = compression_retriever.invoke("질문")
4. 쿼리 변환
쿼리 확장
from langchain.retrievers import MultiQueryRetriever
multi_query_retriever = MultiQueryRetriever.from_llm(
retriever=vector_retriever,
llm=llm
)
# 여러 변형 쿼리로 검색
docs = multi_query_retriever.invoke("원본 질문")
HyDE (Hypothetical Document Embeddings)
from langchain.chains import HypotheticalDocumentEmbedder
hyde = HypotheticalDocumentEmbedder.from_llm(
llm=llm,
embeddings=embeddings,
prompt_key="web_search"
)
# 가상 문서를 생성하여 검색
docs = hyde.invoke("질문")
5. Self-RAG
class SelfRAG:
def __init__(self, retriever, llm):
self.retriever = retriever
self.llm = llm
def invoke(self, query):
# 1. 검색 필요 여부 판단
if self._needs_retrieval(query):
docs = self.retriever.invoke(query)
# 2. 문서 관련성 평가
relevant_docs = self._filter_relevant(docs, query)
# 3. 답변 생성
answer = self._generate(query, relevant_docs)
# 4. 답변 품질 평가
if self._is_supported(answer, relevant_docs):
return answer
else:
return self._regenerate(query, relevant_docs)
else:
return self.llm.invoke(query)
6. 메타데이터 필터링
# 메타데이터 포함 저장
vectorstore.add_documents([
Document(
page_content="내용",
metadata={
"source": "manual.pdf",
"chapter": 3,
"date": "2024-01-15",
"category": "setup"
}
)
])
# 필터링 검색
docs = vectorstore.similarity_search(
query,
filter={"category": "setup", "chapter": {"$gte": 2}}
)
성능 최적화
- 임베딩 캐싱: 동일 문서 재임베딩 방지
- 배치 처리: 대량 문서 병렬 처리
- 인덱스 최적화: HNSW, IVF 등 적절한 인덱스 선택
- 양자화: 벡터 크기 축소로 속도 향상