블로그로 돌아가기

걸어 다닐 수 있는 인덱스를 만들자

MECE 벽 너머로 가는 두 갈래 길 — 문서 단위(PageIndex)와 엔티티 단위(Graph RAG) — 가 결국 같은 일을 하는 이유는, 둘 다 평면적인 유사도 대신 따라갈 수 있는 구조를 만들기 때문이에요.

8 min2026년 5월 4일

RAG 얘기는 보통 retrieval 품질에서 시작해서 같은 자리로 돌아와요. 잘 다듬은 질문을 잘 임베딩한 코퍼스에 던져도 결과는 어딘가 부족하다는 것. 그래서 더 좋은 임베딩, 더 좋은 청커, 더 좋은 reranker를 찾아 다닙니다. 다 조금씩은 도움이 돼요. 그런데 진짜 문제는 건드리지 못합니다.

진짜 문제는 이거예요. 임베딩 벡터는 표면적인 유사성만 잡아내는데, 실제 문서에서 정말 의미 있는 관계는 구조적인 관계입니다.

문서를 임베딩하면 무엇이 사라지나

문서를 청크로 자르고 각 청크를 임베딩하면, 보존되는 신호는 단 하나입니다 — "두 청크가 학습된 의미 공간에서 얼마나 가까운가." 나머지는 다 버려져요. 저자가 글에 새겨둔 위계 — 제목 → 섹션 → 서브섹션 → 문단 — 가 평평해집니다. 3장이 2장의 결과라는 사실이 지워져요. 4.2절이 1.3절과 모순된다는 사실은 보이지도 않아요. 남는 건 "이 두 구절은 비슷한 단어를 쓴다"뿐입니다.

가벼운 질문이면 일반적인 RAG로 충분해요. 그런데 정확도가 중요한 문서 — 규제 신고서, 계약서, 기술 매뉴얼, 연구 논문 — 에서는 다른 방법이 필요합니다.

MECE 벽

잘 쓴 글은 어떤 논리적 프레임워크 위에 서 있고, 가장 흔한 프레임워크는 MECE — Mutually Exclusive, Collectively Exhaustive예요. 한 상위 주제 아래의 하위 주제들은 의도적으로 겹치지 않게 설계됩니다. 겹친다는 건 사고가 정리되지 않았다는 신호니까요. 문제를 분해하는 이유 자체가 각 가지가 서로 다른 영역을 다루게 하는 데 있어요.

이게 벡터 유사도에 어떤 일을 할까요?

하위 카테고리들이 설계상 상호배타적이라면, 임베딩 유사도는 자연스럽게 낮습니다. 같은 부모를 공유하긴 해도 어휘나 내용이 겹쳐선 안 돼요. 저자가 굳이 분리해놓은 거니까요. 형제 사이를 잇는 유일한 길은 로 — 부모 주제로 — 올라가는 길입니다. 그런데 cosine similarity는 그 길을 볼 방법이 없어요. 두 형제를 그저 무관한 청크로 처리합니다. 한쪽을 이해하려면 다른 쪽도 알아야 하는데도요.

Cosine similarity는 형제를 남으로 봐요. 문서의 구조는 가족이라고 말하는데도.

벡터는 관계를 잇지 못한다

MECE 벽을 진지하게 넘으려는 시도가 공통적으로 보여주는 게 이거예요. 그리고 두 갈래 해법을 묶어주는 단 한 줄 관찰이기도 합니다. 임베딩은 평면적인 유사도 공간을 줄 뿐이고, 정작 필요한 건 걸어 다닐 수 있는 무언가다.

벡터 스토어에서는 "이 점 근처에 뭐가 있어?"만 물을 수 있어요. 그게 끝입니다. 두 위치를 비교할 수는 있지만 어디로 걸어갈 수는 없어요. 부모 / 자식 / 형제 / 인용으로 이어진 이웃 / 같은 클러스터의 멤버 같은 개념이 아예 없어요. 거리뿐입니다.

문서와 코퍼스에는 벡터 공간이 가지지 못한 게 있어요. 걸어갈 수 있는 구조 말이에요. 목차는 장에서 절로, 절에서 항으로 내려갈 수 있게 해주고, 엔티티 그래프는 한 개념에서 라벨이 붙은 엣지를 따라 다른 개념으로 점프하게 해줍니다. 인용 네트워크는 참고문헌을 따라가게 해줘요. 이 중 어느 것도 유사도 측정이 아닙니다. 탐색 가능한 인덱스예요.

