"RAG 핵심 학습 (3/26) — Ingestion 설계: 문서 경계·Model-aware Schema·Filter-first Retrieval"

사용자 노트 §35-9 핵심 한 줄"RAG의 검색 성능은 어떤 문서를 찾느냐보다 먼저 어느 문서 그룹에서 찾을 것인가에서 갈린다."

2편에서 PDF를 마크다운으로 바꿨다. 보통은 그대로 "전부 임베딩 → 한 벡터DB에 적재 → top-K 검색"으로 넘어간다. 그러나 그렇게 했더니 회의록이 정책 답변에 끼어들고, 교육 자료가 보안 정책으로 둔갑하고, 작년 결정문이 오늘의 운영 가이드처럼 검색되는 사고가 운영 단계에서 반복된다. 본 편은 1편·2편과 7편(메타데이터) 사이에 끼어 있는 놓치기 쉬운 단계Ingestion 설계 — 를 한 자리에서 푼다.


0. Prerequisites

  • 1편의 RAG 5요소(특히 Knowledge Base와 Context의 차이).
  • 2편의 마크다운 변환 결과.
  • 벡터 임베딩이라는 단어가 익숙할 것(아직 임베딩 모델 비교는 8편).

본 편은 코드를 거의 쓰지 않는다. 결정의 표가 본문의 대부분이다.


1. 학습 목표

  1. 35장 도입의 Ingestion 6단계를 자신의 말로 설명한다.
  2. Whole-document vs Chunk-level언제 어느 쪽으로 갈지 판단 기준을 안다.
  3. Document Boundary + Filter-first Retrieval가 retrieval 정확도에 왜 더 큰 영향을 주는지 설명한다.

이 결정들이 코퍼스 적재 시점에 일어난다. 한 번 잘못 정하면 청킹·임베딩·인덱스 모두 다시 만들어야 한다.


2. 핵심 요약

RAG의 ingestion은 "텍스트를 적재한다"가 아니다. 여섯 단계의 설계 작업이다 — (1) 문서 구조 이해, (2) 임베딩 모델의 학습 형식 확인, (3) title/body/query 형식 전처리, (4) 문서 목적·경계 설정, (5) 메타데이터 필터링 설계, (6) 검색 공간 축소 후 검색. 이 중 4번 문서 경계가 가장 자주 놓친다. 같은 vector space에 정책·교육·회의록·과거 결정문·외부 자료를 섞으면, 의미 유사도가 목적 차이를 덮어 retrieval이 무너진다. 본 편은 그 위에 Filter-first Retrieval을 얹는다 — "전체 → top-K"가 아니라 "질문 분류 → 필터 → 좁힌 공간 → top-K".


3. 직관 — 도서관의 분류 책장

학교 도서관에 가서 "학사 운영 정책"을 묻는다고 하자. 사서가 좋은 사서라면, 모든 책장을 한꺼번에 뒤지지 않는다. 먼저 어느 구역인지를 좁힌다 — 행정 자료 / 교육 자료 / 학생 게시판 / 학사력 / 회의록 / 학칙. 좁힌 다음에 그 구역 안에서 가장 관련 있는 책을 펼친다. 만약 사서가 모든 책장에서 "운영 정책"이라는 키워드와 가장 가까운 책을 가져온다면, 학생 모임의 회의록이 학칙으로 둔갑할 수 있다. 목적이 다르기 때문이다.

RAG의 retrieval도 같다. 같은 vector space에 목적이 다른 문서를 섞으면, 의미 유사도목적 차이를 가린다. 본 편이 답하는 것: 어떻게 미리 구역을 나눌 것인가, 그리고 검색 시점에 어떻게 구역을 좁힐 것인가.

diagram-1

4. 정의 — 35장의 핵심 6용어

용어 한 줄 정의 35장 참조
Document Boundary 같은 vector space에 섞이면 안 되는 문서군의 경계 §35-4
Document Purpose 정책 / 교육 / 회의록 / 결정문 / 매뉴얼 같은 기능적 분류 §35-4
Multi-collection 한 벡터DB 안의 여러 인덱스를 목적별로 분리 §35-5
Namespace 한 collection 안의 논리 분할(예: 부서별·언어별·시기별) §35-5
Pre-filter / Filtered Vector Search 검색 에 metadata로 후보를 좁히는 방식 §35-6
Filter-first Retrieval "질문 분류 → 필터 선택 → 좁힌 공간 → dense/sparse/hybrid → rerank"의 표준 흐름 §35-6

