포스트

RAG 기술 아키텍처 세미나 - (4) Index-based GraphRAG 기반 Neo4j Hybrid RAG 시스템 구현

RAG 기술 아키텍처 세미나 - (4) Index-based GraphRAG 기반 Neo4j Hybrid RAG 시스템 구현

Microsoft GraphRAG × Neo4j × BM25 통합 아키텍처

아키텍처팀 기술 세미나 — 보조 자료
원본 문서: Neo4j 기반 GraphRAG를 활용한 Hybrid RAG 시스템 구현
참조 문서: Index-based GraphRAG 심화 이해
작성일: 2026-05-11


관련글


목차

  1. 이 문서의 목적 — Index-based + Neo4j의 결합
  2. 전체 시스템 개념 지도
  3. 인덱싱 파이프라인 아키텍처
  4. Neo4j 내부 그래프 데이터 모델
  5. 질의 파이프라인 아키텍처 — 세 가지 탐색 방식
  6. Hybrid RAG 통합 아키텍처 — BM25 + Vector + Community
  7. LazyGraphRAG 변형 아키텍처
  8. 질의 유형별 라우팅 설계
  9. 운영 아키텍처 설계
  10. 단계별 구현 전략 — PoC에서 운영까지
  11. Knowledge-based GraphRAG와 병행 활용
  12. 결론

1. 이 문서의 목적 — Index-based + Neo4j의 결합

1.1 왜 Index-based GraphRAG에 Neo4j를 더하는가

Microsoft GraphRAG는 기본적으로 결과물을 Parquet 파일 형태로 로컬 디스크에 저장합니다. 인덱싱이 끝나면 엔터티, 관계, 커뮤니티 리포트, 텍스트 청크 등이 모두 Parquet 파일 묶음으로 존재합니다. 이 상태에서도 Microsoft 제공 CLI로 질의를 실행할 수 있지만, 엔터프라이즈 환경에서 실제 운영 시스템으로 통합하려면 여러 한계가 있습니다.

  • Parquet 파일 기반 저장은 동시 접근, 분산 조회, 실시간 갱신에 적합하지 않습니다.
  • 그래프 구조의 시각화 및 탐색 도구가 제한됩니다.
  • BM25나 벡터 검색 결과와 통합하는 질의 계층을 별도로 구성해야 합니다.
  • 기존 애플리케이션과의 API 통합이 어렵습니다.

이 문제를 해결하는 것이 MS GraphRAG 인덱싱 결과물을 Neo4j로 가져와 그래프 DB를 질의 백엔드로 활용하는 방식입니다. Neo4j가 그래프 저장소, 벡터 인덱스, 전문 검색 인덱스를 모두 단일 플랫폼에서 제공하기 때문에 Hybrid RAG 통합 지점으로서 자연스럽게 기능합니다.

1.2 이 문서에서 다루는 시스템의 전체 정의

이 문서에서 구현하려는 시스템의 정의는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Index-based GraphRAG 기반 Hybrid RAG 시스템]

= Microsoft GraphRAG 인덱싱 파이프라인
  (자유 엔터티 추출 → Leiden 커뮤니티 탐지 → 커뮤니티 요약 생성)

+ Neo4j 그래프 데이터베이스
  (그래프 저장소 + 벡터 인덱스 + 전문 검색 인덱스 통합)

+ BM25 키워드 검색
  (Neo4j Full-text Index 또는 Elasticsearch)

+ 질의 라우터
  (Local Search / Global Search / DRIFT Search / BM25 동적 선택)

+ LLM 응답 생성
  (커뮤니티 요약 + 그래프 탐색 결과 + 문서 청크 결합)

Knowledge-based GraphRAG(Neo4j 기반, 온톨로지 사전 설계)와 달리, 이 시스템은 도메인 온톨로지 없이도 대규모 비정형 문서에서 커뮤니티 기반 지식 구조를 자동으로 추출하는 것이 핵심입니다.


2. 전체 시스템 개념 지도

아래 다이어그램은 이 문서에서 다루는 전체 시스템을 한눈에 나타냅니다. 크게 인덱싱 영역질의 영역으로 구분되고, Neo4j가 두 영역을 연결하는 중앙 저장소 역할을 합니다.

flowchart TB
    subgraph IndexingZone["인덱싱 영역 (사전 수행 / 배치)"]
        direction LR
        subgraph MSGraphRAG["MS GraphRAG 파이프라인"]
            DOCS["원본 문서"]
            CHUNK["청크 분할"]
            EXTRACT["LLM 엔터티/관계 추출"]
            LEIDEN["Leiden 커뮤니티 탐지"]
            SUMMARIZE["LLM 커뮤니티 요약 생성"]
            EMBED_IDX["임베딩 생성"]
            PARQUET["Parquet 파일 출력"]

            DOCS --> CHUNK --> EXTRACT --> LEIDEN --> SUMMARIZE --> EMBED_IDX --> PARQUET
        end

        subgraph Neo4jLoad["Neo4j 적재"]
            IMPORT["Parquet → CSV 변환 및 Neo4j LOAD"]
            NEO4J_STORE[("Neo4j\nGraph DB")]

            IMPORT --> NEO4J_STORE
        end

        subgraph IndexBuild["인덱스 구축"]
            VEC_IDX["벡터 인덱스 생성\n(엔터티·청크·커뮤니티 임베딩)"]
            FT_IDX["전문 검색 인덱스 생성\n(BM25 / Full-text)"]

            NEO4J_STORE --> VEC_IDX
            NEO4J_STORE --> FT_IDX
        end

        PARQUET --> IMPORT
    end

    subgraph QueryZone["질의 영역 (실시간)"]
        direction LR
        USER["사용자 질의"]
        ROUTER["질의 라우터\n(유형 분류)"]

        subgraph SearchPaths["검색 경로"]
            LOCAL["Local Search\n벡터 + 그래프 탐색"]
            GLOBAL["Global Search\n커뮤니티 요약 Map-Reduce"]
            DRIFT["DRIFT Search\n글로벌 + 로컬 혼합"]
            BM25_Q["BM25 키워드 검색\n(전문 검색 인덱스)"]
        end

        MERGE_Q["결과 통합 / Reranking"]
        CTX["컨텍스트 구성"]
        LLM_GEN["LLM 응답 생성"]
        ANSWER["최종 응답"]

        USER --> ROUTER
        ROUTER --> LOCAL
        ROUTER --> GLOBAL
        ROUTER --> DRIFT
        ROUTER --> BM25_Q

        LOCAL --> MERGE_Q
        GLOBAL --> MERGE_Q
        DRIFT --> MERGE_Q
        BM25_Q --> MERGE_Q

        MERGE_Q --> CTX --> LLM_GEN --> ANSWER
    end

    NEO4J_STORE --> LOCAL
    NEO4J_STORE --> GLOBAL
    NEO4J_STORE --> DRIFT
    FT_IDX --> BM25_Q
    VEC_IDX --> LOCAL
    VEC_IDX --> DRIFT

3. 인덱싱 파이프라인 아키텍처

인덱싱은 질의가 들어오기 전에 사전에 수행하는 배치 작업입니다. 이 단계의 품질이 이후 모든 검색 결과의 기반이 됩니다.

3.1 MS GraphRAG 인덱싱 단계 상세

