직접 검색을 선제적으로 하고 토큰 수 제한 등 전처리를 하고 싶다면, RetrievalQA 구조와 맞지 않아 우회를 해야한다.
복잡스럽긴 하지만 뭐... 돌아간다.
유사도 검색 상위 10개가 컨텍스트에 포함된다.
docs = vectorstore.similarity_search(query, k=10)
filtered_docs = truncate_docs_to_token_limit(docs, max_tokens=1500, tokenizer=tokenizer)
context = "\n\n".join([doc.page_content for doc in filtered_docs])
template = """다음은 질문에 대한 참고 문서입니다:
{context}
질문: {question}
답변:"""
prompt = PromptTemplate.from_template(template)
rag_chain = LLMChain(llm=llm, prompt=prompt)
response = rag_chain.invoke({
"question": query,
"context": context
})
search_type 가 없으면 similarity 가 기본값으로 설정된다.
retriever = vectorstore.as_retriever(
search_type="similarity", search_kwargs={"k": 3}
)
search_type | 🔍 설명 | ✅ 장점 | ⚠️ 단점 | 🧩 추천 상황 |
---|---|---|---|---|
similarity (기본값) | 쿼리와 가장 유사한 벡터 k 개 선택 | - 구현이 간단 - 빠르고 효율적 - 대부분의 경우 무난 | - 중복된 내용 가능성 높음 - 정보 다양성 부족 | - 일반적인 문서 검색 - FAQ/지식 베이스 RAG |
mmr (Maximal Marginal Relevance) | 유사도 + 다양성을 함께 고려 | - 중복 줄이고 다양한 문서 반환 - 품질 높은 응답 가능 | - 상대적으로 느림 - fetch_k 파라미터 튜닝 필요 | - 다양한 주제가 섞인 문서 - 중복 회피가 중요한 응답 |
similarity_score_threshold | 유사도 점수가 score_threshold 이상인 문서만 반환 | - 낮은 관련도 문서 필터링 - 정보 정확도 개선 가능 | - 기준값 너무 높으면 문서 없음 - 점수 튜닝 필요 | - 정밀한 검색이 필요한 경우 - 잡음이 많은 DB 환경 |
테스트 환경은 m1 맥북에어 기본형이다.
소설 어린 왕자 중에 "깜짝 놀란 어린 왕자가 꽃들에게 물은 것은?" 으로 질문하였다.
21.54 seconds
16.74 seconds
10.7 seconds
이제 정확도가 떨어진다.
19.3 seconds
16.7 seconds
10.86 seconds
속도는 빠르나 후보군이 더 필요하다.
12.09 seconds
일단... 관련 문서가 없다는 경고와 함께... ㅠ
...
...
...
이후로도 score_threshold 값을 0.001까지 내렸는데 나오지 않았다고 한다. 도와줘...
mmr 의 경우 먼저 후보군을 정하고 거기에서 k값을 통해 중복을 피하면서 결론을 도출하지만 속도 측면에서 유사도 검색과 비교했을때 그닥 차이가 많이 나지는 않았다. similarity_score_threshold 의 경우는 유사도 점수를 찾지 못한 탓에 허무하게 테스트가 끝나고 말았다.