본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 05. 01:53

왜 당신의 RAG 파이프라인은 관계형 질문에 답할 수 없는가 (그리고 우리가 이를 해결한 방법)

요약

표준 RAG가 관계형 질문에 취약한 이유를 데이터 구조적 불일치 관점에서 분석합니다. CRM 데이터와 같은 그래프 구조의 데이터를 처리하기 위해 GraphRAG를 도입하여 정확도와 효율성을 대폭 개선한 사례를 소개합니다.

핵심 포인트

  • 표준 RAG는 단일 청크 기반 조회에는 강하나 다중 엔티티 관계 질문에는 취약함
  • GraphRAG 도입 시 정확도는 25%p 향상되고 토큰 사용량은 86% 감소함
  • CRM 데이터는 평면적 텍text 저장소가 아닌 그래프 구조로 접근해야 함
  • 관계형 질문 해결의 핵심은 코사인 유사도가 아닌 에지(Edge) 순회 능력임

Team BroCode · TigerGraph GraphRAG Inference Hackathon 2026

우리는 90개의 CRM 질문에 대해 세 가지 검색 파이프라인 (retrieval pipelines)을 실행했습니다. 동일한 LLM, 동일한 데이터를 사용했으며 오직 검색 방식만 변경되었습니다.

GraphRAG: 정확도 96.7%, 평균 프롬프트 토큰(avg prompt tokens) 1,483개.
BasicRAG: 정확도 71.1%, 평균 프롬프트 토큰(avg prompt tokens) 10,867개.

토큰은 86% 감소했습니다. 정확도는 25%포인트 향상되었습니다. 속도는 17.5% 더 빨라졌습니다.

이 격차는 튜닝 (tuning)의 문제가 아닙니다. 기하학 (geometry)의 문제입니다. 여기 전체 기술적 스토리가 있습니다.

문제점: CRM 데이터는 문서 저장소 (Document Store)가 아니라 그래프 (Graph)입니다

표준 RAG는 지식 베이스를 임베딩 유사도 (embedding similarity)에 따라 순위가 매겨진 텍스트 청크 (text chunks)의 더미로 취급합니다. 이는 "Gold 등급 벤더의 SLA는 무엇인가요?" 와 같은 사실적 조회 (factual lookups)에는 효과적입니다. 즉, 하나의 청크에서 하나의 답변을 찾는 방식입니다.

하지만 관계형 질문 (relationship questions)에서는 완전히 무너집니다.

질문 예시: "공유된 벤더와 지역을 통해 OUTAGE-001의 영향을 받은 고객은 누구인가요?"

이 답변을 포함하고 있는 단일 문서는 존재하지 않습니다. 답변은 다음과 같은 순회 (traversal)를 통해 얻어집니다:

OUTAGE-001 → REGION-FRANKFURT → VEND-01 → [250명의 고객]

평면적인 코사인 유사도 (cosine similarity)는 OUTAGE-001을 언급하는 청크들을 찾아낼 뿐입니다. 해당 에지 (edge)를 따라 지역 (region)으로 이동하고, 다시 다른 에지를 따라 벤더 (vendor)로 이동한 뒤, 해당 벤더에 속한 모든 고객을 집계하는 메커니즘이 없습니다. 이것은 검색 품질의 문제가 아니라, 검색 방법과 데이터의 형태 사이의 구조적 불일치 (structural mismatch) 문제입니다.

CRM은 근본적으로 그래프입니다. 고객은 벤더에 의존합니다. 벤더는 특정 지역에서 운영됩니다. 장애 (outages)는 특정 지역의 벤더에 영향을 미칩니다. 티켓 (tickets)은 고객으로부터 에스컬레이션 (escalate)됩니다. 만약 당신의 검색 방식이 이러한 에지들을 모델링하지 못한다면, 대부분의 신호 (signal)를 놓치게 되는 것입니다.

우리가 실시한 정직한 테스트: 우리는 BasicRAG에 동일한 CRM 코퍼스 (corpus)로 구축된 풍부한 자원을 가진 평면 벡터 인덱스 (flat-vector index)를 제공했습니다. 모든 평가 엔티티 (eval entity)의 문서가 포함되어 있었습니다. 그럼에도 불구하고 BasicRAG는 71.1%에서 멈췄습니다. 실패 원인은 커버리지 (coverage) 문제가 아닙니다. 압도적인 대다수의 실패는 다중 엔티티 관계 질문 (multi-entity relationship questions)에서 발생했습니다. 즉, 평면 검색 (flat search)으로는 따라갈 수 없는 에지 순회가 필요한 질문들입니다.

