1 환경 설정 & Hello GraphRAG
1.1 설치
1.2 예제 데이터: Animals 데이터셋
graph-rag-example-helpers에 포함된 동물 데이터셋을 사용한다. 각 동물은 텍스트 설명과 메타데이터(타입, 서식지, 원산지, 키워드)를 가진다.
{"id": "alpaca", "text": "alpacas are domesticated mammals ...",
"metadata": {"type": "mammal", "origin": "south america",
"keywords": ["wool", "domesticated", "friendly"]}}
{"id": "caribou", "text": "caribou, also known as reindeer ...",
"metadata": {"type": "mammal", "keywords": ["migratory", "arctic", "tundra"],
"diet": "herbivorous"}}
{"id": "cassowary","text": "cassowaries are flightless birds ...",
"metadata": {"type": "bird", "habitat": "rainforest",
"keywords": ["flightless", "colorful", "powerful"]}}1.3 In-memory 방식으로 시작
외부 서비스(OpenAI, Chroma 서버 등) 없이 로컬에서 바로 실행할 수 있다.
from langchain_graph_retriever.adapters.in_memory import InMemoryAdapter
# InMemoryAdapter: 모든 데이터를 메모리에 저장
# 실제 임베딩 대신 간단한 테스트용 임베딩 사용 가능
store = InMemoryAdapter.from_documents(
documents=animals,
embedding=your_embedding_model, # OpenAIEmbeddings() 등
)1.3.1 OpenAI 없이 테스트하려면
1.4 GraphRetriever 구성
GraphRetriever는 세 가지 필수 파라미터를 받는다.
from graph_retriever.strategies import Eager
from langchain_graph_retriever import GraphRetriever
retriever = GraphRetriever(
store=store, # (1) 어디서 검색?
edges=[("habitat", "habitat"), ("origin", "origin"), # (2) 어떻게 연결?
("keywords", "keywords")],
strategy=Eager(select_k=10, start_k=1, max_depth=2), # (3) 얼마나 탐색?
)1.4.1 파라미터 설명
(1) store: 데이터가 저장된 벡터 스토어 (or Adapter)
(2) edges: 어떤 메타데이터 필드로 노드를 연결할지 정의
# ("출력 필드", "입력 필드") 형태의 튜플
# ("habitat", "habitat") = "habitat 값이 같은 문서끼리 연결"
edges=[
("habitat", "habitat"), # 서식지가 같은 동물끼리 연결
("origin", "origin"), # 원산지가 같은 동물끼리 연결
("keywords", "keywords"), # 공통 키워드가 있는 동물끼리 연결
](3) strategy: 탐색 방식과 범위 제어
1.5 첫 번째 GraphRAG 실행
results = retriever.invoke("카피바라 근처에서 볼 수 있는 포유류는?")
for doc in results:
origin = doc.metadata.get("origin", "unknown")
habitat = doc.metadata.get("habitat", "unknown")
print(f"[{doc.id}] origin={origin}, habitat={habitat}")
print(f" {doc.page_content[:80]}...")
print()예상 출력:
[capybara] origin=south america, habitat=wetland
capybaras are the world's largest rodents, native to south america...
[alpaca] origin=south america, habitat=grassland
alpacas are domesticated mammals valued for their soft wool...
[llama] origin=south america, habitat=grassland
llamas are domesticated south american camelids...
[jaguar] origin=south america, habitat=rainforest
jaguars are the largest cats in the americas...
capybara에서 시작해 origin=south america로 연결된 동물들이 함께 반환된다.
1.6 탐색 과정 이해
질의: "카피바라 근처 포유류"
│
├─ depth=0: 벡터 검색 → [capybara] (start_k=1)
│ └─ capybara.origin = "south america"
│ capybara.habitat = "wetland"
│ capybara.keywords = ["largest rodent", "semi-aquatic"]
│
├─ depth=1: 메타데이터 탐색
│ ├─ origin="south america" → [alpaca, llama, jaguar, anaconda ...]
│ ├─ habitat="wetland" → [hippopotamus, crocodile ...]
│ └─ keywords="semi-aquatic"→ [platypus, beaver ...]
│
└─ depth=2: depth=1 노드들의 메타데이터로 추가 탐색
└─ select_k=10이 되면 중단
1.7 결과 시각화
import networkx as nx
import matplotlib.pyplot as plt
from langchain_graph_retriever.document_graph import create_graph
# 탐색된 문서들의 관계를 그래프로 변환
document_graph = create_graph(
documents=results,
edges=retriever.edges,
)
# 시각화
plt.figure(figsize=(12, 8))
nx.draw(
document_graph,
with_labels=True,
node_color="lightblue",
node_size=2000,
font_size=9,
)
plt.title("GraphRAG 탐색 결과")
plt.show()1.8 Chroma 기반으로 업그레이드 (실제 임베딩 사용)
In-memory에서 검증했다면 Chroma로 전환한다.
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_graph_retriever.adapters.chroma import ChromaAdapter
from langchain_graph_retriever.transformers import ShreddingTransformer
# keywords처럼 리스트 타입 메타데이터는 Shredding 필요 (06번 파일에서 자세히 설명)
shredder = ShreddingTransformer()
shredded_animals = list(shredder.transform_documents(animals))
# Chroma에 저장
vector_store = Chroma.from_documents(
documents=shredded_animals,
embedding=OpenAIEmbeddings(),
collection_name="animals",
)
# ChromaAdapter로 감싸기
store = ChromaAdapter(vector_store, shredder, {"keywords"})
# GraphRetriever 구성 (동일)
retriever = GraphRetriever(
store=store,
edges=[("habitat", "habitat"), ("origin", "origin"), ("keywords", "keywords")],
strategy=Eager(select_k=10, start_k=1, max_depth=2),
)
results = retriever.invoke("what mammals could be found near a capybara")1.9 정리
GraphRetriever(
store = 벡터 스토어 (In-memory / Chroma / PGVector / ...)
edges = [("메타데이터_필드", "메타데이터_필드"), ...] # 엣지 정의
strategy = Eager(select_k=10, start_k=1, max_depth=2) # 탐색 전략
)
동작:
1. start_k개 문서를 벡터 검색으로 찾음
2. 해당 문서의 edges에 정의된 메타데이터로 인접 문서 탐색
3. max_depth까지 반복
4. select_k개 문서 반환
다음 파일에서는 Node, Edge의 내부 구조를 자세히 살펴본다.