Neo4j GraphRAG 개발자 가이드: ToolsRetriever를 활용한 동적 검색 시스템 구축
개요
이 가이드는 Neo4j GraphRAG 파이썬 패키지의 ToolsRetriever를 활용하여 사용자 질문에 따라 최적의 검색 방식을 동적으로 선택하는 지능형 GraphRAG 시스템을 구축하는 방법을 다룹니다. 데이터 수집부터 지식 그래프 설계, 구축, 그리고 다양한 검색 전략을 통합하는 전 과정을 단계별로 설명합니다.
GraphRAG란?
GraphRAG(Graph Retrieval-Augmented Generation)는 그래프 데이터베이스의 구조적 정보와 벡터 검색의 의미론적 검색을 결합한 검색 증강 생성 방식입니다. 전통적인 RAG가 단순히 문서를 벡터화하여 유사도 기반 검색만 수행하는 것과 달리, GraphRAG는 엔티티 간의 관계 정보를 활용하여 더욱 풍부한 맥락 정보를 제공할 수 있습니다.
시스템 아키텍처
전체 시스템은 세 가지 주요 레이어로 구성됩니다:
- 데이터 수집 레이어: 외부 소스(네이버 뉴스)에서 구조화된 데이터를 크롤링
- 지식 그래프 레이어: 수집된 데이터를 노드와 관계로 모델링하여 Neo4j에 저장
- 검색 레이어: 다양한 검색 전략을 도구로 제공하고 질문 유형에 따라 동적으로 선택
1단계: 데이터 수집 및 전처리
데이터 소스 선정
뉴스 기사는 GraphRAG 시스템을 구축하기에 적합한 데이터 소스입니다. 기사는 명확한 메타데이터(제목, 언론사, 카테고리, 작성일)를 가지고 있으며, 내용 간의 관계를 파악할 수 있는 풍부한 텍스트를 포함하고 있습니다.
크롤링 구현
네이버 뉴스에서 다음 6개 카테고리의 헤드라인 뉴스를 수집합니다:
- 정치
- 경제
- 사회
- 생활/문화
- IT/과학
- 세계
각 기사에서 추출해야 할 정보는 다음과 같습니다:
- 기사 제목
- 기사 URL
- 언론사명
- 카테고리
- 작성일시
- 기사 본문
크롤링 시 주의사항으로는 robots.txt를 준수하고, 적절한 지연 시간을 설정하여 서버에 부하를 주지 않도록 해야 합니다. 또한 수집한 데이터는 JSON이나 CSV 형식으로 저장하여 다음 단계에서 쉽게 활용할 수 있도록 합니다.
2단계: 지식 그래프 설계
노드(엔티티) 설계
지식 그래프의 핵심은 현실 세계의 개념을 노드로 표현하는 것입니다. 뉴스 도메인에서 다음 네 가지 노드 타입을 정의합니다:
Article 노드는 개별 뉴스 기사를 나타냅니다. 주요 속성으로는 제목(title), URL(url), 작성일(published_date) 등이 있습니다. 이 노드는 그래프의 중심 엔티티로서 다른 모든 노드들과 연결됩니다.
Media 노드는 기사를 발행한 언론사를 나타냅니다. 언론사명(name)을 주요 속성으로 가지며, 같은 언론사가 발행한 여러 기사들을 연결하는 허브 역할을 합니다.
Category 노드는 기사의 주제 분류를 나타냅니다. 카테고리명(name)을 속성으로 가지며, 같은 주제의 기사들을 그룹화하는 데 사용됩니다.
Content 노드는 기사 본문을 청크 단위로 분할하여 저장합니다. 이는 벡터 검색을 위한 핵심 노드로, 각 청크는 텍스트 내용(text)과 해당 내용의 임베딩 벡터(embedding)를 속성으로 가집니다. 긴 기사를 청크로 나누는 이유는 LLM의 컨텍스트 윈도우 제한을 고려하고, 더 정확한 벡터 검색을 가능하게 하기 위함입니다.
관계(엣지) 설계
노드 간의 연결은 다음과 같이 설계합니다:
PUBLISHED_BY 관계는 Article 노드에서 Media 노드로 연결되어 “어떤 기사가 어느 언론사에 의해 발행되었는가”를 나타냅니다.
BELONGS_TO 관계는 Article 노드에서 Category 노드로 연결되어 기사의 주제 분류를 나타냅니다.
HAS_CHUNK 관계는 Article 노드에서 Content 노드로 연결되며, 하나의 기사가 여러 개의 콘텐츠 청크를 가질 수 있습니다. 이 관계에는 청크의 순서를 나타내는 chunk_index 속성을 추가할 수 있습니다.
청킹 전략
기사 본문을 청크로 나누는 것은 벡터 검색의 성능을 좌우하는 중요한 단계입니다. 일반적으로 다음 전략을 고려합니다:
고정 크기 청킹은 일정한 토큰 수(예: 512토큰)로 텍스트를 분할하는 방식입니다. 구현이 간단하지만 문장이나 문단의 의미 경계를 무시할 수 있습니다.
의미 기반 청킹은 문장이나 문단 단위로 분할하되, 각 청크가 적절한 크기를 유지하도록 하는 방식입니다. 더 나은 검색 품질을 제공하지만 구현이 복잡합니다.
오버래핑 청킹은 인접한 청크 간에 일부 텍스트를 겹치게 하여 문맥 손실을 방지합니다. 예를 들어 20% 정도의 오버랩을 설정할 수 있습니다.
3단계: Neo4j 그래프 데이터베이스 구축
환경 설정
Neo4j를 사용하기 위해서는 먼저 Neo4j 데이터베이스 인스턴스가 필요합니다. Neo4j Desktop을 로컬에 설치하거나, Neo4j AuraDB 클라우드 서비스를 사용할 수 있습니다. 파이썬에서 Neo4j에 연결하기 위해 공식 드라이버를 설치합니다.
데이터 적재
Cypher 쿼리 언어를 사용하여 수집한 데이터를 그래프로 변환합니다. 기본적인 적재 프로세스는 다음과 같습니다:
먼저 고유한 노드들을 생성합니다. Media와 Category 노드는 MERGE 문을 사용하여 중복 생성을 방지합니다. 예를 들어 “조선일보”라는 Media 노드는 여러 기사가 참조하더라도 한 번만 생성되어야 합니다.
다음으로 각 기사에 대해 Article 노드를 생성하고, 해당 기사의 본문을 청크로 분할하여 Content 노드들을 생성합니다. 이때 각 Content 노드의 text 속성에 임베딩을 생성하여 embedding 속성에 저장합니다.
마지막으로 설계한 관계에 따라 노드들을 연결합니다. Article을 Media, Category와 연결하고, Article과 각 Content 청크를 연결합니다.
벡터 인덱스 생성
Content 노드의 임베딩에 대해 벡터 검색을 수행하려면 벡터 인덱스를 생성해야 합니다. Neo4j는 HNSW(Hierarchical Navigable Small World) 알고리즘을 지원하여 효율적인 근사 최근접 이웃 검색을 제공합니다.
인덱스 생성 시 임베딩 차원 수와 유사도 함수(코사인 유사도 등)를 지정해야 합니다. OpenAI의 text-embedding-3-small 모델을 사용한다면 1536차원의 임베딩이 생성됩니다.
그래프 시각화 및 검증
Neo4j Browser를 통해 구축된 그래프를 시각화하면 데이터 모델이 의도대로 구현되었는지 확인할 수 있습니다. 간단한 Cypher 쿼리로 노드와 관계의 개수를 확인하고, 샘플 데이터의 연결 상태를 점검합니다.
4단계: 세 가지 검색 전략 구현
GraphRAG의 핵심은 질문의 특성에 맞는 검색 방식을 선택하는 것입니다. Neo4j GraphRAG 패키지는 다음 세 가지 주요 Retriever를 제공합니다.
Text-to-Cypher Retriever (구조적 검색)
Text-to-Cypher는 자연어 질문을 Cypher 쿼리로 변환하여 그래프의 구조적 정보를 활용하는 방식입니다. 이는 명확한 엔티티나 속성을 기반으로 정보를 찾을 때 가장 효과적입니다.
예를 들어 “경제 분야의 최신 뉴스를 알려주세요”라는 질문은 Category 노드에서 경제 카테고리를 찾고, 그와 연결된 Article 노드들을 작성일 기준으로 정렬하여 반환하는 명확한 구조적 쿼리로 변환될 수 있습니다.
Text-to-Cypher Retriever는 LLM에게 그래프 스키마 정보를 제공하고, 질문을 Cypher 쿼리로 변환하도록 요청합니다. 생성된 쿼리를 Neo4j에서 실행하여 결과를 반환합니다.
이 방식의 장점은 정확한 필터링과 집계가 가능하고, 관계를 따라 복잡한 탐색을 수행할 수 있다는 점입니다. 단점으로는 LLM이 올바른 Cypher 쿼리를 생성하지 못할 수 있으며, 그래프 스키마를 정확히 이해해야 한다는 점입니다.
Vector Retriever (의미 기반 검색)
Vector Retriever는 질문을 임베딩으로 변환하고, Content 노드의 임베딩과 코사인 유사도를 계산하여 가장 관련성 높은 텍스트 청크를 찾습니다.
“모든 연령의 인기가 많은 맛집은 어디인가요?”와 같이 특정 키워드나 구조가 아닌 의미적으로 유사한 내용을 찾을 때 효과적입니다. 질문의 임베딩과 Content 노드들의 임베딩 간 유사도를 계산하여 상위 k개의 청크를 반환합니다.
이 방식은 키워드 매칭의 한계를 극복하고 의미적으로 유사한 내용을 찾을 수 있지만, 구조적 정보를 활용하지 못하고 검색된 청크가 어떤 기사에 속하는지 등의 맥락 정보가 부족할 수 있습니다.
Vector-Cypher Retriever (복합 검색)
Vector-Cypher는 벡터 검색과 그래프 탐색을 결합한 방식입니다. 먼저 벡터 검색으로 관련 Content 노드를 찾은 후, 해당 노드와 연결된 다른 노드들(Article, Media, Category 등)을 함께 탐색하여 풍부한 맥락 정보를 제공합니다.
예를 들어 특정 주제에 대한 질문을 받으면 벡터 검색으로 관련 Content를 찾고, 그 Content가 속한 Article의 제목, 작성일, 언론사 정보를 함께 반환할 수 있습니다. 더 나아가 같은 Category에 속한 다른 기사들까지 탐색하여 관련 뉴스들을 종합적으로 제공할 수 있습니다.
이는 의미 검색의 강점과 구조적 검색의 장점을 모두 활용하는 하이브리드 방식으로, 가장 풍부한 정보를 제공할 수 있지만 구현과 튜닝이 복잡합니다.
5단계: ToolsRetriever를 통한 동적 검색 구현
도구 정의
ToolsRetriever는 LangChain의 도구(Tool) 개념을 활용하여 각 Retriever를 하나의 도구로 정의합니다. 각 도구는 명확한 이름, 설명, 그리고 실행 함수를 가집니다.
Text-to-Cypher 도구는 “언론사별 기사 검색, 카테고리별 기사 검색, 특정 날짜의 기사 검색 등 명확한 엔티티나 속성 기반의 구조적 질문에 사용”과 같은 설명을 가집니다.
Vector Retriever 도구는 “기사 내용의 의미를 기반으로 검색할 때 사용하며, 특정 주제나 키워드와 관련된 내용을 찾을 때 효과적”이라는 설명을 제공합니다.
Vector-Cypher 도구는 “내용 검색과 함께 관련 기사의 메타데이터와 주변 정보를 함께 조회할 때 사용”하는 용도를 명시합니다.
도구 선택 메커니즘
ToolsRetriever는 내부적으로 LLM을 사용하여 사용자의 질문을 분석하고, 각 도구의 설명을 참고하여 가장 적합한 도구를 선택합니다. 이는 ReAct(Reasoning and Acting) 패턴을 기반으로 하며, LLM이 질문의 의도를 파악하고 적절한 도구를 선택하는 과정을 거칩니다.
선택 과정에서 LLM은 다음과 같이 추론합니다:
- 질문이 특정 카테고리나 언론사를 명시하는가? → Text-to-Cypher 선택
- 질문이 의미적 내용 검색을 요구하는가? → Vector Retriever 선택
- 질문이 내용 검색과 함께 상세 정보를 필요로 하는가? → Vector-Cypher 선택
통합 구현
세 가지 Retriever를 ToolsRetriever로 통합하는 코드 구조는 각 Retriever를 초기화하고, 도구 리스트를 생성한 후, ToolsRetriever 인스턴스를 생성하는 방식입니다. ToolsRetriever는 질문을 받으면 자동으로 적절한 도구를 선택하고 실행하여 결과를 반환합니다.
6단계: 시스템 테스트 및 검증
구조적 질문 테스트
“정치 카테고리의 최신 기사를 알려주세요”와 같은 질문으로 Text-to-Cypher가 올바르게 선택되는지 확인합니다. 반환된 기사 목록이 실제로 정치 카테고리에 속하고 최신순으로 정렬되어 있는지 검증합니다.
의미 기반 질문 테스트
“트럼프 대통령 관련 내용”처럼 특정 키워드나 주제에 대한 질문으로 Vector Retriever가 선택되고, 관련 내용이 포함된 청크들이 반환되는지 확인합니다. 반환된 결과의 관련성을 평가합니다.
복합 질문 테스트
의미 검색과 함께 상세 정보가 필요한 질문으로 Vector-Cypher가 작동하는지 테스트합니다. 검색된 내용과 함께 기사 제목, 언론사, 작성일 등의 메타데이터가 함께 제공되는지 확인합니다.
최적화 및 고급 기법
하이브리드 검색
경우에 따라 여러 검색 방식을 조합하여 더 나은 결과를 얻을 수 있습니다. 예를 들어 Vector 검색 결과와 Text-to-Cypher 검색 결과를 결합하고, 중복을 제거하며, 관련성 점수를 기반으로 재정렬할 수 있습니다.
프롬프트 엔지니어링
각 Retriever의 성능은 LLM에게 제공하는 프롬프트에 크게 의존합니다. Text-to-Cypher의 경우 그래프 스키마를 명확히 설명하고, 예시 쿼리를 제공하며, 제약사항을 명시하는 것이 중요합니다.
도구 선택을 위한 프롬프트도 각 도구의 사용 사례를 구체적으로 설명하고, 질문 유형별 예시를 제공하여 LLM이 더 정확한 선택을 할 수 있도록 합니다.
성능 모니터링
각 검색 방식의 선택 빈도와 성공률을 추적하고, 검색 결과의 품질을 평가하며, 응답 시간을 모니터링하여 시스템을 지속적으로 개선합니다.
실무 적용 시 고려사항
확장성
실제 운영 환경에서는 수천, 수만 개의 문서를 처리해야 할 수 있습니다. Neo4j의 인덱싱과 벡터 검색 최적화를 통해 확장성을 확보해야 합니다. 또한 청킹 전략과 임베딩 모델 선택이 성능에 큰 영향을 미칩니다.
비용 관리
LLM API 호출은 비용이 발생하므로, 캐싱 전략을 구현하여 동일하거나 유사한 질문에 대해 재사용할 수 있습니다. 또한 임베딩 생성은 한 번만 수행하고 결과를 저장하여 재사용합니다.
데이터 업데이트
뉴스 기사는 지속적으로 생성되므로 증분 업데이트 전략이 필요합니다. 새로운 기사를 주기적으로 크롤링하고, 그래프에 추가하며, 벡터 인덱스를 업데이트하는 파이프라인을 구축해야 합니다.
오류 처리
Text-to-Cypher에서 잘못된 쿼리가 생성될 수 있으므로 쿼리 검증 로직과 폴백 메커니즘을 구현합니다. 예를 들어 쿼리 실행 실패 시 Vector Retriever로 전환하는 등의 전략을 사용할 수 있습니다.
결론
Neo4j GraphRAG의 ToolsRetriever를 활용하면 사용자 질문의 특성에 따라 가장 적절한 검색 방식을 자동으로 선택하는 지능형 시스템을 구축할 수 있습니다. 구조적 검색, 의미 기반 검색, 그리고 두 방식을 결합한 복합 검색을 통해 다양한 유형의 질문에 효과적으로 대응할 수 있습니다.
이 가이드에서 다룬 뉴스 기사 도메인의 예시는 다른 도메인에도 쉽게 적용할 수 있습니다. 제품 카탈로그, 고객 지원 문서, 연구 논문, 법률 문서 등 다양한 분야에서 GraphRAG의 강력함을 활용할 수 있습니다.
핵심은 도메인에 맞는 적절한 그래프 스키마를 설계하고, 각 검색 방식의 장단점을 이해하며, ToolsRetriever를 통해 이들을 효과적으로 조합하는 것입니다. 지속적인 테스트와 개선을 통해 사용자에게 최상의 검색 경험을 제공하는 GraphRAG 시스템을 완성할 수 있습니다.
참고 자료
Neo4j GraphRAG 공식 문서와 예제 코드는 지속적으로 업데이트되고 있으므로, 최신 정보를 확인하는 것이 중요합니다. 또한 LangChain 문서에서 도구와 에이전트 패턴에 대한 더 자세한 내용을 학습할 수 있습니다.
별첨
💡 주요 내용 요약
영상은 크게 네이버 뉴스 기사 수집부터 시작하여 지식 그래프 구축, 그리고 ToolsRetriever를 활용한 GraphRAG 구현의 3단계로 구성됩니다.
1. 지식 그래프 구축을 위한 데이터 수집 및 설계
- 데이터 수집 01:34: 네이버 뉴스에서 정치, 경제, 사회 등 총 6개의 카테고리에 대한 헤드라인 뉴스 기사를 크롤링하여 데이터를 수집합니다.
- 지식 그래프 설계 03:18: 수집된 데이터를 기반으로 지식 그래프의 엔티티(노드)와 관계(엣지)를 설계합니다.
- 노드: 기사(Article), 언론사(Media), 카테고리(Category), 기사 내용 청크(Content)
관계: 기사-언론사(
PUBLISHED), 기사-카테고리(BELONGS_TO), 기사-청크(HAS_CHUNK) 등으로 연결합니다.Content노드에는 벡터 검색을 위해 기사 내용을 청크 단위로 쪼개어 저장합니다 05:14.- Neo4j 구축 14:55: 설계된 구조를 바탕으로 Cypher 쿼리문을 작성하여 총 60개의 뉴스 기사를 Neo4j 그래프 데이터베이스에 적재하고 시각화된 그래프 구조를 확인합니다 19:06.
2. ToolsRetriever를 활용한 GraphRAG 구현
GraphRAG 에이전트를 구현하기 위해 세 가지의 검색 방식을 도구(Tool)로 정의하고, ToolsRetriever가 질문의 유형에 따라 가장 적절한 도구를 선택하도록 만듭니다.
| 검색 방식 (Retriever) | 사용 목적 (도구 설명) | 예시 질문 |
|---|---|---|
| 텍스트투 사이퍼 (Text-to-Cypher) 09:14 | 언론사, 분야별 기사 등 명확한 엔티티나 속성을 기반으로 정보를 찾을 때 (구조적 검색) | “경제 분야의 최신 뉴스를 알려주세요.” |
| 벡터 리트리버 (Vector Retriever) 10:25 | 뉴스 기사에 등장하는 내용 텍스트를 기반으로 벡터 검색을 할 때 (의미 기반 검색) | “모든 연령의 인기가 많은 맛집은 어디인가요?” |
| 벡터 사이퍼 (Vector-Cypher) 10:50 | 벡터 검색 결과와 연결된 다른 그래프 노드들을 함께 탐색하여 풍부한 맥락 정보를 찾을 때 (복합 검색) | (관련 내용 검색 후) 해당 기사의 상세 정보, 같은 카테고리 다른 기사까지 반환 |
3. 동적 검색 기능 시연
최종적으로 ToolsRetriever를 통해 세 가지 도구를 통합한 GraphRAG를 구현하고, 다양한 질문에 유연하게 답변하는 모습을 시연합니다 36:18.
- 구조적 질문: “정치 카테고리의 최신 기사를 알려주세요.” → Text-to-Cypher Retriever를 선택하여 카테고리 기반 검색을 수행 37:00.
- 내용 기반 질문: “트럼프 대통령 관련 내용”을 물었을 때 → Vector Retriever를 선택하여 텍스트 내용 기반의 벡터 검색을 수행 37:51].
🔗 영상 링크: 데이터 수집부터 지식그래프 구축까지, GraphRAG 완성하기