데이터셋: 상호 연결된 158M 토큰의 CRM 데이터

우리는 다음과 같은 엔티티 (Entity) 유형을 가지며 모두 서로 연결된 합성 CRM 지식 베이스를 구축했습니다:

엔티티 (Entity)개수주요 관계
고객 (Customers)250→ 공급업체 (Vendors) (주요 + 보조), → 지역 (Regions), → 티켓 (Tickets), → 프로젝트 (Projects)
...

총합: 100,820개의 문서에 걸친 158.5M 토큰이며, TigerGraph의 네이티브 HNSW 인덱스를 통해 **577,175개의 벡터 청크 (vector chunks)**로 임베딩되었습니다. 토큰 수는 Gemini count_tokens API를 통해 검증되었으며, 이는 해커톤 최소 기준인 100M의 1.58배입니다.

모든 관계는 TigerGraph에서 탐색 가능한 에지 (edge)입니다. 메타데이터 (metadata)가 아닙니다. 필터 (filter)도 아닙니다. 바로 에지 (edge)입니다.

TigerGraph 스키마 (Schema)

스키마는 CRM 도메인에 직접 매핑됩니다. 정점 (Vertex) 유형은 다음과 같습니다:

CREATE VERTEX Customer (PRIMARY_ID id STRING, name STRING,
  industry STRING, segment STRING, arr FLOAT, health_score INT,
  renewal_date STRING)
...

에지 (Edge) 유형은 관계를 인코딩합니다:

CREATE DIRECTED EDGE depends_on (FROM Customer, TO Vendor)
CREATE DIRECTED EDGE experienced (FROM Vendor, TO Outage)
CREATE DIRECTED EDGE located_in (FROM Customer, TO Region)
...

HNSW 벡터 인덱스는 Document 정점 (vertex)에 위치하며, gemini-embedding-001을 통해 768차원 임베딩을 생성합니다. 검색은 문서에서 시작하여, 소유 엔티티 (entity)로 거슬러 올라간 뒤 해당 엔티티의 에지 (edge)를 따라 확장됩니다.

검색 파이프라인 (Retrieval Pipeline): 2단계 그래프 탐색

모든 유입 질문은 다음 흐름을 거칩니다:

1단계 — 벡터 시드 (Vector Seed)

gemini-embedding-001 (768차원)을 사용하여 질문을 임베딩합니다. TigerGraph의 네이티브 HNSW 인덱스를 쿼리하여 가장 유사한 상위 k개의 Document 노드 (node)를 찾습니다. 이를 통해 질문과 의미론적으로 가장 관련이 깊은 그래프 내 노드인 시드 엔티티 (seed entities)를 확보합니다.

SELECT doc_id, cosine_similarity(embedding, @query_embedding) AS score
FROM Document
ORDER BY score DESC
...

이것은 최종 답변이 아닙니다. 진입점 (entry point)입니다.

Phase 2 — 멀티홉 탐색 (Multi-Hop Traversal)

각 시드 엔티티(seed entity)로부터 타입이 지정된 엣지(typed edges)를 따라 GSQL 탐색을 실행하여 연결된 컨텍스트를 수집합니다. 여기서 어큐뮬레이터(accumulators)에 주목하십시오. SetAccum은 노드 재방문을 방지하며, MapAccum은 탐색 중 홉 거리(hop distance)에 따라 청크(chunk)의 점수를 매깁니다. 이는 단순한 홉 확장(hop expansion)이 아니라, 검색 시점에 발생하는 그래프 연산(graph computation)입니다:

