안녕하세요 여러분, 저는 원문 텍스트로부터 지식 그래프 (Knowledge Graph)를 구축하고, 주제별 커뮤니티를 탐지하며, 표준 벡터 검색 (vector retrieval)의 "중간에서 길을 잃는 (lost in the middle)" 문제를 해결하기 위해 하이브리드 검색 (hybrid search)을 사용하는 오픈소스 풀스택 파이프라인 (Django + React)을 구축했습니다.
파이프라인 구성:
수집 및 청킹 (Ingestion & Chunking): 원문 텍스트를 정제, 파싱하고 로컬 컨텍스트 (local context)를 보존하기 위해 중첩되는 청크 (overlapping chunks)로 분할합니다.
그래프 구축 (Graph Construction): spaCy를 사용하여 각 청크에서 개체명 (named entities)을 추출합니다. NetworkX를 사용하여 가중치가 부여된 공기 (co-occurrence) 그래프를 구축하며, 어떤 개체들이 함께 나타나는지 매핑하고 이를 소스 청크와 연결합니다.
커뮤니티 탐지 (Community Detection): greedy_modularity_communities를 사용하여 그래프를 주제별 클러스터 (thematic clusters)로 분할합니다. 각 클러스터에 대해 무작위 텍스트 청크를 샘플링하여 LLM에 보내 상위 수준의 요약 (high-level summary)을 생성합니다 ("허브 노드 (hub node)" 편향 방지).
인덱싱 (Indexing): 모든 청크는 밀집 벡터 저장소 (dense vector store)에 임베딩되며, 동일한 코퍼스 (corpus)에 대해 희소 BM25 인덱스가 구축됩니다.
하이브리드 검색 (Hybrid Retrieval): 쿼리가 들어오면 시스템은 이중 검색 (밀집 벡터 (Dense Vector) + BM25)을 수행합니다. 동시에 프롬프트 (prompt)에서 개체를 추출하고, 그래프를 탐색하여 1차 이웃 (1st-degree neighbors)을 찾은 뒤 이와 관련된 청크를 검색합니다.
융합 및 재순위화 (Fusion & Reranking): 로컬 결과와 글로벌 결과 (커뮤니티 요약)를 병합, 중복 제거하고 상호 순위 융합 (Reciprocal Rank Fusion, RRF)을 사용하여 점수를 매깁니다. 이후 최상위 K개의 후보는 최대 정밀도를 위해 교차 인코더 (Cross-Encoder)에 의해 재점수화됩니다.
LLM 합성 (LLM Synthesis): 최종적으로 선별된 컨텍스트 (context)는 엄격한 프롬프팅 (prompting)과 함께 LLM에 전달되어 간결하고 구조화되었으며 인용이 포함된 답변을 생성합니다.
작동 원리:
표준 벡터 검색은 다음과 같은 멀티홉 (multi-hop) 쿼리에서 실패합니다: "Sansa의 아버지의 처형을 명령한 사람은 누구이며, 그 사람은 결국 어떻게 죽었습니까?"
그래프를 탐색함으로써 (Sansa -> Ned -> Joffrey -> Poisoning), 시스템은 단절된 텍스트 청크 사이의 간극을 메우고 정확한 답변을 합성합니다.
GitHub: https://github.com/mohammad-majoony/graphrag-studio
피드백을 환영합니다! 감사합니다.
submitted by /u/Future_Caregiver_643 to r/MachineLearning [link] [comments]