flowchart TB
    subgraph Phase1["Phase 1: 문서 처리"]
        D["원본 문서\n(PDF, TXT, MD, DOCX)"]
        C["텍스트 청크\n(기본 300토큰, 오버랩 포함)"]
        D --> |"청크 분할"| C
    end

    subgraph Phase2["Phase 2: LLM 기반 추출 (비용 집중 구간)"]
        direction TB
        E_TYPES["엔터티 유형 설정\n(GRAPHRAG_ENTITY_EXTRACTION_ENTITY_TYPES\n예: organization, system, person, event)"]
        GLEANING["다중 추출 패스\n(Gleaning: LLM을 N회 반복 호출\n→ 누락 엔터티 보완)"]
        ENT["엔터티 노드\n(이름, 유형, 설명, 청크 참조)"]
        REL["관계 엣지\n(출발 엔터티, 도착 엔터티, 관계 설명, 가중치)"]
        COV["공변량\n(엔터티 관련 주요 클레임)"]

        C --> E_TYPES
        E_TYPES --> GLEANING
        GLEANING --> ENT
        GLEANING --> REL
        GLEANING --> COV
    end

    subgraph Phase3["Phase 3: 그래프 통합"]
        MERGE_E["동명 엔터티 병합\n(String Matching 기반)"]
        MERGE_R["다중 소스 관계 통합\n(관계 설명 집계)"]
        KG["통합 지식그래프"]

        ENT --> MERGE_E --> KG
        REL --> MERGE_R --> KG
    end

    subgraph Phase4["Phase 4: Leiden 커뮤니티 탐지 (비LLM)"]
        LEIDEN_ALG["Leiden 알고리즘 실행\n(모듈성 최적화)"]
        L0["Level 0 커뮤니티\n(리프, 가장 세밀)"]
        L1["Level 1 커뮤니티\n(중간)"]
        L2["Level 2 커뮤니티\n(루트, 가장 광범위)"]

        KG --> LEIDEN_ALG
        LEIDEN_ALG --> L0 --> L1 --> L2
    end

    subgraph Phase5["Phase 5: 커뮤니티 요약 생성 (LLM)"]
        SUM_L0["Level 0 커뮤니티 리포트 생성"]
        SUM_L1["Level 1 커뮤니티 리포트 생성\n(하위 요약 참조)"]
        SUM_L2["Level 2 커뮤니티 리포트 생성\n(전체 데이터셋 요약)"]

        L0 --> SUM_L0
        L1 --> SUM_L1
        L2 --> SUM_L2
        SUM_L0 --> SUM_L1 --> SUM_L2
    end

    subgraph Phase6["Phase 6: 임베딩 및 Parquet 출력"]
        EMBED_E["엔터티 설명 임베딩"]
        EMBED_C["텍스트 청크 임베딩"]
        EMBED_CR["커뮤니티 리포트 임베딩"]
        PARQUET_OUT["Parquet 파일 세트\n(entities, relations, communities\ntext_units, community_reports)"]

        SUM_L0 --> EMBED_CR
        SUM_L1 --> EMBED_CR
        SUM_L2 --> EMBED_CR
        ENT --> EMBED_E
        C --> EMBED_C

        EMBED_E --> PARQUET_OUT
        EMBED_C --> PARQUET_OUT
        EMBED_CR --> PARQUET_OUT
        KG --> PARQUET_OUT
    end

3.2 비용 최적화 설정 포인트

인덱싱에서 비용이 집중되는 구간은 Phase 2(엔터티 추출)와 Phase 5(커뮤니티 요약)입니다. 이 두 단계의 비용을 제어하는 주요 설정값은 다음과 같습니다.

설정 항목역할권장 방향
chunk_size청크 크기 (기본 300토큰)도메인에 따라 200~600 조정
chunk_overlap청크 오버랩보통 chunk_size의 10~30%
entity_types추출할 엔터티 유형 목록도메인 특화 유형으로 좁힐수록 품질↑ 비용↓
max_gleanings추출 반복 횟수0이면 단일 패스, 클수록 품질↑ 비용↑
community_level질의에 사용할 계층 (기본 2)낮을수록 광범위하고 저렴
extraction_model추출에 사용할 LLMgpt-4o-mini 등 저렴한 모델 권장
summarization_model요약에 사용할 LLM추출보다 상위 모델 권장

3.3 Parquet → Neo4j 적재 흐름

MS GraphRAG 인덱싱 결과물인 Parquet 파일을 Neo4j에 적재하는 과정입니다.

flowchart LR
    subgraph ParquetFiles["Parquet 파일 (인덱싱 출력)"]
        P1["entities.parquet\n(id, name, type, description, text_unit_ids)"]
        P2["relationships.parquet\n(source, target, description, weight)"]
        P3["communities.parquet\n(id, level, title, entity_ids)"]
        P4["community_reports.parquet\n(id, level, summary, full_content, rank)"]
        P5["text_units.parquet\n(id, text, document_ids, entity_ids)"]
        P6["embeddings\n(entity, chunk, community 임베딩 벡터)"]
    end

    subgraph Transform["변환 단계"]
        CSV["Parquet → CSV 변환\n(pandas 활용)"]
        CYPHER_LOAD["Cypher LOAD CSV 또는\nneo4j-admin import"]
    end

    subgraph Neo4jDB["Neo4j 그래프 DB"]
        N1["Entity 노드"]
        N2["Relationship 엣지"]
        N3["Community 노드"]
        N4["CommunityReport 노드"]
        N5["TextUnit 노드"]
        N6["벡터 인덱스\n(ANN)"]
        N7["전문 검색 인덱스\n(Full-text)"]
    end

    P1 --> CSV
    P2 --> CSV
    P3 --> CSV
    P4 --> CSV
    P5 --> CSV
    P6 --> CSV
    CSV --> CYPHER_LOAD

    CYPHER_LOAD --> N1
    CYPHER_LOAD --> N2
    CYPHER_LOAD --> N3
    CYPHER_LOAD --> N4
    CYPHER_LOAD --> N5
    CYPHER_LOAD --> N6
    CYPHER_LOAD --> N7

4. Neo4j 내부 그래프 데이터 모델

Index-based GraphRAG로 구축된 Neo4j 그래프의 노드와 관계 구조는 Knowledge-based GraphRAG와 다릅니다. 도메인 온톨로지 대신 MS GraphRAG의 고유 데이터 모델이 사용됩니다.

4.1 노드 유형 및 관계 구조

