그래프 RAG
Graph RAG
지식 그래프를 활용한 RAG. 엔티티 간 관계를 이용해 검색 품질 향상.
Graph RAG
지식 그래프를 활용한 RAG. 엔티티 간 관계를 이용해 검색 품질 향상.
그래프 RAG(Graph RAG)는 기존 RAG(Retrieval-Augmented Generation)에 지식 그래프(Knowledge Graph)를 결합한 고급 검색 증강 생성 기법입니다. 일반 RAG가 문서 청크의 벡터 유사도만으로 검색하는 반면, 그래프 RAG는 엔티티(개체)와 그들 간의 관계를 구조화하여 더 정확하고 연관성 높은 정보를 검색합니다. 이를 통해 멀티홉(multi-hop) 추론이 필요한 복잡한 질문에도 효과적으로 답변할 수 있습니다.
그래프 RAG의 핵심 구성요소는 문서에서 엔티티와 관계를 추출하는 지식 그래프 구축, 그래프 기반 검색, 그리고 커뮤니티 요약입니다. 먼저 LLM을 활용해 문서에서 (주어, 관계, 목적어) 형태의 트리플을 추출하여 지식 그래프를 구축합니다. 검색 시에는 쿼리와 관련된 엔티티를 찾고, 그래프 순회를 통해 연결된 정보를 함께 가져옵니다. Microsoft의 GraphRAG는 추가로 Leiden 알고리즘으로 커뮤니티를 탐지하고 각 커뮤니티의 요약을 생성하여 글로벌 검색에 활용합니다.
그래프 RAG는 특히 "무엇이 무엇과 어떤 관계인가?"와 같은 관계 질의, 여러 문서에 걸친 정보를 종합해야 하는 질의, 그리고 전체 데이터셋에 대한 요약 질의에서 기존 RAG보다 우수한 성능을 보입니다. 예를 들어 "A 회사의 CEO가 투자한 다른 회사들은?"처럼 여러 단계의 관계 추론이 필요한 질문에 효과적입니다.
구현 방식으로는 Neo4j, Amazon Neptune 같은 그래프 데이터베이스와 벡터 스토어를 결합하거나, LlamaIndex의 KnowledgeGraphIndex, Microsoft의 GraphRAG 라이브러리를 활용할 수 있습니다. 다만 지식 그래프 구축에 LLM 호출이 많이 필요하여 초기 인덱싱 비용이 높고, 그래프 품질이 검색 성능에 직접 영향을 미치므로 엔티티/관계 추출의 정확도가 중요합니다.
LlamaIndex를 사용한 간단한 그래프 RAG 구현 예제입니다.
# pip install llama-index llama-index-llms-openai llama-index-graph-stores-neo4j
import os
from llama_index.core import (
SimpleDirectoryReader,
KnowledgeGraphIndex,
Settings,
StorageContext
)
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.graph_stores.neo4j import Neo4jGraphStore
os.environ["OPENAI_API_KEY"] = "your-api-key"
# LLM 및 임베딩 설정
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
# 문서 로드
documents = SimpleDirectoryReader("./data").load_data()
# Neo4j 그래프 스토어 연결 (로컬 또는 Aura)
graph_store = Neo4jGraphStore(
username="neo4j",
password="your-password",
url="bolt://localhost:7687",
database="neo4j"
)
storage_context = StorageContext.from_defaults(graph_store=graph_store)
# 지식 그래프 인덱스 생성 (엔티티/관계 자동 추출)
kg_index = KnowledgeGraphIndex.from_documents(
documents,
storage_context=storage_context,
max_triplets_per_chunk=10, # 청크당 최대 트리플 수
include_embeddings=True, # 벡터 검색도 함께 활용
show_progress=True
)
# 쿼리 엔진 생성
query_engine = kg_index.as_query_engine(
include_text=True, # 원본 텍스트도 포함
response_mode="tree_summarize",
embedding_mode="hybrid", # 그래프 + 벡터 하이브리드
similarity_top_k=5
)
# 그래프 RAG 질의
response = query_engine.query(
"삼성전자의 주요 협력사들과 그들 간의 관계를 설명해주세요."
)
print("=== 그래프 RAG 응답 ===")
print(response)
# 추출된 트리플 확인
print("\n=== 추출된 지식 그래프 트리플 (샘플) ===")
for node in list(kg_index.index_struct.table.values())[:5]:
print(f"- {node}")
# 결과 예시:
# === 그래프 RAG 응답 ===
# 삼성전자의 주요 협력사로는 TSMC, SK하이닉스, 퀄컴 등이 있습니다.
# TSMC는 삼성전자와 반도체 파운드리 시장에서 경쟁 관계이며...
#
# === 추출된 지식 그래프 트리플 (샘플) ===
# - (삼성전자, 경쟁사, TSMC)
# - (삼성전자, 공급, 애플)
# - (SK하이닉스, 협력, 삼성전자)
그래프 RAG는 기존 벡터 RAG에 비해 인덱싱 비용이 높지만, 복잡한 질의에서 더 나은 답변 품질을 제공합니다.
| 항목 | 벡터 RAG | 그래프 RAG (Local) | 그래프 RAG (Global) |
|---|---|---|---|
| 인덱싱 비용 (1MB 문서) | $0.01~0.02 | $0.50~2.00 | $0.50~2.00 |
| 쿼리 비용 | $0.01~0.03 | $0.02~0.05 | $0.10~0.50 |
| 쿼리 지연시간 | 1~3초 | 2~5초 | 5~15초 |
| 단순 사실 질의 정확도 | 높음 | 높음 | 보통 |
| 멀티홉 추론 정확도 | 낮음 | 높음 | 높음 |
| 글로벌 요약 품질 | 낮음 | 보통 | 매우 높음 |
비용 최적화 팁: