8 min read
AI assisted

LightRAG 계열 4종 비교 — 같은 뿌리, 다른 프로덕션화 전략

LightRAG에서 파생된 RAG-Anything·ApeRAG·EdgeQuake의 소스코드 레벨 비교

LightRAG는 홍콩대(HKUDS) 연구팀이 2024년 공개한 Graph RAG 프레임워크입니다. 문서에서 엔티티와 관계를 추출해 그래프로 인덱싱하고, 쿼리 시 그래프 탐색과 벡터 검색을 결합해 답변을 생성합니다. 오픈소스 공개 이후 세 개의 파생 프로젝트가 등장했습니다. RAG-Anything, ApeRAG, EdgeQuake — 셋 모두 LightRAG 알고리즘에서 출발했지만 그 위에 무엇을 어떻게 쌓았는지가 완전히 다릅니다.


LightRAG가 하는 일

파생 프로젝트들을 비교하기 전에 공통 기반인 LightRAG 알고리즘을 이해해야 합니다.

인덱싱 단계:

문서 입력
  → 청킹 (텍스트 분할)
  → LLM으로 청크별 엔티티/관계 추출
      예) "삼성전자는 2024년 반도체 부문 투자를 확대했다"
          → 엔티티: {삼성전자(ORG), 2024년(DATE), 반도체(TECH)}
          → 관계: (삼성전자) -[투자확대]→ (반도체)
  → 엔티티와 관계를 그래프 DB에 저장
  → 엔티티 설명 텍스트를 벡터 인덱스에 저장

쿼리 단계:

사용자 쿼리
  → 쿼리를 벡터로 변환
  → 벡터 유사도로 진입 엔티티 탐색
  → 진입 엔티티의 1~2 hop 이웃 수집
  → 수집된 엔티티/관계/청크를 컨텍스트로 조립
  → LLM으로 답변 생성

6가지 쿼리 모드(Naive/Local/Global/Hybrid/Mix/Bypass)와 이 기본 알고리즘은 네 프레임워크 모두 동일합니다. 차이는 "그 위에 무엇을 어떻게 쌓았는가"입니다.

LightRAG (원본, Python 라이브러리)
    ├── RAG-Anything  ── LightRAG 코어 변경 없이 멀티모달 레이어만 추가
    ├── ApeRAG        ── LightRAG 깊이 수정 + 프로덕션 플랫폼으로 확장
    └── EdgeQuake     ── 알고리즘을 Rust로 완전 재구현

RAG-Anything: 얹기 전략

RAG-Anything은 LightRAG를 변경하지 않고 그 위에 멀티모달 레이어를 추가합니다. 코어 GraphRAG 알고리즘은 LightRAG를 그대로 import합니다.

추가한 것은 5가지 모달리티 프로세서입니다.

# RAG-Anything 내부 구조
from lightrag import LightRAG  # 변경 없이 그대로 import

class MultiModalRAG:
    def __init__(self):
        self.rag = LightRAG(...)  # LightRAG 코어
        # 5가지 모달리티 프로세서 추가
        self.processors = {
            'image': ImageModalProcessor(),      # Vision LLM으로 이미지 → 텍스트+엔티티
            'table': TableModalProcessor(),      # LLM으로 표 구조 분석
            'equation': EquationModalProcessor(),# 수식 인식
            'office': OfficeModalProcessor(),    # LibreOffice 경유 변환
            'generic': GenericModalProcessor(),  # 폴백
        }

이미지 처리 방식이 특징적입니다. 이미지를 텍스트로 풀어 쓰는 데서 끝나지 않고, 이미지에서 추출한 엔티티가 그래프의 독립 노드로 들어갑니다.

PDF 문서 파싱
  → 텍스트 청크 → 일반 LightRAG 파이프라인
  → 이미지 감지 → Vision LLM → 이미지 설명 + 엔티티 추출
      → 그래프에 "이미지 엔티티 노드" 생성
      → 텍스트 엔티티와 연결
  → 테이블 감지 → LLM 분석 → "테이블 엔티티 노드" 생성

"이미지 안의 차트가 보여주는 트렌드"에 대해 질문하면 그 이미지 노드를 통해 관련 텍스트와 연결되는 방식입니다.

프로덕션 기능: 없음. 인증, 멀티테넌시, 요청 제한, 대화 이력 — 모두 없습니다. pip install 후 Python 코드에 임베드하는 라이브러리입니다.

적합한 사용 사례: 이미지·수식·표를 포함한 문서(학술 논문, 기술 도면, 재무 보고서)를 처리해야 하고, 기존 Python 애플리케이션에 통합하는 경우.


ApeRAG: 깊이 수정 + 플랫폼화

ApeRAG는 LightRAG를 fork해 핵심 알고리즘부터 수정했습니다. 그 위에 Celery 분산 태스크, React WebUI, K8s 배포, RBAC을 더했습니다.

핵심 변경: 엔티티 추출 포맷

LightRAG는 엔티티를 JSON 형태로 추출합니다. ApeRAG는 튜플 형식으로 바꿨습니다.