graph TD
    subgraph DocumentLayer["문서 계층 (렉시컬 그래프)"]
        DOC["Document\n원본 문서"]
        TU["TextUnit\n텍스트 청크\n+ 임베딩 벡터"]
        DOC --"CONTAINS"--> TU
        TU --"NEXT"--> TU
    end

    subgraph EntityLayer["엔터티 계층"]
        E1["Entity\n이름: Log4j\n유형: Library\n설명: ...\n임베딩 벡터: [...]"]
        E2["Entity\n이름: 결제서비스\n유형: Application\n설명: ..."]
        E3["Entity\n이름: CVE-2021-44228\n유형: Vulnerability\n설명: ..."]

        E1 --"RELATED\n(weight, description)"-->E2
        E2 --"RELATED\n(weight, description)"--> E3
        E1 --"RELATED"--> E3
    end

    subgraph CommunityLayer["커뮤니티 계층"]
        CL0["Community\nlevel=0 (리프)\nid: C-001"]
        CL1["Community\nlevel=1 (중간)\nid: C-010"]
        CL2["Community\nlevel=2 (루트)\nid: C-100"]

        CL2 --"PARENT_OF"--> CL1
        CL1 --"PARENT_OF"--> CL0
    end

    subgraph ReportLayer["커뮤니티 리포트 계층"]
        CR0["CommunityReport\nlevel=0\nsummary: '...\n보안 취약점 관련 라이브러리...'\nrank: 8.5\n임베딩 벡터: [...]"]
        CR1["CommunityReport\nlevel=1\nsummary: '...인프라 시스템과\n보안 관리 체계...'\nrank: 7.2"]
        CR2["CommunityReport\nlevel=2\nsummary: '전체 데이터셋은\n주로 엔터프라이즈\nIT 시스템 운영에 관한...'\nrank: 9.1"]

        CL0 --"HAS_REPORT"--> CR0
        CL1 --"HAS_REPORT"--> CR1
        CL2 --"HAS_REPORT"--> CR2
    end

    E1 --"IN_COMMUNITY"--> CL0
    E2 --"IN_COMMUNITY"--> CL0
    E3 --"IN_COMMUNITY"--> CL0

    TU --"MENTIONS"--> E1
    TU --"MENTIONS"--> E2
    TU --"MENTIONS"--> E3

4.2 인덱스 구성

Neo4j 내부에 세 종류의 인덱스가 구성됩니다.

flowchart LR
    subgraph VectorIndexes["벡터 인덱스 (ANN 검색)"]
        VI_E["entity-embedding-index\n대상: Entity 노드의 embedding 속성"]
        VI_T["textunit-embedding-index\n대상: TextUnit 노드의 embedding 속성"]
        VI_C["community-report-index\n대상: CommunityReport 노드의 embedding 속성"]
    end

    subgraph FulltextIndexes["전문 검색 인덱스 (BM25)"]
        FT_E["entity-fulltext-index\n대상: Entity.name + Entity.description"]
        FT_T["textunit-fulltext-index\n대상: TextUnit.text"]
        FT_C["communityreport-fulltext-index\n대상: CommunityReport.summary"]
    end

    subgraph GraphIndex["그래프 인덱스 (Cypher 탐색)"]
        GI["RELATED 관계 인덱스\nIN_COMMUNITY 관계 인덱스\nCONTAINS 관계 인덱스"]
    end

    VI_E --> |"Local Search\nDRIFT Search"| QUERY["질의 처리"]
    VI_C --> |"DRIFT Search"| QUERY
    FT_E --> |"BM25 검색"| QUERY
    FT_T --> |"BM25 검색"| QUERY
    GI --> |"그래프 탐색 확장"| QUERY

4.3 커뮤니티 계층 구조 예시

graph TB
    subgraph Level2["Level 2 커뮤니티 (루트)"]
        C2A["C2-A: 엔터프라이즈 IT 시스템 운영\n엔터티 수: 287개\n커뮤니티 리포트 rank: 9.1"]
    end

    subgraph Level1["Level 1 커뮤니티 (중간)"]
        C1A["C1-A: 보안 및 취약점 관리\n엔터티 수: 84개\nrank: 8.5"]
        C1B["C1-B: 애플리케이션 배포 인프라\n엔터티 수: 102개\nrank: 7.8"]
        C1C["C1-C: 서비스 운영 체계\n엔터티 수: 101개\nrank: 7.2"]
    end

    subgraph Level0["Level 0 커뮤니티 (리프)"]
        C0A["C0-A: Java 라이브러리 취약점\n엔터티: Log4j, CVE-2021-44228\nrank: 8.9"]
        C0B["C0-B: 결제 시스템 스택\n엔터티: 결제서비스, 운영서버-001\nrank: 7.4"]
        C0C["C0-C: 인증 서비스 그룹\n엔터티: 인증서버, OAuth2 Provider\nrank: 6.8"]
        C0D["C0-E: 알림 발송 인프라\n엔터티: 알림서버, SES, Kafka\nrank: 6.1"]
    end

    C2A --"PARENT_OF"--> C1A
    C2A --"PARENT_OF"--> C1B
    C2A --"PARENT_OF"--> C1C
    C1A --"PARENT_OF"--> C0A
    C1B --"PARENT_OF"--> C0B
    C1B --"PARENT_OF"--> C0C
    C1C --"PARENT_OF"--> C0D

5. 질의 파이프라인 아키텍처 — 세 가지 탐색 방식

5.1 Local Search 아키텍처 — 엔터티 중심 탐색

flowchart TB
    Q["사용자 질의\n예: 'Log4j 관련 취약점 정보'"]

    subgraph LocalSearch["Local Search 처리 흐름"]
        direction TB
        EMBED_Q["질의 임베딩 생성"]
        VEC_SEARCH["Entity 벡터 인덱스 검색\n→ 유사 엔터티 Top-K 반환\n(Log4j, CVE-2021-44228 등)"]

        subgraph GraphExpansion["Neo4j 그래프 확장 (Cypher)"]
            direction LR
            HOP1["1홉 확장\n인접 엔터티 수집\n(RELATED 관계 탐색)"]
            HOP2["커뮤니티 연결\n(IN_COMMUNITY → HAS_REPORT)"]
            CHUNKS["원본 청크 수집\n(MENTIONS 역방향 탐색)"]
        end

        GATHER["컨텍스트 수집\n엔터티 설명 + 관계 설명\n+ 커뮤니티 요약 + 원본 청크"]
        RANK_LOCAL["관련도 기반 컨텍스트 정렬\n(LLM 토큰 한도 내 구성)"]
        LLM_LOCAL["LLM 응답 생성"]

        EMBED_Q --> VEC_SEARCH --> GraphExpansion
        HOP1 --> GATHER
        HOP2 --> GATHER
        CHUNKS --> GATHER
        GATHER --> RANK_LOCAL --> LLM_LOCAL
    end

    Q --> EMBED_Q
    LLM_LOCAL --> ANS_LOCAL["구체적 엔터티 중심 응답\n(근거: 원본 청크 + 관계 설명)"]

Local Search의 컨텍스트 구성 요소:

컨텍스트 항목출처역할
엔터티 설명Entity.description핵심 개체 정보
관계 설명RELATED.description개체 간 연결 맥락
커뮤니티 요약CommunityReport.summary더 넓은 주제 맥락
원본 텍스트 청크TextUnit.text실제 근거 문장
공변량 정보Covariate엔터티 관련 클레임

5.2 Global Search 아키텍처 — Map-Reduce 패턴