Document Boundary는 물리적 분리(collection·namespace)와 논리적 분리(metadata field) 모두를 포함한다. 어느 쪽을 택할지는 5장에서 본다.

또한 Model-aware Ingestion(§35-1, §35-2)이라는 별도 축이 있다. 임베딩 모델이 어떤 형식으로 학습되었는지에 맞춰 문서를 그 형식으로 적재한다. 가장 자주 보는 형식:

  • Title / Body 분리(많은 모델이 title을 강하게 본다)
  • Query / Passage 구분(Instruction-tuned embedding은 passage: 접두사를 요구)
  • Document Type / Purpose 필드(custom schema)

5. 35장 도입의 6단계 워크플로

본 편의 중심이다. 사용자 노트 35장 도입 한 문장을 풀면 다음과 같다.

1단계: 문서 구조 이해

각 문서의 섹션 구조를 본다 — 제목 계층, 표·이미지·코드 블록의 분포, 문서가 답하는 단위. "이 문서가 답하는 한 질문이 무엇인가"를 운영자가 정의한다. 단위는 한 페이지일 수도, 한 절일 수도, 문서 전체일 수도 있다.

2단계: 임베딩 모델 학습 형식 확인

임베딩 모델 카드를 본다. - Query prefix가 필요한가(예: passage:, query:)? - Title 필드를 별도로 받을 수 있는가? - Multilingual인가, English-centric인가? - Max sequence length가 얼마인가(이게 청크 상한)?

이 형식에 맞춰 문서를 적재한다. 모델이 학습 시점에 본 형식과 다르게 넣으면 임베딩 품질이 떨어진다.

3단계: title/body/query 형식 전처리

문서를 모델이 받는 형식으로 정규화한다. 보통 다음 schema 중 하나를 고른다.

{
  "document_type": "policy",
  "title": "정보 보안 정책",
  "purpose": "직원 행동 규약",
  "body": "...",
  "section": "5.2 권한",
  "valid_from": "2025-01-01",
}

title은 강한 신호이므로 별도 필드로 둔다. body는 청킹 단위. document_type·purpose필터링에 쓴다.

4단계: 문서 목적·경계 설정 — 핵심

§35-4가 강조한 단계. 같은 vector space에 섞이면 안 되는 문서군의 경계를 명시적으로 정한다.

분리 대상 (§35-5) 이유
정책 vs 교육 자료 의도가 다름. 정책은 규약, 교육은 안내
최신 vs 과거 동일 주제라도 시점이 다르면 답이 다름
내부 vs 외부 출처 권위가 다름
법령 vs 해설 법령은 정확 인용, 해설은 의역
사양 vs 영업 자료 사실 vs 마케팅
회의록 vs 최종 결정 결정 과정 vs 결정 결과
개발자 문서 vs 사용자 매뉴얼 추상 수준이 다름

분리는 (a) collection 분리, (b) namespace 분리, (c) metadata 필드 분리 중 하나로 표현된다.

5단계: 메타데이터 필터링 설계

검색 시점에 어떤 필터를 걸 수 있도록 metadata 필드를 미리 정한다. 자주 쓰이는 필드:

  • document_id, chunk_id, version, page, section
  • document_type(policy / education / minutes / decision)
  • purpose, valid_from, valid_to
  • security_level, language, region
  • source_authority(internal / official / vendor / public)
  • audience(developer / user / executive)

이 필드들이 7편에서 다시 정리된다. 본 편의 역할은 어떤 필드가 필요한지를 4단계의 경계로부터 도출하는 것.

6단계: 검색 공간 축소 후 검색 — Filter-first

검색은 두 단계로 일어난다. 1. 질문 분류 → 필터 선택: 사용자 질문의 유형을 분류해 적용할 필터를 정함. 2. 좁힌 공간 → top-K: 그 필터로 좁힌 공간 안에서 dense / sparse / hybrid 검색.

이 흐름이 Filter-first Retrieval이다. Naive RAG가 "전체 → top-K"라면, Filter-first는 "분류 → 필터 → 좁힌 공간 → top-K → rerank"다.


6. 원리 워크스루 — Filter-first 한 질의

표준 호출은 다음 두 줄로 충분하다.

filter_dict = classify_and_build_filter(query)  # 예: {"document_type": "policy", "valid_from": ">2024-01-01"}

