Engineering

HyperbolicRAG를 바로 도입하지 않고, hierarchy-aware retrieval부터 검증하기

HyperbolicRAG의 문제의식은 유효하지만, 먼저 검증할 것은 구조 신호 기반 rerank. dense baseline에서 relation-aware rerank까지의 실험 기록.

최근 HyperbolicRAG 류의 글을 보면 문제의식 자체는 꽤 설득력 있습니다.

질문은 단순합니다.

지금 RAG가 놓치는 것은 “유사도”일까, 아니면 “구조”일까?

예를 들어 질의가 만성 스트레스가 면역을 어떻게 약화시키는가일 때, 일반적인 dense retrieval은 종종 건강, 질병, 스트레스 같은 넓은 허브 개념으로 끌려갑니다. 답이 완전히 틀리진 않더라도, 실제로 필요한 경로인 만성 스트레스 -> 코르티솔 -> 림프구 활성 저하 -> 면역 억제를 놓치기 쉽습니다.

이 문제 정의는 유효합니다. 다만 그 해결책이 바로 hyperbolic geometry여야 하는지는 별개의 질문입니다.

이 글은 Schift 엔진 관점에서 그 질문을 정리한 개발 메모입니다. 결론부터 말하면, 지금 우리가 먼저 검증해야 하는 것은 hyperbolic branch가 아니라 hierarchy-aware retrieval입니다.

이 논의가 특히 자연스럽게 붙는 내부 도메인은 법률 코퍼스입니다. 성능과 운영 관점에서 법률형 workload를 먼저 정리한 기록은 법률 데이터 벤치마크에 따로 있습니다.

문제는 이해할 만하다

HyperbolicRAG가 찌르는 핵심은 세 가지입니다.

  • dense similarity만으로는 generic hub에 끌려가기 쉽다
  • multi-hop 질문은 “비슷한 것”보다 “정답 경로에 있는 것”이 더 중요하다
  • 계층적인 지식에서는 구조 신호를 retrieval 점수에 반영해야 한다

이건 우리 문제의식과도 크게 다르지 않습니다.

실제로 Schift는 이미 단일한 flat space만 바라보는 방향으로 가지 않고 있습니다.

  • 모든 임베딩을 canonical 1024d 공간에 정렬하려고 하고
  • global -> sector -> user 구조로 local geometry를 보정하려고 하고
  • 벡터 recall 위에 graph traversal / inference를 얹을 수 있는 엔진 구조를 갖고 있습니다

즉 우리가 바로 버려야 할 것은 flat retrieval only이지, canonical serving space 자체는 아닙니다.

우리가 바로 하이퍼볼릭으로 가지 않는 이유

하이퍼볼릭 표현은 흥미롭지만, 엔진 기본축으로 넣기에는 아직 비용이 큽니다.

첫째, 복잡도가 커집니다.

  • 별도 임베딩 공간
  • 별도 거리 함수
  • 별도 인덱싱/서빙 경로
  • 듀얼 랭킹 병합
  • 평가/디버깅 복잡도 증가

둘째, 개선의 원인이 흐려질 수 있습니다.

하이퍼볼릭 실험에서 좋아졌다고 해도, 실제로는 geometry 자체가 아니라 다음 요소들 덕분일 가능성이 큽니다.

  • 허브 노드 감점
  • 구체적 evidence 가점
  • 구조 경로 보너스
  • multi-hop 전용 rerank

이걸 분리해서 보지 않으면, 비싼 아키텍처를 들여온 뒤에야 “사실 단순한 rerank feature로도 충분했다”는 결론에 도달할 수 있습니다.

셋째, Schift의 차별화 포인트와도 약간 결이 다릅니다.

우리의 강점은 “공간을 하나 더 만드는 것”보다, canonical space를 유지하면서도 sector / user adaptation으로 local geometry를 학습하는 데 있습니다.

한 문장으로 줄이면 이렇습니다.

HyperbolicRAG의 문제의식은 참고하되, Schift는 먼저 adaptive canonical retrieval이 어디까지 갈 수 있는지 증명해야 한다.

지금 먼저 실험할 것

실험 순서는 “가장 싸고 해석 가능한 것”부터 시작합니다.

1. Hub penalty