flowchart TB
    Q_G["사용자 질의 (글로벌)\n예: '이 문서 집합의 주요 보안 이슈 패턴은?'"]

    subgraph GlobalSearch["Global Search 처리 흐름"]
        direction TB

        FETCH_CR["지정 레벨 커뮤니티 리포트 전체 조회\n(기본: Level 2, Dynamic Selection 시 필터링)"]

        subgraph MapPhase["Map 단계 (병렬 LLM 처리)"]
            direction LR
            MAP1["CR-A 처리\n→ 부분 답변 A\n→ 관련도 점수"]
            MAP2["CR-B 처리\n→ 부분 답변 B\n→ 관련도 점수"]
            MAP3["CR-C 처리\n→ 부분 답변 C\n→ 관련도 점수"]
            MAPN["CR-N 처리\n..."]
        end

        subgraph ReducePhase["Reduce 단계"]
            SORT["관련도 점수 기반 정렬\n(하위 점수 필터 가능)"]
            REDUCE_LLM["최종 통합 LLM 호출\n(상위 부분 답변들 통합)"]
        end

        FETCH_CR --> MapPhase
        MAP1 --> SORT
        MAP2 --> SORT
        MAP3 --> SORT
        MAPN --> SORT
        SORT --> REDUCE_LLM
    end

    Q_G --> FETCH_CR
    REDUCE_LLM --> ANS_G["전체 데이터 조망 응답\n(커뮤니티 구조 기반)"]

Dynamic Community Selection (동적 커뮤니티 선택)

전체 커뮤니티 리포트를 모두 LLM에 통과시키는 기본 Global Search는 비용이 큽니다. 2025년 1월 도입된 Dynamic Community Selection은 이를 개선합니다.

flowchart LR
    ALL_CR["전체 커뮤니티 리포트"]

    subgraph DCS["Dynamic Community Selection"]
        CHEAP_LLM["저비용 LLM으로\n관련도 점수만 계산\n(gpt-4o-mini 등)"]
        THRESHOLD["관련도 임계값 필터링\n(낮은 점수 커뮤니티 제거)"]
        MAIN_LLM["관련 커뮤니티만\n고품질 LLM 처리"]
    end

    ALL_CR --> CHEAP_LLM --> THRESHOLD --> MAIN_LLM --> FINAL["최종 응답"]

    NOTE["토큰 비용 최대 79% 절감\n(2025년 1월 업데이트)"]

5.3 DRIFT Search 아키텍처 — 글로벌과 로컬의 통합

flowchart TB
    Q_D["사용자 질의\n예: '결제 관련 시스템의 보안 취약점 영향은?'"]

    subgraph DRIFTSearch["DRIFT Search 처리 흐름"]
        direction TB

        HYDE["HyDE\n(Hypothetical Document Embeddings)\n→ 가상 이상 문서 생성 후 임베딩"]

        VEC_COMM["커뮤니티 벡터 검색\n→ 관련 커뮤니티 리포트 Top-K"]

        subgraph Primer["1차: 글로벌 컨텍스트 수집"]
            COMM_CTX["커뮤니티 요약 → 초기 컨텍스트\n초기 응답 생성 + 신뢰도 점수"]
            FOLLOW_UP["LLM이 팔로업 질문 자동 생성\n(예: '결제서비스는 어떤 버전 사용?'\n'CVE-2021-44228 영향 범위는?')"]
        end

        subgraph Iteration["2차~N차: 로컬 탐색 반복"]
            direction LR
            LOCAL_1["팔로업 질문 1\n→ Local Search 실행"]
            LOCAL_2["팔로업 질문 2\n→ Local Search 실행"]
            LOCAL_N["팔로업 질문 N\n→ Local Search 실행"]
            CONF_CHECK["신뢰도 평가\n(충분한가? → 종료\n부족한가? → 추가 팔로업)"]
        end

        HIERARCHY["계층적 Q&A 구조 구성\n(최상위 질의 + 팔로업 + 답변 트리)"]
        FINAL_GEN["최종 통합 응답 생성"]

        HYDE --> VEC_COMM --> Primer
        COMM_CTX --> FOLLOW_UP --> Iteration
        LOCAL_1 --> CONF_CHECK
        LOCAL_2 --> CONF_CHECK
        LOCAL_N --> CONF_CHECK
        CONF_CHECK --> HIERARCHY --> FINAL_GEN
    end

    Q_D --> HYDE
    FINAL_GEN --> ANS_D["구조화된 종합 응답\n(글로벌 맥락 + 로컬 근거)"]

6. Hybrid RAG 통합 아키텍처 — BM25 + Vector + Community

세 가지 MS GraphRAG 탐색 방식에 BM25 키워드 검색을 더하면 완전한 Hybrid RAG 시스템이 됩니다. 각 검색 방식은 서로 다른 강점을 가지며 상호 보완합니다.

6.1 네 가지 검색 경로의 역할

flowchart TB
    Q["사용자 질의"]

    subgraph FourPaths["네 가지 검색 경로"]
        direction TB

        subgraph P_BM25["① BM25 키워드 검색"]
            BM25_DESC["강점: 정확한 용어 매칭\n예: CVE ID, 버전 번호, 시스템 이름\n약점: 표현 변화에 취약"]
            BM25_SRC["소스: Neo4j Full-text Index\n또는 Elasticsearch"]
        end

        subgraph P_LOCAL["② Local Search (벡터 + 그래프)"]
            LOCAL_DESC["강점: 특정 엔터티 중심 탐색\n멀티홉 관계 확장\n약점: 전체 맥락 파악 제한"]
            LOCAL_SRC["소스: Entity 벡터 인덱스\n+ Neo4j 그래프 탐색"]
        end

        subgraph P_GLOBAL["③ Global Search (커뮤니티 요약)"]
            GLOBAL_DESC["강점: 전체 데이터 조망\n주제 파악, 패턴 발견\n약점: 구체적 사실 응답 약함"]
            GLOBAL_SRC["소스: CommunityReport 노드\n+ Map-Reduce LLM"]
        end

        subgraph P_DRIFT["④ DRIFT Search (혼합)"]
            DRIFT_DESC["강점: 글로벌 + 로컬 균형\n복합적 질의 대응\n약점: 가장 높은 LLM 비용"]
            DRIFT_SRC["소스: Community 벡터 인덱스\n+ 반복적 Local 탐색"]
        end
    end

    MERGE_ALL["결과 통합 레이어\n(RRF + 가중치 조정)"]
    CTX_BUILD["컨텍스트 구성"]
    LLM_FINAL["LLM 최종 응답"]

    Q --> P_BM25
    Q --> P_LOCAL
    Q --> P_GLOBAL
    Q --> P_DRIFT

    P_BM25 --> MERGE_ALL
    P_LOCAL --> MERGE_ALL
    P_GLOBAL --> MERGE_ALL
    P_DRIFT --> MERGE_ALL

    MERGE_ALL --> CTX_BUILD --> LLM_FINAL --> RESPONSE["최종 응답"]

6.2 질의 특성별 검색 경로 가중치

모든 질의에 네 가지 경로를 동일 비중으로 사용하는 것은 비효율적입니다. 질의 특성에 따라 가중치를 동적으로 조정합니다.

질의 유형BM25LocalGlobalDRIFT예시
정확한 용어 기반높음중간낮음낮음“CVE-2021-44228 상세 정보”
특정 엔터티 탐색중간높음낮음낮음“Log4j 사용 애플리케이션 목록”
전체 패턴 분석낮음낮음높음중간“문서 전체의 보안 이슈 패턴”
복합 관계 분석낮음중간중간높음“결제 시스템 보안 취약점 영향 전체”

6.3 Hybrid RAG 통합 아키텍처 전체도