hits = vector_index.search(query_vec, top_k=5, filter=filter_dict)

여섯 단계를 풀면 이렇게 된다.

  1. 질문 텍스트의 키워드·문체에서 유형 추정(정책 vs 교육 vs 회의록).
  2. 유형 → metadata 필터 매핑.
  3. 필터를 벡터DB에 그대로 전달(대부분의 벡터DB가 metadata pre-filter 지원).
  4. 좁힌 공간에서 dense 또는 hybrid 검색.
  5. top-K를 rerank (12편).
  6. 컨텍스트 조립 후 답 생성.

이 흐름의 핵심 효과는 정확도와 비용 둘 다 개선이다.

  • 정확도: 의미 유사도가 목적 차이를 덮을 가능성이 줄어든다(8.5절 1편 참조).
  • 비용: 좁힌 공간 검색이 더 빠르고 더 싸다. top-K도 줄일 수 있다.

trade-off는 질문 분류가 틀릴 때다. 17편(Query Classification)에서 분류 신뢰도와 fallback retriever를 다룬다.


7. 변형과 사례 — 분리 패턴 5블록

7.1 Multi-collection — 컬렉션 단위 분리

  • 무엇이 바뀌나: 한 벡터DB 안에 여러 collection을 둔다. 각 collection은 문서 목적당 하나.
  • 왜 등장했나: 가장 명확한 물리적 분리. 검색 시 collection을 선택하는 것이 곧 필터.
  • 무엇이 가능해졌나: collection 간에 임베딩 모델도 다르게 쓸 수 있다(법령은 정확 일치 강한 모델, 회의록은 multilingual 모델).
  • 어디에 적합한가: 도메인이 명확하게 갈리고 collection 간 재인덱싱이 독립적으로 일어나는 환경.
  • 한계와 다음 단계: collection 수가 많아지면 라우팅 로직이 복잡해진다. → 19편 Query Routing.

7.2 Namespace — 한 collection 내 논리 분할

  • 무엇이 바뀌나: 같은 collection 안에 namespace 키를 둔다. Pinecone, Weaviate가 1급 시민으로 지원.
  • 왜 등장했나: 부서별·언어별·테넌트별 분리가 물리적 collection까지 갈 필요 없을 때.
  • 무엇이 가능해졌나: 같은 임베딩 모델·인덱스를 공유하면서 논리적으로 격리.
  • 어디에 적합한가: 다국적 기업의 언어별 격리, B2B SaaS의 테넌트별 격리.
  • 한계와 다음 단계: 임베딩 모델이 공유된다는 점. 언어가 다른데 영어 중심 모델을 쓰면 한국어 데이터 품질이 떨어진다. → 8편 임베딩.

7.3 Metadata Field — 필드 단위 분리

  • 무엇이 바뀌나: 분리 단위를 물리적 collection이 아니라 metadata 필드로 표현. 검색 시 where document_type = 'policy' 같은 조건.
  • 왜 등장했나: 분리 축이 동적이거나 교차하는 경우. 정책 × 부서 × 언어처럼 축이 여러 개.
  • 무엇이 가능해졌나: 한 collection 안에서 축의 조합을 자유롭게 필터링.
  • 어디에 적합한가: 분리 축이 자주 변경되거나 시간에 따라 늘어나는 코퍼스.
  • 한계와 다음 단계: 필터 키 수가 많아지면 벡터DB가 인덱싱하지 않은 필드에서 느려진다. 필드 인덱스 사전 설정 필요.

7.4 Versioning — 시기별 분리

  • 무엇이 바뀌나: version, valid_from, valid_to 필드로 시간 축 분리.
  • 왜 등장했나: 정책은 시점에 따라 답이 다르다. "현재 정책"과 "작년 정책"이 동일 vector space에 섞이면, 사용자가 묻는 시점이 모호해진다.
  • 무엇이 가능해졌나: "현재 유효한 정책"만 검색, 과거 비교 시 동일 주제의 시점별 결과를 따로 조회.
  • 어디에 적합한가: 정책·법령·계약처럼 유효성이 중요한 영역.
  • 한계와 다음 단계: 청킹 단위가 문서 전체가 아니면 version 필드가 각 청크에 복제되어야 함. → 7편 메타데이터, 25편 재색인 운영.

