"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. 학습 목표
- 35장 도입의 Ingestion 6단계를 자신의 말로 설명한다.
- Whole-document vs Chunk-level을 언제 어느 쪽으로 갈지 판단 기준을 안다.
- 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에 목적이 다른 문서를 섞으면, 의미 유사도가 목적 차이를 가린다. 본 편이 답하는 것: 어떻게 미리 구역을 나눌 것인가, 그리고 검색 시점에 어떻게 구역을 좁힐 것인가.
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,sectiondocument_type(policy / education / minutes / decision)purpose,valid_from,valid_tosecurity_level,language,regionsource_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)
여섯 단계를 풀면 이렇게 된다.
- 질문 텍스트의 키워드·문체에서 유형 추정(정책 vs 교육 vs 회의록).
- 유형 → metadata 필터 매핑.
- 필터를 벡터DB에 그대로 전달(대부분의 벡터DB가 metadata pre-filter 지원).
- 좁힌 공간에서 dense 또는 hybrid 검색.
- top-K를 rerank (12편).
- 컨텍스트 조립 후 답 생성.
이 흐름의 핵심 효과는 정확도와 비용 둘 다 개선이다.
- 정확도: 의미 유사도가 목적 차이를 덮을 가능성이 줄어든다(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를 다섯 축으로 비교한다.
댓글
댓글 쓰기