flowchart LR
    subgraph InputLayer["입력 계층"]
        USER_Q["사용자 질의"]
        EMBED_SVC["임베딩 서비스\n(질의 → 벡터)"]
        USER_Q --> EMBED_SVC
    end

    subgraph RouterLayer["라우터 계층"]
        QROUTER["질의 라우터\n(유형 분류 + 가중치 결정)"]
        EMBED_SVC --> QROUTER
    end

    subgraph RetrievalLayer["검색 계층"]
        subgraph BM25_PATH["BM25 경로"]
            BM25_E["엔터티 전문 검색\n(Neo4j Full-text)"]
            BM25_T["청크 전문 검색\n(Neo4j Full-text)"]
        end

        subgraph LOCAL_PATH["Local Search 경로"]
            VEC_E["엔터티 벡터 검색\n(Neo4j ANN)"]
            CYPHER_EXPAND["Cypher 그래프 확장\n(RELATED / IN_COMMUNITY\nHAS_REPORT / MENTIONS)"]
            VEC_E --> CYPHER_EXPAND
        end

        subgraph GLOBAL_PATH["Global Search 경로"]
            ALL_CR_FETCH["커뮤니티 리포트 조회\n(지정 Level)"]
            DYN_SEL["Dynamic Selection\n(저비용 LLM 필터링)"]
            MAP_REDUCE["Map-Reduce LLM 처리"]
            ALL_CR_FETCH --> DYN_SEL --> MAP_REDUCE
        end

        subgraph DRIFT_PATH["DRIFT Search 경로"]
            HYDE_GEN["HyDE 생성"]
            COMM_VEC["커뮤니티 벡터 검색"]
            ITER_LOCAL["반복 Local 탐색"]
            HYDE_GEN --> COMM_VEC --> ITER_LOCAL
        end

        QROUTER --> BM25_PATH
        QROUTER --> LOCAL_PATH
        QROUTER --> GLOBAL_PATH
        QROUTER --> DRIFT_PATH
    end

    subgraph FusionLayer["결합 계층"]
        RRF["RRF\n(Reciprocal Rank Fusion)"]
        WEIGHT["가중 통합\n(라우터 가중치 적용)"]
        RERANK["Reranker 모델\n(Cross-encoder 선택적 적용)"]

        BM25_E --> RRF
        BM25_T --> RRF
        CYPHER_EXPAND --> RRF
        MAP_REDUCE --> RRF
        ITER_LOCAL --> RRF
        RRF --> WEIGHT --> RERANK
    end

    subgraph GenerationLayer["생성 계층"]
        CTX_ASSEMBLE["컨텍스트 조립\n(토큰 한도 내 최적 구성)"]
        PROMPT_BUILD["프롬프트 구성\n(시스템 지시 + 컨텍스트 + 질의)"]
        GEN_LLM["생성 LLM\n(GPT-4o / Claude Sonnet)"]
        PROV["근거 추적\n(Provenance)"]

        RERANK --> CTX_ASSEMBLE --> PROMPT_BUILD --> GEN_LLM
        GEN_LLM --> PROV --> FINAL_ANS["최종 응답"]
    end

    subgraph Neo4jStorage["Neo4j 데이터 저장소"]
        GRAPH_STORE["그래프 저장\n(Entity, Relation, Community\nCommunityReport, TextUnit)"]
        VEC_STORE["벡터 인덱스\n(ANN)"]
        FT_STORE["전문 검색 인덱스\n(Full-text / BM25)"]
    end

    LOCAL_PATH --> GRAPH_STORE
    LOCAL_PATH --> VEC_STORE
    BM25_PATH --> FT_STORE
    GLOBAL_PATH --> GRAPH_STORE
    DRIFT_PATH --> VEC_STORE
    DRIFT_PATH --> GRAPH_STORE

7. LazyGraphRAG 변형 아키텍처

7.1 LazyGraphRAG가 인덱싱 단계를 어떻게 바꾸는가

flowchart TB
    subgraph TraditionalIndexing["전통적 GraphRAG 인덱싱"]
        direction LR
        TI1["LLM 엔터티/관계 추출\n(모든 청크)"]
        TI2["Leiden 커뮤니티 탐지"]
        TI3["LLM 커뮤니티 요약 생성\n(모든 커뮤니티)"]
        TI4["임베딩 생성"]
        TI5["Neo4j 적재"]

        TI1 --> TI2 --> TI3 --> TI4 --> TI5

        COST1["비용: LLM 추출 + 요약\n= 전체의 ~99%\n상대 비용: 100%"]
    end

    subgraph LazyIndexing["LazyGraphRAG 인덱싱"]
        direction LR
        LI1["NLP 명사구 추출\n(LLM 없음, spaCy 등)"]
        LI2["공유 명사구 기반\n그래프 구성"]
        LI3["Leiden 커뮤니티 탐지\n(LLM 없음)"]
        LI4["청크 임베딩 생성만"]
        LI5["Neo4j 적재"]

        LI1 --> LI2 --> LI3 --> LI4 --> LI5

        COST2["비용: 임베딩만\n상대 비용: 0.1%\n(LLM 호출 없음)"]
    end

    subgraph LazyQuery["LazyGraphRAG 질의 시점 처리"]
        direction LR
        LQ1["벡터 검색\n(관련 청크 후보)"]
        LQ2["저비용 LLM으로\n관련도 테스트\n(Budget 설정)"]
        LQ3["커뮤니티 기반\n지식 확장"]
        LQ4["최종 응답 생성\n(고품질 LLM)"]

        LQ1 --> LQ2 --> LQ3 --> LQ4

        COST3["비용: 질의당 발생\n예산 제어 가능"]
    end

    TraditionalIndexing --> |"대비"| LazyIndexing
    LazyIndexing --> LazyQuery

7.2 LazyGraphRAG 적용 시 Neo4j 저장 구조 변화

flowchart LR
    subgraph TraditionalNeo4j["전통적 GraphRAG Neo4j 구조"]
        T_ENT["Entity 노드\n(LLM 추출, 설명 포함)"]
        T_REL["RELATED 관계\n(LLM 추출)"]
        T_COMM["Community 노드\n(Leiden)"]
        T_RPT["CommunityReport 노드\n(LLM 생성 요약)"]
        T_TU["TextUnit 노드\n(청크 + 임베딩)"]
        T_ENT --- T_REL
        T_ENT --- T_COMM --- T_RPT
        T_TU --- T_ENT
    end

    subgraph LazyNeo4j["LazyGraphRAG Neo4j 구조"]
        L_NOUN["NounPhrase 노드\n(NLP 추출 명사구)"]
        L_CO["COOCCURS_IN 관계\n(동일 청크 내 공출현)"]
        L_COMM["Community 노드\n(Leiden, 요약 없음)"]
        L_TU["TextUnit 노드\n(청크 + 임베딩 필수)"]
        L_NOUN --- L_CO
        L_NOUN --- L_COMM
        L_TU --- L_NOUN

        NOTE_L["커뮤니티 요약은\n질의 시점에\n온디맨드 생성"]
    end

7.3 LazyGraphRAG 질의 파이프라인