7.5 Source Authority — 출처 권위 분리

  • 무엇이 바뀌나: source_authority 필드로 내부 공식 / 외부 표준 / 벤더 자료 / 공개 자료를 구분. 검색 시 권위 순위로 가중치를 다르게 줌.
  • 왜 등장했나: 같은 주제라도 공식 문서벤더 마케팅 자료의 신뢰도가 다르다.
  • 무엇이 가능해졌나: "공식 답변이 가능하면 공식 출처, 아니면 보조"의 fallback 전략.
  • 어디에 적합한가: 컴플라이언스가 중요한 영역. 의료·법령·금융.
  • 한계와 다음 단계: 권위 점수의 유지보수가 사람의 일. 신뢰도가 시간에 따라 변할 수 있음.

8. 한계와 실패 양상

8.1 분리 누락 — "어쩌다 같은 collection에 넣었더니…"

  • 왜 본질적인가: 운영 초기에는 작은 코퍼스라 분리를 미룬다. 코퍼스가 자라면서 목적이 다른 문서가 쌓이지만, 분리는 retrofit이 비싸다. 재인덱싱·임베딩 재호출·필터 룰 작성이 한꺼번에 일어난다.
  • 진단: 운영 1~3개월 후 retrieval 정확도가 느리게 떨어지는 패턴. 새 문서가 들어올 때마다 약간씩.
  • 완화: 처음부터 4단계의 분리 표를 만든다. 모든 새 문서는 분리 표의 한 칸에 들어가야 적재 가능.
  • 다음 편으로 연결: 7편 메타데이터 설계.

8.2 임베딩 모델 형식 미스매치

  • 왜 본질적인가: 모델은 학습 시점에 본 형식에 강하다. query: ... 접두사 없이 query를 임베딩하면 passage embedding과 거리 측정이 어긋난다. BGE-M3·E5-Mistral은 명시적 접두사를 요구.
  • 진단: 같은 코퍼스를 다른 형식으로 임베딩해 top-K 정답률을 비교.
  • 완화: 모델 카드의 권장 형식을 그대로. Title/Body 분리를 지원하는 모델이면 둘 다 받는다.
  • 다음 편으로 연결: 8편 임베딩 모델 비교, 18편 Query Rewrite.

8.3 필터 키 인덱싱 누락

  • 왜 본질적인가: 벡터DB는 벡터에만 인덱스를 만들고, metadata 필드는 선택적. 자주 쓰는 필드를 인덱스 설정 안 함으로 두면 검색이 전체 스캔이 된다.
  • 진단: 같은 query를 필터 적용 / 미적용으로 비교했을 때 지연이 비슷하면 필드 인덱스 누락.
  • 완화: 4단계에서 정한 필드를 모두 인덱스 설정. Pinecone metadata index, Qdrant payload index, Weaviate property index 등.
  • 다음 편으로 연결: 9편 벡터DB 비교.

8.4 Query Classification 오분류

  • 왜 본질적인가: 분류기가 틀리면 잘못된 필터가 걸려 정답 문서가 좁힌 공간 밖에 있게 된다. 답이 나올 수가 없는 상태.
  • 진단: 답이 빈 경우와 답이 틀린 경우를 구분. 빈 경우가 많으면 분류기 의심.
  • 완화: 분류기 신뢰도가 낮으면 fallback retriever(필터 미적용 검색) 추가. 또는 분류 결과를 다중 collection 동시 검색으로 확장.
  • 다음 편으로 연결: 17편 Query Classification, 19편 Query Routing.

8.5 Whole-document vs Chunk 결정 누락

  • 왜 본질적인가: 작은 문서·FAQ·정책 한 페이지·README 같은 짧은 단위문서 전체를 한 임베딩으로 두는 게 의미 보존에 유리한 경우가 많다. 무조건 청킹하면 의미가 조각난다.
  • 진단: 짧은 문서를 문서 단위chunk 단위로 각각 임베딩해 top-K 정답률 비교.
  • 완화: 문서 단위 retrieval과 chunk 단위 retrieval을 공존시킴. 5편 청킹에서 결정 표를 다시 본다.
  • 다음 편으로 연결: 5편 청킹 전략, 6편 Contextual Chunking.

8.5 Common Pitfalls

  • "모든 문서를 한 collection에" — 8.1절.
  • "임베딩 모델의 권장 형식 무시" — 8.2절.
  • "metadata는 청크에 따라가도록만" — 인덱스 설정 없이는 필터링이 느림. 8.3절.
  • "분류기가 다 분류해 줄 거다" — 분류 신뢰도 모니터링 없이는 답 빈 케이스가 늘어난다. 8.4절.
  • "청크 사이즈는 512가 표준" — 짧은 문서는 문서 단위가 나을 수 있다. 8.5절, 5편.