LightRAG 원본:
{"entity": "Samsung", "type": "ORG", "description": "대한민국 전자 회사"}

ApeRAG 수정:
("Samsung", "ORG", "대한민국 전자 회사")

튜플 파싱이 LLM 출력 파싱 안정성 측면에서 더 견고합니다. 동의어 엔티티 머징(entity merging)도 추가했습니다. "삼성", "삼성전자", "Samsung Electronics"가 같은 엔티티로 통합됩니다.

그래프 스토리지: Apache AGE 없는 순수 관계형

흥미로운 설계 결정이 있습니다. ApeRAG는 Apache AGE를 쓰지 않습니다. 그래프를 순수 PostgreSQL 관계형 테이블로 구현합니다.

-- ApeRAG 그래프 스키마 (추상화)
CREATE TABLE entities (id UUID PRIMARY KEY, name TEXT, type TEXT, ...);
CREATE TABLE relationships (
    source_id UUID REFERENCES entities(id),
    target_id UUID REFERENCES entities(id),
    relation_type TEXT,
    ...
);

-- 1-hop 이웃 탐색
SELECT DISTINCT e.*
FROM entities e
JOIN relationships r ON (r.source_id = e.id OR r.target_id = e.id)
WHERE r.source_id = $entity_id OR r.target_id = $entity_id;

CTE + UNION ALL 방식의 단일 쿼리로 1-hop 탐색을 처리합니다. N+1 문제가 없습니다(batch 버전 기준). AGE와 Cypher 없이 PostgreSQL 표준 SQL만 씁니다.

구조적 한계: multi-hop 미구현

소스코드에 명시돼 있습니다.

# pg_ops_sync_graph_storage.py:289
"""
For now, it only supports getting nodes by label pattern
and their immediate connections.
Full graph traversal with max_depth would require
additional Repository methods.
"""

max_depth 파라미터가 함수 시그니처에 있지만 내부에서 사용되지 않습니다. 항상 1-hop만 처리합니다.

LightRAG 표준 워크로드가 1-hop 지배적이라 실용적으로는 문제없는 경우가 많습니다. 하지만 "2hop 이상 추론이 필요한 지식 그래프 쿼리"는 ApeRAG에서 현재 지원되지 않는다는 점을 인식해야 합니다.

프로덕션 기능: Celery + K8s + RBAC

ApeRAG의 강점은 프로덕션 인프라입니다.

기능 구현
분산 인덱싱 Celery 워커 큐
배포 Docker Compose / K8s Helm
인증 API 키 기반
멀티테넌시 Collection 격리
에이전트 워크플로우 React WebUI 내 flow 편집기
MCP 서버 지원
외부 서비스 PG + Qdrant + ES + Redis (4종)

4종 외부 서비스를 역할별로 분리합니다. PostgreSQL은 그래프와 KV 저장, Qdrant는 청크 벡터 검색, Elasticsearch는 풀텍스트 검색, Redis는 캐시입니다. 기능이 명확히 분리돼 있지만 운영 복잡도가 높습니다.


EdgeQuake: Rust 재구현

EdgeQuake는 LightRAG 알고리즘을 Python에서 Rust로 처음부터 다시 썼습니다. 11개 Rust crate 구조입니다.

왜 Rust로 재작성했는가

Python의 GIL(Global Interpreter Lock)은 한 시점에 하나의 Python 스레드만 실행을 허용합니다. I/O는 병렬로 할 수 있지만 CPU 연산은 직렬화됩니다. 대규모 동시 요청을 처리할 때 Python 서버의 처리량 한계가 됩니다.

Rust는 GIL이 없습니다. tokio 비동기 런타임을 쓰면 수천 개 동시 요청을 처리할 수 있습니다. EdgeQuake는 1,000+ 동시 사용자를 지원합니다.

LightRAG, RAG-Anything, ApeRAG는 모두 Python 기반이라 CPython GIL 제약을 공유합니다. ApeRAG는 Celery로 수평 확장해서 이를 보완하지만, 단일 인스턴스 한계는 여전합니다.

엔티티 추출 품질 개선

EdgeQuake는 엔티티 추출 방식을 세 가지 면에서 변경했습니다.

1. 엔티티 타입 고정

LightRAG는 LLM이 자유롭게 엔티티 타입을 결정합니다. 같은 엔티티가 "company", "corporation", "organization", "기업", "회사"로 다양하게 추출될 수 있습니다. EdgeQuake는 7개로 고정합니다.

PERSON | ORG | LOCATION | CONCEPT | EVENT | TECH | PRODUCT

2. UPPERCASE_UNDERSCORE 정규화

"Samsung" → "SAMSUNG"
"삼성전자" → "SAMSUNG_ELECTRONICS"  (번역 후 정규화)
"Samsung Electronics" → "SAMSUNG_ELECTRONICS"

이 단순한 정규화가 엔티티 중복을 36~40% 감소시킵니다. "samsung", "Samsung", "SAMSUNG", "삼성전자"가 모두 다른 노드로 쌓이는 현상을 막습니다. 그래프가 작아지고 탐색이 빨라집니다.

3. 멀티패스 글리닝(Gleaning)