flowchart TB
    Q_LAZY["사용자 질의"]

    subgraph LazyQueryPipeline["LazyGraphRAG 질의 파이프라인"]
        direction TB

        BEST_FIRST["Best-first 탐색\n(벡터 유사도 기반\n청크 후보 수집)"]

        subgraph BudgetedTest["관련도 테스트 (Budget 제어)"]
            CHEAP["저비용 LLM\n(gpt-4o-mini)\n→ 각 청크 관련도 0~1 점수"]
            BUDGET_CHECK["Budget 소진 여부 확인\n(relevance_test_budget 파라미터)"]
            EXPAND["관련 청크 → 커뮤니티 확장"]

            CHEAP --> BUDGET_CHECK --> EXPAND
        end

        subgraph BreadthFirst["Breadth-first 확장"]
            COMM_EXPAND["커뮤니티 노드 탐색\n→ 추가 관련 청크 발견"]
            ITER_CHECK["반복 계속 여부 결정\n(품질 vs 비용 trade-off)"]
            COMM_EXPAND --> ITER_CHECK
        end

        FINAL_GEN["최종 응답 생성\n(고품질 LLM)"]

        BEST_FIRST --> BudgetedTest
        EXPAND --> BreadthFirst
        ITER_CHECK --> FINAL_GEN
    end

    Q_LAZY --> BEST_FIRST
    FINAL_GEN --> ANS_LAZY["비용 효율적 응답\n(Traditional GraphRAG 대비\n로컬: 동등 이상\n글로벌: 700배 낮은 비용)"]

8. 질의 유형별 라우팅 설계

8.1 라우터 판단 기준

질의 라우터는 들어오는 질의를 분석하여 최적의 검색 경로를 선택합니다. 분류는 두 가지 차원으로 이루어집니다.

flowchart TB
    Q_INPUT["사용자 질의 입력"]

    subgraph Dim1["차원 1: 범위 (Scope)"]
        direction LR
        SPEC["구체적\n(특정 엔터티/사실)"]
        BROAD["광범위\n(전체 데이터 조망)"]
    end

    subgraph Dim2["차원 2: 관계 복잡성"]
        direction LR
        SIMPLE["단순\n(직접 검색)"]
        COMPLEX["복잡\n(멀티홉 추론)"]
    end

    subgraph RoutingMatrix["라우팅 매트릭스"]
        direction TB

        CELL_SS["구체적 + 단순\n→ BM25 우선\n+ Local Search 보완"]
        CELL_SC["구체적 + 복잡\n→ Local Search 우선\n+ DRIFT 보완"]
        CELL_BS["광범위 + 단순\n→ Global Search 우선\n+ BM25 보완"]
        CELL_BC["광범위 + 복잡\n→ DRIFT Search 우선\n+ Global 보완"]
    end

    Q_INPUT --> Dim1
    Q_INPUT --> Dim2
    Dim1 --> RoutingMatrix
    Dim2 --> RoutingMatrix

8.2 라우팅 판단 흐름도

flowchart TD
    Q["질의 입력"]

    A{"명시적 식별자 포함?\n(CVE ID, 버전, 코드명 등)"}
    B{"전체 데이터 분석 요구?\n('전체', '패턴', '모든', '요약' 등 키워드)"}
    C{"관계 추적 필요?\n('영향', '의존', '연결', '경로' 등)"}
    D{"복합 질의?\n(다중 엔터티, 조건 결합)"}

    R1["BM25 우선\n+ Local 보완\n(정확한 키워드 매칭)"]
    R2["Global Search 우선\n+ BM25 보완\n(전체 조망)"]
    R3["Local Search 우선\n+ DRIFT 보완\n(관계 탐색)"]
    R4["DRIFT Search 우선\n+ Global + Local\n(종합 분석)"]
    R5["Local Search 기본\n+ BM25 보완\n(일반적 탐색)"]

    Q --> A
    A --> |"예"| R1
    A --> |"아니오"| B
    B --> |"예"| R2
    B --> |"아니오"| C
    C --> |"예"| D
    C --> |"아니오"| R5
    D --> |"예"| R4
    D --> |"아니오"| R3

8.3 라우팅 예시 — 아키텍처팀 실무 질의

질의 예시분류선택 경로
“CVE-2021-44228 영향받는 버전은?”구체적+단순BM25 → Local 보완
“Log4j 사용 애플리케이션의 배포 서버는?”구체적+복잡Local Search → DRIFT 보완
“장애 보고서 전체에서 반복되는 원인 패턴은?”광범위+단순Global Search
“결제 시스템과 연관된 보안 취약점의 전체 영향 범위는?”광범위+복잡DRIFT Search
“우리 아키텍처 문서의 주요 의존성 리스크는?”광범위+복잡DRIFT Search

9. 운영 아키텍처 설계

9.1 전체 운영 컴포넌트 구성

flowchart TB
    subgraph ExternalSystems["외부 데이터 소스"]
        direction LR
        CONFLU["Confluence\n(기술 문서)"]
        JIRA["Jira\n(장애/이슈 이력)"]
        GIT["Git Repo\n(README, ADR)"]
        SHARE["SharePoint\n(보고서, 메뉴얼)"]
    end

    subgraph IngestionPipeline["수집 및 인덱싱 파이프라인"]
        direction TB
        COLLECTOR["문서 수집기\n(커넥터별 API)"]
        NORMALIZER["문서 정규화\n(포맷 통일 / 메타데이터)"]
        MSRAG_RUNNER["MS GraphRAG 인덱서\n(graphrag index CLI)"]
        PARQUET_STAGE["Parquet 스테이징\n(S3 / MinIO)"]
        NEO4J_LOADER["Neo4j 로더\n(Parquet → Cypher)"]
        IDX_BUILDER["인덱스 구축\n(벡터 + 전문 검색)"]

        COLLECTOR --> NORMALIZER --> MSRAG_RUNNER --> PARQUET_STAGE --> NEO4J_LOADER --> IDX_BUILDER
    end

    subgraph OrchestrationLayer["오케스트레이션 계층"]
        AIRFLOW["Apache Airflow\n(배치 스케줄링)"]
        MONITOR["모니터링\n(Prometheus / Grafana)"]
        ALERT["알림\n(품질 이상 / 오류)"]
    end

    subgraph CoreServices["핵심 서비스"]
        direction TB
        API_GW["API Gateway\n(인증 / 라우팅)"]

        subgraph QueryService["질의 서비스"]
            Q_ROUTER["질의 라우터"]
            LOCAL_SVC["Local Search 서비스"]
            GLOBAL_SVC["Global Search 서비스"]
            DRIFT_SVC["DRIFT Search 서비스"]
            BM25_SVC["BM25 검색 서비스"]
            FUSION_SVC["결과 통합 서비스\n(RRF + Reranker)"]
        end

        LLM_PROXY["LLM 프록시\n(모델 선택 / 비용 제어)"]
        CACHE["응답 캐시\n(Redis)"]
    end

    subgraph StorageLayer["저장 계층"]
        NEO4J_PROD["Neo4j\n(Graph + Vector + Full-text)"]
        RAW_STORE["원본 문서 저장\n(S3 / MinIO)"]
        METADATA_DB["메타데이터 DB\n(PostgreSQL)"]
    end

    subgraph LLMLayer["LLM 계층"]
        EMBED_MODEL["임베딩 모델\n(text-embedding-3-large)"]
        EXT_MODEL["추출 LLM\n(gpt-4o-mini: 비용 절감)"]
        GEN_MODEL["생성 LLM\n(gpt-4o / Claude Sonnet)"]
    end

    subgraph ClientLayer["클라이언트"]
        WEB_UI["웹 챗봇 UI"]
        API_CLI["API 클라이언트"]
    end

    ExternalSystems --> COLLECTOR
    AIRFLOW --> IngestionPipeline
    IDX_BUILDER --> NEO4J_PROD

    WEB_UI --> API_GW
    API_CLI --> API_GW
    API_GW --> Q_ROUTER

    Q_ROUTER --> LOCAL_SVC
    Q_ROUTER --> GLOBAL_SVC
    Q_ROUTER --> DRIFT_SVC
    Q_ROUTER --> BM25_SVC

    LOCAL_SVC --> FUSION_SVC
    GLOBAL_SVC --> FUSION_SVC
    DRIFT_SVC --> FUSION_SVC
    BM25_SVC --> FUSION_SVC

    FUSION_SVC --> LLM_PROXY --> GEN_MODEL
    LOCAL_SVC --> NEO4J_PROD
    GLOBAL_SVC --> NEO4J_PROD
    DRIFT_SVC --> NEO4J_PROD
    BM25_SVC --> NEO4J_PROD

    EMBED_MODEL --> NEO4J_PROD
    EXT_MODEL --> MSRAG_RUNNER

    LLM_PROXY --> CACHE
    MONITOR --> CoreServices
    ALERT --> MONITOR

