30

Hybrid Retrieval 심화: Vector + Graph + Keyword 3-way 통합

GraphRAG 통합

학습 목표

Vector/Graph/Keyword 검색의 강점을 비교한다 Reranking과 Score Fusion 기법을 이해한다 제조 도메인의 실전 하이브리드 아키텍처를 설계할 수 있다

한 가지 검색 방식만으로는 부족하다

실무에서 만나는 질문은 다양하다. 각 질문 유형에 가장 잘 맞는 검색 방식이 다르다.

질문 1: "3호기 E-201 알람 원인은?"
  → 정확한 관계 추론 → Graph 검색이 최강

질문 2: "스핀들이 떨릴 때 매뉴얼에 뭐라고 나와있어?"
  → 의미 유사도 → Vector 검색이 최강

질문 3: "BRG-6205-2RS 부품번호 검색"
  → 정확 매칭 → Keyword(역색인) 검색이 최강

3가지를 다 쓰는 것이 Hybrid Retrieval.


3-way 통합 아키텍처

[사용자 질문]
    ↓
[Query Router] — 질문 유형 분류 (LLM 또는 규칙)
    ↓
├─ Vector 검색 (Neo4jVector / Pinecone)
│   → 임베딩 유사도 Top-5
├─ Graph 검색 (Neo4j Cypher)
│   → 관계 기반 결과
└─ Keyword 검색 (Elasticsearch / PostgreSQL FTS)
    → 정확 매칭 Top-5
    ↓
[Score Fusion] — 결과 통합
    ↓
[Reranker] — 최종 순위 결정 (Cross-Encoder)
    ↓
[LLM Generator] — 답변 생성

Score Fusion 기법

다른 검색 방식의 점수를 어떻게 결합할까?

방법 1: Reciprocal Rank Fusion (RRF)

def rrf_fusion(rankings: dict, k: int = 60) -> dict:
    """각 검색기의 순위를 기반으로 통합 점수 계산
    rankings = {
      "vector": [doc_id_a, doc_id_b, ...],
      "graph":  [doc_id_c, doc_id_a, ...],
      "keyword": [doc_id_d, doc_id_b, ...]
    }
    """
    scores = {}
    for source, ranked_docs in rankings.items():
        for rank, doc_id in enumerate(ranked_docs):
            scores[doc_id] = scores.get(doc_id, 0) + 1.0 / (k + rank + 1)
    return dict(sorted(scores.items(), key=lambda x: -x[1]))

장점: 점수 스케일이 달라도 작동, 구현 간단.

방법 2: Weighted Fusion

def weighted_fusion(scores: dict, weights: dict) -> dict:
    """가중치를 두어 결합
    weights = {"vector": 0.5, "graph": 0.3, "keyword": 0.2}
    """
    combined = {}
    for source, doc_scores in scores.items():
        w = weights.get(source, 1.0)
        for doc_id, score in doc_scores.items():
            combined[doc_id] = combined.get(doc_id, 0) + w * score
    return combined

장점: 도메인 지식 반영 가능 (제조에서는 Graph 비중을 높임).


Reranking: 최종 순위 결정

Fusion 후에도 상위 N개 후보가 남는다. Cross-Encoder가 마지막 정렬.

from sentence_transformers import CrossEncoder

reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')

def rerank(query: str, candidates: list, top_k: int = 5):
    pairs = [(query, doc) for doc in candidates]
    scores = reranker.predict(pairs)
    ranked = sorted(zip(candidates, scores), key=lambda x: -x[1])
    return [doc for doc, _ in ranked[:top_k]]

효과: 검색 정확도 10~30% 향상 (벤치마크 기준).


Query Router의 역할

질문 유형을 미리 분류하여 적절한 검색기에만 호출.

ROUTER_PROMPT = """제조 현장 질문을 분류:
- "factual": 특정 사실 (예: 부품 번호, 알람 코드)  → Keyword 우선
- "relational": 관계/원인/영향 (예: 원인 추적)        → Graph 우선
- "semantic": 의미 유사 (예: 증상 매뉴얼 검색)        → Vector 우선
- "hybrid": 위의 조합 필요                            → 3가지 모두

질문: {query}
응답: factual/relational/semantic/hybrid 중 하나
"""

제조 도메인 권장 가중치

경험적으로 다음 비율이 잘 작동한다:

질문 유형VectorGraphKeyword
진단/원인 추적0.20.60.2
매뉴얼 검색0.60.10.3
부품/코드 조회0.10.20.7
일반 Q&A0.40.30.3

핵심 정리

1. 단일 검색기에 의존하지 마라 → 질문 유형이 다양함
2. Router로 비용 최적화 → 모든 검색기를 매번 부르지 마라
3. RRF는 가장 간단하고 robust한 fusion 방법
4. Reranker는 정확도를 한 번 더 끌어올린다
5. 제조 진단 질문은 Graph 비중을 0.6 이상으로

이번 주는 Graph 위주, Week 8에서 Vector 결합 + Reranker를 추가한다.

AI로 학습하기 — 꿀팁
🧪3-way 검색 스코어 퓨전 제조 적용AI 학습 팁

Vector+Graph+Keyword 3-way 검색 결과를 제조 Q&A에서 어떻게 융합할지 구체적인 전략을 AI에게 요청하세요.

제조 설비 Q&A 시스템에서 Vector 검색(의미 유사도), Graph 탐색(관계 경로), Keyword 검색(BM25) 세 결과를 Reciprocal Rank Fusion(RRF)으로 통합하는 방법을 설명해줘. 각 검색의 가중치를 어떻게 조정하는 것이 제조 도메인에 유리한지, 실제 Python 코드 예시도 포함해줘.
이 팁이 도움이 됐나요?
핵심 포인트
  • Hybrid Retrieval = Vector(의미) + Graph(관계) + Keyword(정확)
  • RRF는 점수 스케일 차이를 흡수하는 가장 견고한 fusion 기법
  • Cross-Encoder Reranker로 정확도 10~30% 추가 향상 가능
  • 제조 진단 질문에서는 Graph 가중치가 가장 높아야 함