LLM이 첫 번째 패스에서 모든 엔티티를 추출하지 못하는 경우가 있습니다. 긴 청크나 복잡한 도메인에서는 재현율이 낮아집니다.

글리닝은 추출 후 "이 청크에서 놓친 엔티티가 있는가?"를 LLM에게 다시 묻는 과정입니다. LightRAG는 1회, EdgeQuake는 멀티패스로 반복합니다. 재현율이 15~25% 향상됩니다. 인덱싱 비용이 늘어나지만 그래프 품질이 높아집니다.

커뮤니티 탐지 타이밍

네 프레임워크의 커뮤니티 탐지 타이밍이 다릅니다.

프레임워크 커뮤니티 탐지 시점
LightRAG 쿼리 시 (Global 모드 요청 시)
RAG-Anything LightRAG 위임 (쿼리 시)
ApeRAG LightRAG 위임 (쿼리 시)
EdgeQuake 인제스션 시 (Louvain 사전 계산)

쿼리 시 커뮤니티 탐지는 첫 번째 Global 모드 쿼리가 느리다는 문제가 있습니다. 대규모 그래프에서 Louvain 알고리즘 실행에 수십 초가 걸릴 수 있습니다.

EdgeQuake는 문서 인덱싱 시점에 Louvain 커뮤니티를 사전 계산합니다. 각 노드에 community_id를 부여해두면 쿼리 시에는 커뮤니티 ID를 기준으로 검색하면 됩니다. 쿼리 응답이 일정해집니다. 인덱싱 비용이 올라가지만 프로덕션에서는 이쪽이 더 예측 가능합니다.

그래프 스토리지: PostgreSQL + AGE

EdgeQuake는 그래프를 Apache AGE(PostgreSQL extension)로 저장합니다. Cypher 쿼리를 사용하고, tokio::join!으로 병렬화합니다.

주의할 점이 있습니다. GraphDB 8종 벤치마크에서 AGE는 u=50 동시 사용자 기준 78 RPS를 기록했습니다. LightRAG 스타일의 1-hop 탐색에서는 충분하지만, 20명 이상의 동시 사용자가 예상되는 프로덕션 환경에서는 독립적인 부하 테스트가 필요합니다.

EdgeQuake의 1,000+ 동시 사용자 지원은 Rust tokio 런타임의 비동기 처리가 기반이지만, 실제 그래프 쿼리 처리량은 AGE의 PostgreSQL 레이어에 영향을 받습니다.

프로덕션 기능: PostgreSQL 단일 스택

EdgeQuake는 외부 서비스를 PostgreSQL 하나로 통합합니다.

기능 구현
그래프 PostgreSQL + AGE
벡터 검색 pgvector + HNSW
풀텍스트 PostgreSQL tsvector + GIN
KV / 캐시 PostgreSQL
감사 로그 PostgreSQL
인증 JWT + Argon2
멀티테넌시 워크스페이스 격리, ADMIN/EDITOR/VIEWER
요청 제한 사용자/워크스페이스별
비용 추적 작업별 LLM 토큰 비용
SDK Python, TS, Rust, Java, Go, C#, Ruby, Swift, PHP

ApeRAG가 4종 외부 서비스를 역할별로 분리했다면, EdgeQuake는 PostgreSQL 하나로 통합합니다. 운영이 단순하지만 PostgreSQL 단일 장애점이 됩니다.


핵심 차이 요약

항목 LightRAG RAG-Anything ApeRAG EdgeQuake
언어 Python Python Python + Celery Rust
LightRAG 관계 원본 변경 없이 위에 추가 깊이 수정 재구현
멀티모달 없음 5종 프로세서 5종 인덱스 타입 PDF Vision만
그래프 스토리지 Neo4j / NetworkX (LightRAG 위임) PG 관계형 테이블 PG + AGE
multi-hop 탐색 지원 지원 미구현 지원
엔티티 정규화 없음 없음 동의어 머징 UPPERCASE + 글리닝
커뮤니티 탐지 쿼리 시 쿼리 시 쿼리 시 인제스션 시
동시 사용자 낮음 낮음 Celery 수평 확장 1,000+
외부 서비스 0–1개 0–1개 4개 1개 (PG)
프로덕션 기능 없음 없음 RBAC + K8s JWT + 비용 추적
에이전트 워크플로우 없음 없음 WebUI 편집기 없음
MCP 없음 없음 지원 지원

선택 기준

사용 사례 선택
연구·프로토타입, 최소 의존성 LightRAG
기존 Python 앱에 임베드 LightRAG 또는 RAG-Anything
이미지·표·수식 포함 멀티모달 문서 RAG-Anything
에이전트 워크플로우 + K8s 수평 확장 ApeRAG
단일 PostgreSQL 스택 + 고성능 EdgeQuake
multi-hop 그래프 탐색 EdgeQuake (ApeRAG 미구현)
엔티티 추출 품질 최적화 EdgeQuake (글리닝 + 정규화)
엔터프라이즈 기능 (비용 추적, 요청 제한) EdgeQuake
로컬 모델 다양하게 지원 LightRAG 또는 RAG-Anything