Vector Database & Retrieval
의미 기반 검색을 가능하게 하는 벡터 DB의 원리, 임베딩 모델, 검색 알고리즘.
설명
벡터 임베딩의 원리
텍스트를 고차원 벡터로 변환하면, 의미적으로 유사한 텍스트는 벡터 공간에서도 가깝다.
텍스트 1: "Apple의 분기별 매출"
텍스트 2: "Apple의 분기별 수익"
텍스트 3: "삼성의 분기별 매출"
임베딩 후:
- 텍스트1, 텍스트2: 벡터 거리 가깜 (의미 유사)
- 텍스트1, 텍스트3: 벡터 거리 멈 (회사는 다름)
임베딩 모델 선택
| 모델 | 언어 | 차원 | 용도 | 비용 |
|---|---|---|---|---|
| OpenAI text-embedding-3-small | 영어+다언어 | 1536 | 일반용 | 가장 저렴 |
| OpenAI text-embedding-3-large | 영어+다언어 | 3072 | 고정확 | 중간 |
| sentence-transformers | 무료, 다언어 | 768 | 로컬 운영 | 0원 (단 성능 약간 ↓) |
| Cohere Embed | 다언어 | 1024 | RAG 특화 | 중간 |
선택 기준:
- 공개 데이터 + 영어: OpenAI embedding-3-small (비용 효율)
- 도메인 특화: 해당 분야 fine-tuned 모델
- 로컬 운영: sentence-transformers (비용 0원)
벡터 DB의 검색 알고리즘
1. Brute Force (전수 비교)
모든 벡터와 거리 계산. 정확하지만 느림.
2. HNSW (Hierarchical Navigable Small World)
그래프 기반 검색. 빠르고 정확 (Pinecone 기본값).
검색 과정:
1. 상위 계층에서 대략 위치 파악
2. 점진적으로 하위 계층으로 내려감
3. 최종 단계에서 정확한 이웃 찾음
특징: O(log n) 시간, 높은 정확도
3. IVF (Inverted File)
클러스터링 기반. 빠르지만 정확도는 HNSW보다 낮음.
4. PQ (Product Quantization)
벡터 압축으로 메모리 절감. 대규모 데이터셋에 유용.
Metadata Filtering (메타데이터 필터)
벡터 검색 + 필터 조합:
Query: "Apple 매출" + Filter: "date >= 2024-01-01"
결과: 벡터 유사도 높으면서, 2024년 이후 문서만
예시:
- “최근 6개월 뉴스”:
date >= 2024-11-27 - “신뢰도 높은 소스”:
source in [reuters, ap, bbc] - “영어 문서만”:
language == en
청킹 역설 (Chunking Paradox)
문제
청크 크기의 트레이드오프:
| 크기 | 장점 | 단점 |
|---|---|---|
| 작음 (50 토큰) | 정확한 정보 | 맥락 손실 → 검색 오류 ↑ |
| 중간 (256-512 토큰) | 균형 | — |
| 큼 (2000 토큰) | 풍부한 맥락 | 노이즈 → 마찬가지로 오류 ↑ |
해결책
1. Ragas Context Recall로 튜닝
from ragas.metrics import context_recall
# 여러 청크 크기로 평가
for chunk_size in [128, 256, 512, 1024]:
score = context_recall(dataset, chunk_size)
print(f"Size {chunk_size}: {score}")2. Semantic 청킹
의미적 경계에서 분할:
원본:
"...머신러닝의 정의는... 신경망의 작동은..."
↓ Semantic Chunking
청크1: "머신러닝의 정의는..."
청크2: "신경망의 작동은..."
3. 중복 청킹 (Sliding Window)
청크 간 겹침으로 경계 정보 보존:
청크1: [문장1, 문장2, 문장3]
청크2: [문장2, 문장3, 문장4]
청크3: [문장3, 문장4, 문장5]
Retrieval 전략
1. Semantic Search (의미 검색)
벡터 유사도 기반:
Query: "Apple의 최신 이익"
↓ 임베딩 변환
Query Vector: [0.24, -0.14, 0.91, ...]
↓ 유사도 계산
Results: [벡터1 (cos=0.92), 벡터2 (cos=0.88), ...]
강점: 의미 이해 (paraphrase 포착) 약점: 아크로님, 숫자 약함
2. Lexical Search (키워드)
BM25 알고리즘:
Query: "Apple Q1 revenue"
↓ 토큰화
Terms: [apple, q1, revenue]
↓ BM25 점수 계산
Results: 모든 용어 포함 문서 우선
강점: 정확한 용어, 숫자 약점: 동의어 미포착 (“profit” vs “revenue”)
3. Hybrid Search (하이브리드)
의미 + 키워드 조합:
최종 점수 = α × semantic_score + (1-α) × lexical_score
(권장 α=0.7, 의미 중심)
효과:
- 도메인 용어 포착율 ↑
- 의미 이해도 ↑
- 일반적으로 가장 높은 정확도
4. Reranking (재순위화)
검색 결과를 더 정교한 모델로 재평가:
초기 검색 (10개 결과)
↓ Reranker (Cohere, BGE-reranker)
최종 순위 (5개, 더 정확)
효과: 노이즈 감소, Context Precision ↑
메타데이터 전략
효과적인 메타데이터
document = {
"content": "Apple의 2024년 Q1 매출은 93.7B USD",
"metadata": {
"date": "2024-01-30",
"source": "Apple Inc Investor Relations",
"quarter": "Q1",
"year": 2024,
"reliability": "official",
"tags": ["earnings", "apple", "financial"]
}
}필터 활용 시나리오
# 최근 3개월 공식 발표만
results = vector_db.search(
query_vector,
filter={
"date": {"$gte": "2026-01-27"},
"reliability": {"$in": ["official", "verified"]}
}
)관련 개념
- rag — RAG의 Retrieval 단계와 벡터 DB의 역할
- agentic-ai-patterns — 에이전트의 Tool로서 검색