가장 먼저 넣어볼 신호는 generic hub penalty입니다.

아이디어는 단순합니다.

  • 너무 많은 질의에서 자주 상위 노출되는 노드
  • 그래프에서 degree가 과도하게 높은 노드
  • 특정 도메인에서 지나치게 일반적인 section/chunk/entity

이런 후보는 dense score가 높아도 최종 랭킹에서 약하게 감점합니다.

이 실험은 cheap한데도 효과를 보일 확률이 높습니다. HyperbolicRAG가 지적한 “generic drift”를 가장 직접적으로 겨냥하기 때문입니다.

2. Specificity / depth bonus

다음은 “얼마나 구체적인 evidence인가”를 별도 feature로 주는 것입니다.

예를 들면:

  • heading depth
  • chunk 길이와 밀도
  • entity rarity
  • corpus frequency inverse
  • relation specificity

여기서 중요한 점은 하이퍼볼릭 공간의 “중심=추상, 경계=구체”를 꼭 geometry로 구현할 필요는 없다는 것입니다. 우선은 feature engineering으로도 상당 부분 흉내낼 수 있습니다.

3. Sector-aware rerank

이건 Schift 쪽에서 가장 중요한 실험입니다.

우리는 이미 global -> sector -> user라는 적응 구조를 보고 있기 때문에, retrieval도 이 계층을 반영해야 합니다.

간단한 형태는 이렇습니다.

  • query를 먼저 global canonical에서 recall
  • coarse routing 또는 sector centroid로 sector 후보를 추정
  • sector가 맞는 evidence에 가점
  • 필요하면 sector-local rerank를 추가

이 실험이 잘 되면, “새 geometry”보다 “더 나은 routing + rerank”가 실제 개선의 핵심이라는 증거가 됩니다.

4. Graph-aware rerank

그 다음은 graph traversal / relation support를 랭킹 feature로 써보는 것입니다.

중요한 점은 처음부터 PPR까지 가지 않는 것입니다.

우선은:

  • dense top-N을 seed로 잡고
  • 1-hop / 2-hop edge expansion을 한 뒤
  • relation type별 가중치를 넣고
  • edge support가 있는 후보를 끌어올리는 정도면 충분합니다

이 단계에서 multi-hop 질문이 실제로 좋아지는지 먼저 봐야 합니다.

점수 함수는 이렇게 시작할 수 있다

첫 번째 실험 라운드는 단순해야 합니다.

final_score
= a * dense_score
- b * hub_score
+ c * specificity_score
+ d * sector_match_score
+ e * edge_support_score

여기서 핵심은 “완벽한 이론식”이 아니라 “무엇이 실제 개선을 만드는지 분해 가능한 식”입니다.

어떤 데이터에서 봐야 하나

이 실험은 단일 데이터셋으로 보면 해석을 망칩니다.

최소한 두 그룹이 필요합니다.

Group A: single-hop / 일반 retrieval

예:

  • 일반 문서 QA
  • 단문 fact lookup
  • 명시적인 키워드 + 근접 의미 검색

여기서는 새 feature를 넣어도 성능이 나빠지지 않아야 합니다.

Group B: multi-hop / hierarchy-heavy retrieval

예:

  • HotpotQA
  • 2Wiki
  • MuSiQue
  • 내부 법률/과학/enterprise corpus

여기서는 dense baseline 대비 실제 개선이 보여야 합니다.

특히 법률은 단순한 “문장 유사도 검색” 문제가 아니라:

  • 법률 -> 장 -> 절 -> 조문 계층
  • 조문 간 인용 / 관련 관계
  • 상위 맥락 복원 필요

가 함께 있기 때문에, hierarchy-aware retrieval을 검증하기 좋은 내부 도메인입니다.

무엇을 측정할 것인가

LLM 최종 답변 점수만 보면 원인을 설명할 수 없습니다. retrieval과 answer를 나눠서 봐야 합니다.

Retrieval metrics

  • Recall@5, Recall@10
  • MRR, nDCG
  • generic hit ratio
  • hub hit ratio
  • gold evidence까지의 평균 hop distance

Answer metrics

  • EM, F1
  • citation precision
  • “답은 맞지만 너무 일반적임” 비율