9.2 데이터 갱신 주기 설계

Index-based GraphRAG의 갱신 전략은 재인덱싱 비용을 고려하여 설계해야 합니다.

flowchart LR
    subgraph UpdateStrategy["갱신 전략"]
        direction TB

        subgraph Strategy1["전략 1: 전체 재인덱싱 (Full Reindex)"]
            FR_WHEN["주기: 월 1회 또는 대규모 문서 변경 시"]
            FR_HOW["방식: 전체 MS GraphRAG 인덱싱 재실행\n→ Neo4j 전체 교체"]
            FR_COST["비용: 가장 높음\n품질: 가장 일관됨"]
        end

        subgraph Strategy2["전략 2: 증분 인덱싱 (Incremental)"]
            INC_WHEN["주기: 주 1회 또는 신규 문서 발생 시"]
            INC_HOW["방식: 신규/변경 문서만 인덱싱\n→ 그래프에 병합 (MERGE)"]
            INC_COST["비용: 중간\n주의: 커뮤니티 구조 불일치 가능"]
        end

        subgraph Strategy3["전략 3: LazyGraphRAG + 실시간 청크 갱신"]
            LZ_WHEN["주기: 문서 변경 즉시"]
            LZ_HOW["방식: 임베딩만 갱신\n→ 커뮤니티 요약은 질의 시 생성"]
            LZ_COST["비용: 가장 낮음\n단점: 고정 커뮤니티 구조 활용 불가"]
        end
    end

    Strategy1 --> |"권장 시나리오"| S1_REC["대규모 문서 집합\n일관성 중요한 운영 환경"]
    Strategy2 --> |"권장 시나리오"| S2_REC["지속적 문서 추가 환경\n커뮤니티 재계산 허용 가능"]
    Strategy3 --> |"권장 시나리오"| S3_REC["실시간성 요구\n초기 도입 / PoC 단계"]

10. 단계별 구현 전략 — PoC에서 운영까지

10.1 4단계 구현 로드맵

flowchart LR
    subgraph Stage1["Stage 1: PoC\n(2~4주)"]
        S1A["소규모 문서 선정\n(50~200개)"]
        S1B["MS GraphRAG CLI로\n인덱싱 실행"]
        S1C["Parquet → Neo4j 적재\n(기본 Import 스크립트)"]
        S1D["Local + Global 검색\n직접 테스트"]
        S1E["질의 품질 평가\n(BenchmarkQED 활용)"]
        S1A --> S1B --> S1C --> S1D --> S1E
    end

    subgraph Stage2["Stage 2: Pilot\n(1~2개월)"]
        S2A["BM25 전문 검색\n인덱스 추가"]
        S2B["질의 라우터 구현\n(규칙 기반 초안)"]
        S2C["DRIFT Search 통합"]
        S2D["결과 통합 레이어\n(RRF 구현)"]
        S2E["소수 사용자 시범 서비스"]
        S2A --> S2B --> S2C --> S2D --> S2E
    end

    subgraph Stage3["Stage 3: 운영 전환\n(2~3개월)"]
        S3A["자동화 인덱싱\n파이프라인 구축\n(Airflow)"]
        S3B["API Gateway 통합\n+ 인증 체계"]
        S3C["LazyGraphRAG 검토\n(비용 최적화)"]
        S3D["모니터링 대시보드\n구축"]
        S3E["전체 문서 적재\n+ 품질 검증"]
        S3A --> S3B --> S3C --> S3D --> S3E
    end

    subgraph Stage4["Stage 4: 고도화\n(지속)"]
        S4A["Knowledge-based 병행\n(Neo4j 온톨로지 추가)"]
        S4B["도메인 특화 프롬프트\n(auto-tuning 활용)"]
        S4C["멀티모달 확장\n(다이어그램, 표 등)"]
        S4D["에이전트 워크플로우\n(LangGraph 통합)"]
        S4A --> S4B --> S4C --> S4D
    end

    Stage1 --> Stage2 --> Stage3 --> Stage4

10.2 단계별 핵심 의사결정 포인트

flowchart TD
    D1{"LazyGraphRAG vs\n전통적 GraphRAG?"}
    D2{"Neo4j AuraDB(클라우드) vs\n자체 호스팅?"}
    D3{"엔터티 유형 설정\n자동 vs 수동?"}
    D4{"커뮤니티 레벨\n몇 단계까지?"}
    D5{"LLM 모델 선택\n추출 vs 생성 분리?"}

    D1 --> |"PoC / 비용 제약"| LAZY_CHOICE["LazyGraphRAG 선택\n인덱싱 비용 0.1%"]
    D1 --> |"품질 우선 / 예산 여유"| FULL_CHOICE["전통적 GraphRAG 선택\n더 풍부한 커뮤니티 요약"]

    D2 --> |"빠른 시작 / 소규모"| AURA["Neo4j AuraDB\n(관리형, 월정액)"]
    D2 --> |"대규모 / 보안 요구"| SELF["자체 Neo4j 클러스터\n(Kubernetes 권장)"]

    D3 --> |"도메인 불명확 / PoC"| AUTO_TYPES["자동 추론 (기본 유형 사용)\n나중에 도메인 특화로 정제"]
    D3 --> |"도메인 명확"| MANUAL_TYPES["수동 설정 권장\n(2~4시간 auto-tuning 활용)"]

    D4 --> |"소규모 문서"| L2["Level 2까지 (기본)\n속도 빠름 / 커뮤니티 수 적음"]
    D4 --> |"대규모 복잡 문서"| L3["Level 3+ 고려\n더 세밀한 커뮤니티 구조"]

    D5 --> |"비용 최적화"| SPLIT_MODEL["추출: gpt-4o-mini\n생성: gpt-4o 또는 Claude Sonnet\n비용 절감 효과 큼"]
    D5 --> |"단순 구성 선호"| SINGLE_MODEL["단일 모델 사용\n(gpt-4o / Claude Sonnet)"]