CREATE QUERY getRelevantContext(STRING entity_id, INT k) {
  SetAccum<VERTEX> @@visited;
  MapAccum<STRING, FLOAT> @@chunkScores;
...

OUTAGE-001에 관한 질문의 경우: 시드가 정전(outage) 문서를 찾습니다. 홉 1(Hop 1)은 공급업체(vendor)와 지역(region)으로 탐색합니다 (점수 1.0). 홉 2(Hop 2)는 공급업체에서 고객(customers)으로, 그리고 지역에서 다른 영향을 받은 엔티티(affected entities)로 탐색합니다 (점수 0.5). 우리는 577,000개의 모든 청크가 아니라, 이 질문과 연결된 서브그래프(subgraph)만을 수집합니다.

결과는 약 1,483 토큰의 프롬프트로 조립됩니다. 압축적이고, 관련성이 높으며, 구조적으로 완전합니다.

Phase 3 — 재순위화(Rerank) + 생성(Generate)

검색된 청크들은 관련성에 따라 재순위화(rerank)됩니다 (Groq 기반 재순위화기, 청크별 병렬 처리). 상위 청크들은 생성을 위해 Gemini 2.5 Flash로 전달됩니다. 전체 파이프라인 소요 시간: 평균 약 7.5초.

평가: 우리가 스스로 채점하지 않았음을 어떻게 보장했는가

벤치마크의 정직함을 유지하기 위한 세 가지 의도적인 선택:

1. 독립적인 판사 모델 (Independent judge model). Groq Llama 3.1 8B Instant가 참조 답변(reference answers)을 바탕으로 PASS/FAIL을 할당합니다. 생성 모델(Gemini)과는 다른 모델 계열을 사용하여 자기 채점 편향(self-scoring bias)을 제거했습니다. 판사 모델은 어떤 파이프라인이 어떤 답변을 생성했는지 절대 알 수 없습니다.

2. 세 파이프라인 모두에 동일한 LLM 사용. Gemini 2.5 Flash가 LLM-Only, BasicRAG, GraphRAG의 모든 답변을 생성합니다. 유일한 변수는 검색(retrieval) 단계에서 무엇을 전달하느냐입니다. 정확도의 차이가 발생한다면 그것은 모델의 품질이 아니라 검색의 품질 차이입니다.

3. 표준 BERTScore (Canonical BERTScore). HuggingFace의 bert_score 라이브러리, roberta-large, rescale_with_baseline=True를 사용하며, 이는 공식 루브릭(rubric) 설정과 정확히 일치합니다:

from bert_score import score
P, R, F1 = score(
    candidates,
...

결과:

지표GraphRAGBasicRAGLLM-Only
LLM-judge 정확도96.7% (87/90)71.1% (64/90)3.3% (3/90)
...
GraphRAG는 BERTScore의 두 가지 기준치(rescaled ≥0.55 및 raw ≥0.88)를 모두 통과했습니다.

3가지 솔직한 실패 사례

90/90이 아닌 87/90입니다. 이 3가지 실패 사례는 그래프 RAG (Graph RAG)가 여전히 개선할 여지가 어디에 있는지를 정확히 보여주기 때문에 설명할 가치가 있습니다.

세 사례 모두 어려운 멀티홉 집계 (hard multi-hop aggregation) 질문이었습니다. 예시:

"REGION-FRANKFURT 지역에서 OUTAGE-001에 의해 영향을 받은 프로젝트는 몇 개인가요?"

이 질문은 다음 과정을 필요로 합니다: OUTAGE-001 찾기 → REGION-FRANKFURT로 이동(traverse) → 해당 지역의 프로젝트 필터링 → OUTAGE-001과 연결된 프로젝트만 카운트. 이는 조인 필터 (join filter)와 마지막 단계의 집계 (aggregation)가 포함된 멀티홉 경로입니다.

현재 우리의 GSQL 탐색 (traversal)은 깊이 제한이 있는 깊이 우선 탐색 (depth-first hop expansion) 방식을 사용합니다. 이는 연결된 서브그래프 (subgraph)를 수집하지만, 조인 조건을 명시적으로 표현하지는 않습니다. 따라서 LLM은 올바른 원시 데이터 (raw data)를 받지만, 집계 추론 (aggregation inference)을 직접 더 많이 수행해야 하며, 이 과정에서 가끔 오류를 범합니다.

해결책은 쿼리 유형을 인식하는 GSQL (query-type-aware GSQL)입니다. 즉, 현재 사용 중인 범용적인 홉 확장 (hop expansion) 방식 대신, 집계 패턴에 특화된 특정 탐색 방식을 작성하는 것입니다. 이는 로드맵에 포함되어 있습니다.

TigerGraph에 대해 배운 점 (진실된 이야기)

하나의 엔진에 HNSW와 GSQL이 통합되어 있다는 점이 실제 차별점입니다. 우리가 고려했던 모든 경쟁사 방식은 유사도 검색 (similarity search)을 위한 벡터 DB (vector DB)와 탐색 (traversal)을 위한 그래프 DB (graph DB)라는 두 개의 시스템을 필요로 했습니다. TigerGraph는 이 두 가지를 네이티브하게 수행합니다. 이는 마케팅 문구가 아니라, 2단계 검색 파이프라인 (two-phase retrieval pipeline)을 실제로 구축할 수 있게 만든 핵심 요소입니다.

GSQL 어큐뮬레이터 (accumulators)는 이해하는 데 시간이 걸리지만, 일단 익숙해지면 매우 강력해집니다. SumAccum, SetAccum, MapAccum 등은 SQL의 집계와는 다릅니다. 이는 탐색 과정 중에 발생하는 누적 (accumulation)입니다. SQL처럼 작성하려는 시도를 멈추고 "그래프를 따라 이동하면서 무엇을 누적할 것인가"라고 생각하기 시작하면, 멀티홉 집계 쿼리가 자연스럽게 풀릴 것입니다.

Community Edition (CE)는 진정으로 프로덕션 환경에서 사용 가능합니다. 우리는 CE의 어떤 제한 사항에도 걸리지 않고 100,820개의 문서와 577K개의 HNSW 인덱싱된 청크(chunks)를 실행했습니다. 네이티브 벡터 인덱스(native vector index)가 모든 검색(retrieval)을 처리했습니다. 외부 벡터 DB도, 관리형 클라우드(managed cloud)도 필요 없었습니다. 단 하나의 Docker 컨테이너면 충분했습니다.

우리가 겪었던 인프라 장애 — 그리고 이를 통해 배운 점. 임베딩(embedding) 도중 컨테이너가 비정상적으로 종료되어 한 번 gstore가 손상된 적이 있습니다. 전체 재구축(rebuild) 과정을 잃었습니다. 여기서 얻은 교훈은 다음과 같습니다: 평가(evaluation)를 실행하기 전, 임베딩이 완료된 직후에 즉시 gstore의 스냅샷(snapshot)을 찍으십시오. 우리는 자가 치유(self-healing) 와처(watcher) 스크립트와 복구 절차를 구축했습니다. 이 기능들은 리포지토리(repo)에 포함되어 있습니다.

시간적 여유가 더 있다면 시도할 것들:

  • 쿼리 유형을 인식하는 GSQL (집계(aggregation) vs 조회(lookup) vs 비교(comparison)를 위한 특정 트래버설(traversal))
  • 쿼리 복잡도 분류에 기반한 적응형 홉 깊이(adaptive hop depth)
  • 신뢰 구간(confidence intervals)을 좁히기 위한 200개 이상의 평가(eval) 질문
  • 쿼리 실행 전 벤더 리스크 클러스터(vendor risk clusters)를 식별하기 위한 커뮤니티 탐지(Community Detection) 단계

구조적 시사점 (The Structural Takeaway)

평면적 유사도(Flat similarity)는 한 가지를 잘 수행합니다. 바로 사용자의 쿼리와 유사해 보이는 텍스트를 찾는 것입니다. 내부 관계가 없는 문서 코퍼스(corpus)의 경우, 그것이 올바른 도구입니다.

하지만 정답이 엔티티(entities) 사이, 즉 엣지(edges)에 존재하는 데이터의 경우, 해당 엣지를 따라갈 수 있는 검색(retrieval)이 필요합니다. 이는 그래프 RAG(Graph RAG)가 더 최신이거나 더 복잡하기 때문이 아닙니다. 검색의 구조가 데이터의 구조와 일치해야 하기 때문입니다.

평면적 RAG(Flat RAG)를 사용해야 할 때: 문서 QA, 독립적인 사실들로 구성된 지식 베이스(knowledge bases), 청크(chunk)별로 내용이 완결된 텍스트.

그래프 RAG(Graph RAG)를 사용해야 할 때: 엔티티 간에 타입화된 관계(typed relationships)가 존재하는 모든 도메인 — CRM, 공급망(supply chain), 보안 사고 그래프(security incident graphs), 금융 네트워크, 헬스케어. 만약 질문에 "~을 통해(through)", "~을 거쳐(via)", "~와 관련된(related to)", "~의 영향을 받는(impacted by)", "~에 따라(depending on)"와 같은 표현이 포함되어 있다면, 그것은 유사도 질문이 아니라 트래버설(traversal) 질문입니다.

스택 (Stack)

계층 (Layer)기술 (Technology)
그래프 DB (Graph DB)TigerGraph Community Edition 4.2 (Docker)
...

GitHub: github.com/vishnu-k-dev/crm-nexus
라이브 대시보드 (Live dashboard): crm-nexus-team-brocode.vercel.app

TigerGraph GraphRAG 추론 해커톤 2026을 위해 제작됨 — 팀 BroCode

#TigerGraph #GraphRAG #그래프데이터베이스 #LLM #RAG #GSQL #벡터검색

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0