그래서 RAG의 구조적 한계에 진지하게 응답하는 두 진영의 동작은 결국 같습니다. 임베딩이 평평하게 만들어버린 관계를 복원할 수 있는, 따라갈 수 있는 인덱스 — 또는 맵 — 을 만든다. 두 길이 갈리는 지점은 그 인덱스를 무엇 위에 만드느냐 하나뿐이에요.

걸어 다닐 수 있는 두 가지 인덱스

문서 단위 인덱스 — PageIndex

[[pageindex-vectorless-rag|PageIndex]]는 문서가 이미 가지고 있는 인덱스를 보존해요. 저자가 써놓은 목차요. 문서에서 위계적인 "table of contents" 트리를 만들고 각 노드에 요약을 붙입니다. 그리고 LLM이 트리를 따라 내려가며 관련 섹션을 찾게 해요. 청킹 없음, 임베딩 없음, 벡터 DB 없음. retrieval 엔진은 이미 문서 안에 있던 구조 위에서 LLM이 논리적으로 추론하는 행위 그 자체입니다.

이 방법이 거는 베팅은 명확해요. 진지한 문서는 자기 MECE 구조를 이미 목차에 새겨놨다. 우리가 그걸 그동안 그냥 버렸을 뿐이고요. LLM이 "1장: 매출, 2장: 비용, 3장: 재무상태표"를 읽으면 — "매출"이라는 단어가 어딘가에 패턴 매칭되지 않아도 — 매출 질문에 1장으로 내려가야 한다는 걸 알아요. 목차가 곧 인덱스입니다. 탐색은 LLM이 트리를 따라가는 행위고요.

PageIndex의 한 발 더 나간 주장은 이거예요. OCR 자체도 정보 손실이 있다 — 2D 시각 문서를 1D 텍스트 시퀀스로 바꾸는 순간 공간 구조가 버려진다. 그래서 vision 모드 변형은 OCR을 아예 건너뜁니다. LLM이 트리를 걷고, 페이지를 고르고, VLM이 그 페이지를 이미지로 읽어요.

만들어지는 것: 트리. 그걸 걷는 것: LLM의 추론.

엔티티 단위 맵 — Graph RAG

[[graph-rag|Graph RAG]]는 문서의 목차를 신뢰하지 않습니다. 목차가 약하거나, 아예 한 문서에 없고 여러 문서에 흩어져 있을 때를 위한 길이에요. 그래서 구조를 보존하는 대신 직접 만들어요. 엔티티와 그 관계로 이루어진 명시적인 그래프요.

[[lightrag-algorithm|LightRAG]]가 이 레시피의 정석입니다. 인덱싱 단계에서 LLM이 각 청크를 읽고 (엔티티, 타입, 설명) 튜플과 (출발, 도착, 키워드, 설명) 관계 튜플을 추출해요. 결과물은 벡터와 함께 저장되는 진짜 지식 그래프입니다. 쿼리 시점에는 모드를 섞어요. 벡터 검색으로 관련 엔티티를 먼저 찾고, 그 엔티티에서 그래프를 따라 연결된 엔티티들로 — 임베딩만으로는 절대 떠오르지 않을 것들로 — 확장합니다. "X가 Z를 거쳐서 Y와 어떻게 연결되지?" 같은 멀티홉 쿼리는 그래프에 실제 경로가 있어서 작동해요. "주요 테마가 뭐지?" 같은 주제형 쿼리는 community detection이 단어가 아니라 관계를 공유하는 엔티티들을 묶어줘서 작동하고요.

만들어지는 것: 그래프. 그걸 걷는 것: 그래프 탐색 (벡터를 거친 첫 조회로 두기도 함).

같은 동작, 다른 인덱스

두 길은 정반대로 보이지만, 사실 같은 동작 — 걸어 다닐 수 있는 무언가를 만든다 — 을 다른 스케일에 적용한 결과예요.