11. Knowledge-based GraphRAG와 병행 활용

Index-based와 Knowledge-based GraphRAG는 각자 잘하는 영역이 다릅니다. 두 방식을 Neo4j라는 단일 플랫폼에서 병행 운영하는 것이 이상적입니다.

11.1 같은 Neo4j에서 두 방식 공존

flowchart TB
    subgraph Neo4j["Neo4j 단일 인스턴스 (또는 클러스터)"]
        subgraph IndexGraph["Index-based 그래프\n(MS GraphRAG 산출물)"]
            I_ENT["Entity 노드\n(자유 추출)"]
            I_REL["RELATED 관계"]
            I_COMM["Community 노드"]
            I_RPT["CommunityReport 노드"]
            I_TU["TextUnit 노드"]
            I_ENT --- I_REL
            I_ENT --- I_COMM --- I_RPT
            I_TU --- I_ENT
        end

        subgraph KBGraph["Knowledge-based 그래프\n(온톨로지 기반)"]
            K_APP["Application 노드"]
            K_LIB["Library 노드"]
            K_VULN["Vulnerability 노드"]
            K_SRV["Server 노드"]
            K_SVC["Service 노드"]
            K_APP --"USES"--> K_LIB
            K_VULN --"AFFECTS"--> K_LIB
            K_APP --"DEPLOYED_ON"--> K_SRV
            K_APP --"PROVIDES"--> K_SVC
        end

        subgraph CrossLink["두 그래프 연결"]
            BRIDGE["SAME_AS 관계\n(엔터티 매핑)\n예: I_ENT(Log4j) SAME_AS K_LIB(Log4j)"]
        end

        I_ENT -.->|"SAME_AS"| K_LIB
    end

    QUERY_ROUTER["질의 라우터"]
    QUERY_ROUTER --> |"패턴 분석 / 글로벌 질의"| IndexGraph
    QUERY_ROUTER --> |"관계 탐색 / 영향도 분석"| KBGraph
    QUERY_ROUTER --> |"복합 질의"| CrossLink

11.2 두 방식의 역할 분담

flowchart LR
    subgraph Questions["질의 유형별 담당"]
        Q1["'이 문서 집합의 핵심 주제는?'"]
        Q2["'반복되는 장애 패턴은?'"]
        Q3["'Log4j 취약점 영향 서비스는?'"]
        Q4["'결제팀이 관리하는 외부 서비스는?'"]
        Q5["'보안 이슈 전반의 맥락과\n특정 시스템의 영향 범위는?'"]
    end

    IB["Index-based GraphRAG\n(글로벌 패턴, 테마 분석)"]
    KB["Knowledge-based GraphRAG\n(정밀 관계 탐색, 영향도 분석)"]
    HYBRID_Q["두 방식 결합\n(복합 질의)"]

    Q1 --> IB
    Q2 --> IB
    Q3 --> KB
    Q4 --> KB
    Q5 --> HYBRID_Q

12. 결론

12.1 이 시스템이 제공하는 가치

Index-based GraphRAG를 Neo4j와 통합하고 BM25를 추가한 Hybrid RAG 시스템은 기존 Vector RAG에서 출발하여 세 가지 방향으로 능력을 확장합니다.

첫째, 전체 조망 능력. 커뮤니티 기반 요약 색인을 활용하면 수천 개의 문서를 단일 Vector RAG로는 얻을 수 없는 방식으로 포괄적으로 이해할 수 있습니다. “이 문서 집합의 핵심 패턴은 무엇인가?”라는 질문에 전체 데이터를 조망하여 답할 수 있습니다.

둘째, 관계 기반 탐색. Neo4j의 그래프 저장 구조와 Cypher 탐색을 통해 엔터티 중심의 Local Search가 가능합니다. 특정 기술이나 시스템과 연결된 지식을 그래프를 따라가며 수집하는 능력이 Vector RAG를 초월합니다.

셋째, 비용 유연성. LazyGraphRAG 적용 시 인덱싱 비용을 전통적 GraphRAG 대비 0.1% 수준으로 낮출 수 있어, 대규모 문서 집합에서도 경제적으로 도입 가능합니다.

12.2 최종 아키텍처 결정 프레임

flowchart TD
    START["Index-based GraphRAG + Neo4j\nHybrid RAG 도입 결정"]

    C1{"도메인 명확한\n관계 질의 중심?"}
    C2{"전체 데이터 조망\n/ 패턴 분석 필요?"}
    C3{"인덱싱 비용\n허용 범위?"}
    C4{"실시간 갱신\n필요?"}

    R_KB["Knowledge-based 위주\n(온톨로지 + Neo4j)\n이 문서 참조"]

    R_FULL["전통적 GraphRAG\n(Full Indexing)\nGlobal 검색 최적화"]

    R_LAZY["LazyGraphRAG\n(인덱싱 최소화)\n질의 시점 처리"]

    R_BOTH["두 방식 병행\n(Index + Knowledge-based)\n최고 품질 달성"]

    C1 --> |"예"| R_KB
    C1 --> |"아니오"| C2
    C2 --> |"예"| C3
    C2 --> |"아니오"| R_KB
    C3 --> |"충분"| C4
    C3 --> |"제한적"| R_LAZY
    C4 --> |"필요"| R_LAZY
    C4 --> |"불필요"| R_FULL
    R_KB --> |"추가 발전"| R_BOTH
    R_FULL --> |"추가 발전"| R_BOTH

세 가지 문서 — 메인 세미나 자료, Index-based 심화, Knowledge-based 심화, 그리고 이 문서 — 는 각각 독립적으로 읽을 수 있지만, 함께 읽을 때 가장 완전한 그림을 그릴 수 있습니다. 이 문서는 Index-based 관점에서 Neo4j Hybrid RAG 시스템을 실제로 어떻게 설계하고 구현할 것인지를 아키텍처 중심으로 정리한 것입니다.


참고 자료

  • Microsoft GraphRAG 공식 문서: https://microsoft.github.io/graphrag/
  • Neo4j Blog: “Integrating Microsoft GraphRAG into Neo4j” (Tomaz Bratanic, 2024)
  • Neo4j + GitHub: ms-graphrag-neo4j 공식 통합 레포지터리
  • Microsoft Research Blog: “LazyGraphRAG: Setting a New Standard for Quality and Cost” (November 2024)
  • Microsoft Research Blog: “BenchmarkQED: Automated Benchmarking of RAG Systems” (June 2025)
  • Microsoft Research Blog: “GraphRAG: Improving Global Search via Dynamic Community Selection” (January 2025)
  • Paperclipped.de: “Graph RAG in 2026: What Works in Production” (March 2026)
  • Microsoft GraphRAG GitHub CLI Reference: --community-level, --dynamic-community-selection 파라미터
  • Neo4j × Microsoft 공식 협력: Azure Marketplace AuraDB 통합

작성일: 2026-05-11
작성자: 아키텍처팀
관련 문서: Neo4j 기반 GraphRAG를 활용한 Hybrid RAG 시스템 구현
관련 문서: Index-based GraphRAG 심화 이해
관련 문서: Knowledge-based GraphRAG 심화 이해

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.