728x90
이 글에서는 RAG의 핵심인 벡터 검색의 내부 동작 방식을 집중적으로 살펴봅니다.
특히 벡터 간 유사도 계산, top-k 정렬 기준, 검색 점수(score)의 의미를 시각적으로 이해할 수 있도록 설명드립니다.
❓ 질문: "top-k 검색은 어떻게 작동하나요?"
사용자의 질문도 벡터로 변환되며,
저장된 문서 벡터들과 비교해
가장 유사한 문서 상위 k개(top-k) 를 선택합니다.
그렇다면 유사도는 어떤 기준으로 계산될까요?
🧠 Cosine Similarity: 벡터 간 유사도 측정의 핵심
용어 | 설명 |
Cosine Similarity | 두 벡터가 이루는 각도의 코사인 값을 계산 |
값 범위 | -1 ~ 1 (1에 가까울수록 유사함) |
사용 이유 | 벡터 크기와 무관하게 방향성만 비교 가능 |
예시:
문장 | 코사인 유사도 (예시) |
상품 테이블 | 0.92 |
주문 테이블 | 0.71 |
고객 정보 | 0.48 |
🔍 LangChain에서 top-k 검색 수행하기
# ✅ Retriever 구성 시 top-k 설정
retriever = vectordb.as_retriever(
search_type="similarity", # 기본: 유사도 기반 검색
search_kwargs={"k": 2} # 유사도 상위 2개의 문서 반환
)
🧪 검색 결과 직접 확인하기
# ✅ 사용자 질문 정의
query = "상품 정보를 담고 있는 테이블이 뭐야?"
# ✅ 관련 문서 검색
results = retriever.get_relevant_documents(query)
# ✅ 결과 출력
for i, doc in enumerate(results):
print(f"[결과 {i+1}]\n{doc.page_content}\n")
❗기본적으로 get_relevant_documents()는 유사도 점수를 함께 제공하지 않습니다.
점수가 필요하다면 similarity_search_with_score() 를 사용해야 합니다.
🔎 검색 점수(score)를 확인하는 방법
# ✅ 점수와 함께 검색 결과를 반환
results = vectordb.similarity_search_with_score(query, k=3)
# ✅ 결과 출력
for i, (doc, score) in enumerate(results):
print(f"[결과 {i+1} - 점수: {score:.4f}]")
print(doc.page_content + "\n")
✅ 출력 예시:
[결과 1 - 점수: 0.0837]
📂 테이블명: products
🧾 컬럼 목록:
- product_id (long)
- name (string)
🧩 파티션: category
➡️ 여기서 score는 거리 값입니다.
낮을수록 유사도가 높습니다. (cosine similarity의 distance 기반 변환)
📌 점수 해석 기준 (실무 참고용)
점수 | 범위 해석 |
0.0 ~ 0.1 | 거의 동일한 의미 (매우 강한 관련성) |
0.1 ~ 0.3 | 유사하지만 약간 다른 문맥 |
0.3 이상 | 관련성이 낮음 → 제외 가능 |
※ 실제 사용 환경에 따라 튜닝 필요
⚙️ Retriever 내부 검색 파라미터
설정 키 | 의미 |
k | 반환할 문서 수 |
search_type | similarity / mmr (다양성 고려) |
score_threshold | 유사도 점수가 특정 수치 이상일 때만 포함 |
예시:
retriever = vectordb.as_retriever(
search_type="similarity",
search_kwargs={
"k": 3,
"score_threshold": 0.3 # 점수 0.3 이하 문서만 반환
}
)
📎 요약 및 핵심 정리
- top-k 검색은 질문 벡터와 가장 유사한 문서 벡터를 고르는 방식입니다.
- 기본적으로 Cosine Similarity 기반으로 유사도를 계산합니다.
- similarity_search_with_score()를 사용하면 점수(score)를 확인할 수 있습니다.
- 점수는 낮을수록 유사도가 높습니다.
728x90
'LLM & Generative AI > RAG in Practice' 카테고리의 다른 글
[LangChain RAG 구축 시리즈 Ep.12] 🧵 대화형 검색과 맥락 기억 기능 구현해보기 (1) | 2025.04.05 |
---|---|
[LangChain RAG 구축 시리즈 Ep.11] 🔄 Retrieval QA 실습: 문서 기반 답변 구성 (1) | 2025.04.05 |
[LangChain RAG 구축 시리즈 Ep.09] 🗂️ ChromaDB로 벡터 저장소 구성하기 (1) | 2025.04.05 |
[LangChain RAG 구축 시리즈 Ep.08] 🧠 OpenAI Embedding 실습: JSON을 임베딩해보기 (1) | 2025.04.05 |
[LangChain RAG 구축 시리즈 Ep.07] 💬 사용자 질문을 벡터와 어떻게 매칭할까? (1) | 2025.04.05 |