문서 단위 (PageIndex)엔티티 단위 (Graph RAG / LightRAG)
무엇이 만들어지나트리 (문서의 목차)그래프 (추출한 엔티티 + 관계)
인덱스의 출처저자가 직접 써놓은 것LLM이 인덱싱 시점에 추출한 것
무엇이 그것을 걷나LLM의 논리적 추론, 위에서 아래로그래프 탐색 (보통 벡터로 시드)
최소 retrieval 단위섹션 / 페이지엔티티 / 관계
잘 맞는 곳길고 잘 구조화된 단일 문서여러 문서에 흩어진 코퍼스, 희소한 사실들
안 맞는 곳위계가 사실상 없는 문서위계가 강한데도 그걸 버리는 코퍼스
벡터 필요?없음있음 (엔티티 disambiguation + 시드용)

PageIndex는 저자의 인덱스를 믿어요. Graph RAG는 못 믿어서 자기 맵을 새로 그립니다. 둘 다 평면 임베딩을 평면 청크에 던져서 문서가 원래 새겨두었던 걸 복원할 수 있다는 전제 자체를 거부해요.

그래서 어떤 스택을 골라야 하나

코퍼스가 구조가 살아 있는 긴 단일 문서 — 10-K 신고서, 교과서, 규제 매뉴얼 — 라면 PageIndex가 정답이에요. 목차 트리가 이미 있으니까 그걸 보존만 하면 됩니다. Mafin 2.5가 FinanceBench에서 98.7%를 찍은 게 정확히 이 패턴이고요.

코퍼스가 암묵적인 상호 참조로 묶인 짧은 문서들의 모음 — 연구 문헌, 위키, 지식 베이스 — 이라면 Graph RAG / LightRAG입니다. 의지할 단일 목차가 없는 대신, 문서들 사이에 흩어진 엔티티와 관계가 있어요. LLM이 한 번 추출해두면 그 다음부터는 영원히 탐색만 하면 됩니다.

코퍼스가 계속 쌓아가는 모든 자료 — Karpathy의 "LLM Knowledge Bases" 패턴 — 이라면 둘 다 적용됩니다. [[openkb-knowledge-base|OpenKB]]는 긴 PDF에는 PageIndex를, 코퍼스 단위로는 LLM이 컴파일한 cross-document concept 페이지를 써요. 문서 구조가 있으면 그걸 쓰고, 없으면 엔티티 구조를 새로 만들고요.

코퍼스가 코드베이스여도 같은 논리예요. [[code-to-knowledge-graph|Graphify]]가 코드용 Graph RAG입니다 — tree-sitter로 AST를 뽑고, Leiden community detection으로 모듈 구조를 찾고, 에이전트가 파일을 grep하는 대신 그래프를 읽어요.

그렇다고 임베딩이 죽은 건 아니에요

이 글이 임베딩이 끝났다는 얘기는 아니에요. 임베딩은 원래 설계된 표면 유사도 작업에는 여전히 정답입니다. 의미적으로 가까운 구절 찾기, 청크 단위 관련도 계산, 구조 레이어가 다듬기 전에 빠른 1차 retrieval을 제공하는 일들이요. 잘못된 건 임베딩을 파이프라인 전체로 취급한 거예요. 임베딩은 구조 레이어 아래에 깔리는 거친 층이지, 구조의 대체물이 아닙니다.

2026년 RAG의 아키텍처 전환은 "더 좋은 임베딩 모델을 찾자"가 아니에요. 걸어 다닐 수 있는 인덱스를 만들자입니다. 그 인덱스가 저자가 이미 써놓은 트리(PageIndex)든, LLM이 추출하는 그래프(Graph RAG / LightRAG)든. 그리고 탐색이 원래 해야 했던 일을 cosine similarity에 떠넘기는 걸 그만두는 일이고요.

관련 자료

  • [[pageindex-vectorless-rag]] — 문서 단위 경로. OCR 자체가 정보 손실이라는 정보이론 논변까지 포함
  • [[graph-rag]] — 엔티티 단위 경로의 큰 그림
  • [[lightrag-algorithm]] — 엔티티 + 관계 그래프 RAG의 정석 레시피
  • [[rag-techniques]] — 30여 개 retrieval 기법을 목적별로 정리한 카탈로그
  • [[multimodal-rag]] — 그림 / 표가 섞인 문서에 그래프 + 멀티모달을 적용한 RAG-Anything
  • [[openkb-knowledge-base]] — 긴 문서엔 PageIndex를 쓰는 코퍼스 단위 위키 컴파일러
  • [[code-to-knowledge-graph]] — 같은 패턴을 코드에 적용한 사례
  • [[document-intelligence-archive|Document Intelligence Archive]] — 이 글의 논변이 통과하는 도구 목록 전체