9. 정리된 결론

Q1. 35장 도입의 6단계는 무엇인가.

정답: 문서 구조 이해 → 임베딩 모델 학습 형식 확인 → title/body/query 형식 전처리 → 문서 목적·경계 설정 → 메타데이터 필터링 설계 → 검색 공간 축소 후 검색. 근거: §5. 본문 챕터: §5.

Q2. Filter-first Retrieval과 Naive RAG의 차이는?

정답: Naive는 "전체 → top-K". Filter-first는 "질문 분류 → 필터 → 좁힌 공간 → top-K → rerank". 근거: 좁힌 공간 검색이 정확도·비용 둘 다 개선. trade-off는 분류 오류. 본문 챕터: 5장 6단계, §6.

Q3. 같은 vector space에 섞이면 안 되는 문서군의 7가지 분리 대상은?

정답: 정책 vs 교육 / 최신 vs 과거 / 내부 vs 외부 / 법령 vs 해설 / 사양 vs 영업 / 회의록 vs 결정 / 개발자 vs 사용자 매뉴얼. 근거: 5장 4단계 표(§35-5). 본문 챕터: §5.

Q4. Multi-collection / Namespace / Metadata Field 분리의 차이는?

정답: Multi-collection은 물리적 분리(임베딩 모델까지 다를 수 있음). Namespace는 논리적 분할(임베딩 모델 공유). Metadata Field는 축의 조합을 동적으로 표현. 근거: 7.1절·7.2·7.3. 본문 챕터: §7.

Q5. Whole-document Retrieval을 언제 쓰는 게 맞나?

정답: 짧고 의미 단위가 분명한 문서 — FAQ, 정책 한 페이지, README, 회의록 한 건. 청킹이 의미를 조각내는 경우. 근거: §35-1, 8.5절. 본문 챕터: 8.5절.


10. 추가 학습

1차 자료

  • 사용자 노트 35장 전체 — Embedding Model-Aware Ingestion의 9개 하위 섹션.
  • Pinecone Blog — Multi-namespace Architecture for Multi-tenant Apps (2024).
  • Weaviate Docs — Multi-tenancy (2024).
  • Qdrant Docs — Payload index and filtering (2024).
  • Sarthi, P. et al. RAPTOR: Recursive Abstractive Processing for Tree-Organized Retrieval. ICLR 2024. arXiv:2401.18059 (Whole-document·계층적 retrieval 연구의 한 갈래).

공식 docs

  • Pinecone Namespaces: https://docs.pinecone.io/guides/indexes/use-namespaces
  • Weaviate Multi-tenancy: https://weaviate.io/developers/weaviate/concepts/data#multi-tenancy
  • Qdrant Payload: https://qdrant.tech/documentation/concepts/payload/

보조 자료

  • 사용자 노트 §35-9 — 핵심 한 줄 ("어느 문서 그룹에서 찾을 것인가").
  • 사용자 노트 §35-7 — 학습 순서 매핑(본 편 5장에 반영).

Cheat Sheet

결정 핵심 질문
분리 단위 같은 vector space에 들어가도 되는가? 안 된다면 collection / namespace / metadata field 중 어느 방식?
임베딩 형식 모델 카드가 권장하는 prefix·title/body 분리·max length를 따랐는가?
Schema document_type, purpose, valid_from, security_level, source_authority가 필요한가?
Filter 인덱스 자주 쓰는 metadata 필드가 벡터DB의 인덱스에 포함되어 있는가?
Whole-doc vs Chunk 문서가 짧고 의미 단위가 분명하면 문서 단위 retrieval도 검토
Filter-first 흐름 질문 분류 → 필터 → 좁힌 공간 → top-K → rerank

Bridge — 다음 편

다음 — RAG 핵심 학습 (4/26) OCR과 레이아웃 분석.

3편에서 어디서 찾을 것인가를 정했다. 다시 무엇을 적재할 것인가로 돌아간다 — 2편의 마크다운 변환이 못 잡은 부분, 즉 스캔 PDF·이미지 안의 텍스트·표·다단 레이아웃. PaddleOCR / Tesseract / AWS Textract / Azure DI / LayoutLMv3를 다섯 축으로 비교한다.

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"