Serving metrics

  • p50, p95 latency
  • rerank overhead
  • index / feature storage overhead

성공 기준

좋은 실험은 종료 기준이 있어야 합니다.

첫 라운드의 성공 기준은 다음 정도가 적당합니다.

  • multi-hop Recall@5 또는 MRR가 baseline 대비 유의미하게 상승
  • single-hop 성능은 유지 또는 미세 손실 이내
  • latency 증가는 10~20% 이내
  • generic / hub hit ratio는 명확히 감소

반대로 아래 상황이면 중단하거나 축소해야 합니다.

  • single-hop 품질 하락이 크다
  • multi-hop 개선이 미미하다
  • latency 비용이 구조적 이득보다 크다

첫 번째 실제 실행 결과

추상적인 얘기로 끝내지 않기 위해, 기존 로컬 PoC 경로에서 가장 작은 diagnostic seed set을 다시 돌려봤습니다.

Dense baseline

BAAI/bge-m3, seed_corpus(16), seed_queries(12) 기준:

  • overall nDCG@10 = 0.9692
  • overall MRR@10 = 0.9583
  • control / polarity / entity는 이미 1.0
  • 약한 구간은 temporal:
    • nDCG@10 = 0.9077
    • MRR@10 = 0.875

즉, 이 작은 세트에서는 dense baseline 자체가 이미 강합니다. 그래서 다음 실험의 질문은 “전체 평균을 더 올릴 수 있나?”보다 “dense가 약한 구조 그룹을 정확히 찌를 수 있나?”가 됩니다.

Relation-aware rerank

같은 seed set에서 manual claim sidecar를 붙인 relation rerank는:

  • overall nDCG@10 = 1.0
  • overall MRR@10 = 1.0
  • 특히 약점이던 temporal 그룹도 1.0으로 회복

이 결과가 의미하는 것은 분명합니다.

  • 적어도 이 diagnostic set에서는
  • 새로운 geometry 없이도
  • 구조 신호를 얹은 rerank만으로 dense의 약점을 메울 수 있습니다

물론 이 결과만으로 일반화할 수는 없습니다. seed set은 작고, 손으로 설계된 failure mode가 강하기 때문입니다. 하지만 출발점으로는 충분합니다.

Hard eval

hard_eval_corpus(350), hard_eval_queries(200) 기준 dense baseline은:

  • overall nDCG@10 = 0.9830
  • overall MRR@10 = 0.9775
  • 가장 약한 구간은 다시 temporal:
    • nDCG@10 = 0.9336
    • MRR@10 = 0.91

같은 세트에서 auto-generated sidecar 기반 relation rerank를 붙이면:

  • overall nDCG@10 = 1.0
  • overall MRR@10 = 1.0
  • temporal1.0

이건 중요한 신호입니다. seed에서만 우연히 맞은 것이 아니라, 더 큰 diagnostic set에서도 dense의 약점이 구조 rerank로 메워졌습니다.

하이퍼볼릭은 언제 실험하나

이 모든 단계를 거친 뒤에도 이런 상황이면 hyperbolic PoC를 할 이유가 생깁니다.

  • hub penalty + specificity + sector bias + graph-aware rerank로도 한계가 보인다
  • 특히 hierarchy-heavy / multi-hop 데이터셋에서 추가 개선 여지가 남아 있다
  • 복잡도를 감수할 만한 품질 차이가 기대된다

그때의 실험은 엔진 기본 구조 변경이 아니라, 분리된 연구 경로로 가는 것이 맞습니다.

우리가 실제로 돌릴 순서

이 메모를 실행 계획으로 줄이면 다음과 같습니다.

  1. dense baseline 로그를 먼저 정리한다
  2. hub penalty만 넣은 실험군을 만든다
  3. specificity bonus를 추가한다
  4. sector-aware rerank를 붙인다
  5. graph-aware rerank를 붙인다
  6. 이 조합으로 multi-hop / single-hop을 모두 평가한다
  7. 그래도 부족하면 hyperbolic PoC를 연구 경로로 분리한다

핵심은 간단합니다.

먼저 구조 신호가 필요한지 증명하고, 그 다음에야 어떤 geometry가 필요한지 묻는다.

Ready to try Schift?

Switch embedding models without re-embedding. Start free.

Get started free