RAG에서 청킹(Chunking): 조건을 잃지 않고 문서를 분할하는 방법
요약
RAG 시스템에서 청킹(Chunking)은 단순히 텍스트를 작게 나누는 것이 아니라, 사실과 그 조건을 분리하지 않고 검색 가능한 조각을 만드는 과정입니다. 큰 청크는 주제가 혼합되거나 중요한 조건이 누락될 위험이 있습니다. 따라서 문서 구조 기반의 청킹 전략이 중요하며, 오버랩이나 부모-자식 검색만으로는 근본적인 컨텍스트 문제를 해결할 수 없습니다.
핵심 포인트
- 청킹은 텍스트를 작게 나누는 것이 아니라, 사실과 조건을 분리하지 않는 조각화 과정이다.
- 큰 청크는 주제 혼합 및 조건 누락을 유발하여 답변의 정확성을 떨어뜨린다.
- 문서 구조 기반으로 청크를 생성하고, 실제 질문으로 테스트하는 것이 중요하다.
- 검색된 증거(evidence), 컨텍스트 완전성, 답변 정확성은 각각 분리하여 검증해야 한다.
당신의 AI 비서가 직원 복리후생 핸드북을 가지고 있습니다. 당신이 “수습 기간 중인 사람이 안경 착용 혜택을 청구할 수 있나요?”라고 질문합니다.
AI는 자신 있게 “네, 연간 최대 3,000 바트까지 가능합니다.”라고 답변합니다. 하지만 핸드북에는 이 혜택이 오직 수습 기간을 마친 정규직 직원에게만 해당된다고 명시되어 있습니다. 모델은 한계에 도달했지만, 자격 조건은 놓쳤습니다.
이러한 실패는 생성(generation) 전에, 문서 경계에서 시작될 수 있습니다. RAG에서 청킹(Chunking)은 텍스트를 가능한 한 작게 만드는 것이 아닙니다. 이는 사실과 그 사실을 참으로 만드는 조건을 분리하지 않고 검색 가능한 조각들을 만드는 것입니다.
여기서 제시된 정책과 금액은 NEXT4I나 고객의 실제 정책이 아닌 가상의 예시입니다.
TL;DR
- 청크(chunk)는 검색에 사용되는 원본 콘텐츠의 한 조각입니다. 그 자체가 본질적으로 벡터인 것은 아닙니다.
- 큰 청크는 관련 없는 주제들을 혼합할 수 있습니다. 작은 청크는 주제, 조건, 예외 사항을 잃어버릴 수 있습니다.
- 문서 구조부터 시작하고, 너무 큰 섹션은 제한하며, 실제 질문으로 테스트해야 합니다.
- 오버랩(Overlap)과 부모-자식 검색(parent-child retrieval)은 누락된 컨텍스트에 도움을 줄 수 있지만, 잘못 추출된 텍스트를 복구할 수는 없습니다.
- 검색된 증거(evidence), 컨텍스트의 완전성, 답변의 정확성을 각각 분리하여 확인해야 합니다.
청킹이란 무엇이며, 왜 전체 파일을 사용하지 않아야 하는가?
청킹은 문서를 인덱싱하고 검색할 수 있는 조각들로 나누는 과정입니다. 단순화된 파이프라인은 다음과 같습니다:
Document -> 텍스트 추출 및 정리 -> 청크 생성
-> 텍스트와 원본 참조 저장 -> 인덱스 구축
...
검색(Retrieval)은 키워드 검색, 벡터 검색 또는 둘 다를 사용할 수 있습니다. 모든 청크가 임베딩(embedding)을 필요로 하는 것은 아닙니다. 벡터 검색이 사용될 때, 임베딩 모델은 콘텐츠의 수치적 표현을 만듭니다.
검색 가능한 단위가 반드시 최종적인 읽기 단위일 필요는 없습니다. 시스템은 짧은 구절을 검색한 다음, 그 주변 섹션을 모델에 제공할 수 있습니다.
100페이지짜리 핸드북 하나를 담고 있는 단일 청크는 여러 주제를 혼합합니다. 이는 특정 구절의 검색을 어렵게 만들거나 모델 입력 제한을 초과할 수 있습니다. 관련 없는 자료를 전송하는 것 또한 토큰 비용이 들고 중요한 증거에서 주의를 산만하게 할 수 있습니다.
짧은 문서의 경우 전체 문서 컨텍스트가 작동할 수 있습니다. 작은 청크가 무조건 더 좋은 것은 아닙니다. 적절한 규칙 없이 양만으로는 불완전한 증거입니다.
하나의 경계가 답변을 바꿀 수 있다
다음 가상의 구절을 고려해 봅시다:
Section 8.1: Prescription eyewear benefit
The company reimburses up to 3,000 baht per year.
Only permanent employees who have completed probation are eligible.
길이 기반 분할은 다음과 같은 결과를 낼 수 있습니다:
Chunk A: The company reimburses up to 3,000 baht per year.
Chunk B: Only permanent employees who have completed probation are eligible.
제목 없이 두 조각 모두 주제를 잃습니다. B는 혜택을 언급하지 않으며, 벡터 검색이 그 누락된 관계의 복구를 보장하지 않습니다.
만약 A만 LLM에 도달한다면, 이는 자격 요건에 대한 충분한 증거가 아니라 금액에 대한 증거를 가지고 있습니다. 정보 조작 금지 프롬프트는 불확실성을 인정하도록 도울 수 있습니다. 공급되지 않은 문장을 복원할 수는 없습니다.
제목, 금액, 조건을 함께 유지하는 것이 증거를 사용 가능하게 만드는 데 도움이 됩니다. 이것이 정확한 답변을 보장하지는 않습니다.
주요 접근 방식과 그 트레이드오프
이러한 접근 방식들은 결합될 수 있습니다. 제목별로 분할한 다음, 너무 큰 섹션을 나누는 것이 모든 곳에 하나의 방법을 고수하는 것보다 더 유용할 때가 많습니다.
1. 고정 크기 분할 (Fixed-size splitting)
500 토큰과 같은 길이를 선택하고 텍스트를 연속적인 조각으로 나눕니다. 간단하지만, 경계가 문장, 표 또는 예외 사항을 자를 수 있습니다.
토큰 제한이 중요할 때는 실제 모델 토크나이저를 사용하세요. 문자 수는 토큰 수와 상호 교환되지 않으며, 태국어 단어가 반드시 하나의 토큰을 의미하는 것은 아닙니다.
2. 중첩(Overlap)을 이용한 고정 크기 분할
중첩은 한 청크의 일부 텍스트를 다음 청크에서 반복하여, 경계 근처의 자료가 함께 유지될 기회를 제공합니다.
하지만 이는 멀리 떨어진 조건이나 뒤섞인 읽기 순서를 수정할 수는 없습니다. 신뢰도가 낮은 간격 처리 과정을 거친 태국어 OCR 역시 경계 확인이 필요합니다.
중첩을 많이 할수록 색인되는 콘텐츠와 중복이 많아집니다. 거의 동일한 결과가 다른 증거를 담아야 할 검색 슬롯을 차지할 수 있습니다. 적절한 경우 LLM에 보내기 전에 중복된 내용이나 겹치는 컨텍스트를 제거하거나 병합하세요.
3. 재귀적 분할(Recursive splitting)
재귀적 스플리터는 단락, 문장 등 선택된 순서의 구분자들을 시도하며, 조각들이 크기 제한에 맞을 때까지 더 세밀한 경계를 사용합니다.
이는 문장을 가로지르는 불필요한 절단을 피하지만, 의미를 이해하지는 못합니다. 하나의 단락이 여러 주제를 다룰 수 있으며, 손상된 OCR은 경계를 제거할 수 있습니다.
4. 구조 인식 분할(Structure-aware splitting)
제목, 목록, 표, 코드 블록을 사용하여 경계를 안내하세요. 하위 섹션은 상위 제목을 포함하여 짧은 구절이라도 명확한 주제를 갖도록 할 수 있습니다.
표는 특별한 주의가 필요합니다. 단순히 '3,000'이라는 숫자가 있는 것만으로는 충분하지 않습니다. 행 이름, 열 이름, 단위를 보존해야 합니다. 가상의 예시에서
6. 부모-자식 검색 및 문맥적 청킹
이 방법들은 위에서 설명한 분할(splitting) 방식들과는 다른 문제들을 해결합니다.
**부모-자식 검색 (Parent-child retrieval)**은 작은 자식 구절(child passages)을 인덱싱하여 검색하고, 매칭된 결과를 더 큰 부모 섹션(parent section)으로 확장하여 읽게 합니다. 링크를 유지하고, 문맥 크기를 제어하며, 확장된 부모에 대한 접근 권한도 확인해야 합니다.
**문맥적 청킹 (Contextual chunking)**은 문서 제목, 섹션 이름 또는 짧고 출처 기반의 설명(source-grounded explanation)과 같은 유용한 문맥을 인덱싱하기 전에 추가합니다. 만약 LLM이 이 설명을 생성했다면, 그 설명이 조건을 지어내지 않았는지 확인해야 합니다. 생성된 문맥을 출처 증거로 취급하는 대신, 인용을 위해 원본 텍스트를 유지할 수 있도록 해야 합니다.
명제적(Propositional) 또는 에이전트 기반 접근 방식은 LLM을 사용하여 독립적인 진술(standalone statements)을 추출하거나 콘텐츠 그룹화를 선택할 수 있습니다. 구현 방법은 다양합니다. 공통적으로 고려해야 할 트레이드오프는 추가 비용과 재작성 과정에서 자격 요건(qualification)이 누락될 위험입니다. 비-LLM 기준선(baseline)과 비교하고 원본 출처를 유지하는 것이 중요합니다.
문서에 맞는 접근 방식 선택
| 문서 | 합리적인 첫 번째 접근 방식 | 주의 깊게 확인할 사항 |
|---|---|---|
| 마크다운 또는 구조화된 매뉴얼 | 제목별 분할, 너무 큰 섹션은 세분화 | 부모 제목, 표(tables), 각주(footnotes) |
| ... | ||
| 이것들은 시작점일 뿐이며, 실제 문서를 검토하는 것의 대체재가 아닙니다. |
우선순위를 바꾼 태국 관광 PDF
RAG 파이프라인을 실험하던 중, 저는 태국에 관한 아름답게 디자인된 관광 PDF를 사용했습니다. 추출된 텍스트는 훨씬 매력적이지 않았습니다. 태국 모음과 성조 부호가 잘못 배치되어 있었고, 색상 배경, 워터마크, 삽화 등이 읽기를 방해했기 때문입니다.
일부 페이지에 대해서는 글자를 더 명확하게 하기 위해 흑백 변환을 시도했습니다. 이 역시 시각적 문맥을 잃을 수 있습니다. 여러 모델의 도움을 받아 결과물을 비교했고, 사람이 맞춤법을 다시 검토하도록 했습니다.
이 내용은 제가 이전 PDF 및 Markdown 문서 작성물(태국어)에서 설명했습니다. 모든 PDF가 동일한 워크플로우를 필요로 한다는 증거라기보다는 하나의 경험일 뿐입니다.
교훈은 간단했습니다. 청크 크기를 변경한다고 해서 추출 과정에서 이미 손실된 단어들을 되돌릴 수는 없습니다.
Markdown은 구조를 식별하기 쉽게 만들 뿐, 평가가 불필요하다는 것을 의미하지 않습니다. 섹션은 여전히 너무 크게 될 수 있고, 표의 행들은 헤더가 필요합니다.
청크 크기와 오버랩(overlap)은 얼마나 커야 할까요?
만능 설정은 없습니다. 단락 기반 텍스트의 경우 300500 토큰에 1020%의 오버랩이 초기 실험값으로 사용될 수 있습니다. 이 수치들은 제 시스템의 벤치마크 결과가 아니며 모든 곳에 적용할 표준도 아닙니다.
튜닝을 하기 전에 네 가지를 확인하세요:
- 의미(Meaning): 각 조각이 주제를 식별하고 필요한 조건을 보존하는가?
- 제한(Limits): 실제 토크나이저와 지침, 질문, 검색된 모든 컨텍스트, 답변에 대한 예산을 사용하세요.
- 중복(Duplication): 오버랩이 유용한 증거를 추가하는가 아니면 단순히 반복하는가?
- 질문 유형(Question type): 금액에 대한 조회와 자격 요건에 대한 질문은 서로 다른 증거를 필요로 할 수 있습니다.
구조와 크기 제한으로 시작하세요. 테스트에서 컨텍스트 누락이 발견될 때 오버랩이나 부모 확장(parent expansion)을 추가하고, 단순히 더 많은 컨텍스트가 안전하다고 느껴진다고 해서 추가하지 마세요.
청킹이 작동하는지 어떻게 알 수 있을까요?
알려진 지원 문서, 섹션 또는 페이지를 사용하여 질문을 만드세요. 경계에 민감한 질문(boundary-sensitive questions), 금액 조회, 그리고 문서가 답변할 수 없는 질문들을 포함하세요.
동일한 소스 및 질문에 대해 유사한 컨텍스트 예산을 가진 두세 가지 접근 방식을 비교하세요. 그런 다음 세 계층을 검사하세요:
- 검색 (Retrieval): 레이블이 지정된 지원 구절들이 발견되었는가? Recall@k는 상위 k개 결과에서 미리 정의된 관련 증거를 검색하는 것을 측정한다. 사용 가능한 증거가 질문에 충분한지 별도로 확인해야 한다.
- 문맥 (Context): 조건과 예외 사항이 존재하는가? 중복 정보가 다른 증거들을 압도하고 있는가? 표의 헤더와 단위는 온전한가?
- 답변 (Answer): 증거를 따르고 있는가? 각 인용은 관련된 주장을 뒷받침하는가? 시스템이 정보 부족을 인정할 수 있는가?
document_id, section, page/offset, 그리고 version과 같은 메타데이터를 저장하여 구절들을 추적하고 오래된 인덱스 항목들을 관리할 수 있도록 한다.
조직적인 데이터를 위해서는, 확장된 부모 문맥(expanded parent context)을 포함하여 콘텐츠가 모델에 도달하기 전에 권한을 강제해야 한다. 최종 답변을 숨기는 것은 모델이 무엇을 받는지 통제하는 것의 대용품이 아니다.
소스 텍스트가 잘못되었다면, 수집 과정(ingestion)을 수정하라. 증거는 존재하지만 발견되지 않았다면, 청킹과 검색을 검사하라. 완전한 증거가 모델에 도달했지만 답변이 틀렸다면, 문맥 조립(context assembly)과 생성 과정을 검사하라.
목표는 사용 가능한 증거이다
RAG 시스템은 일반적으로 각 질문에 대해 전체 라이브러리가 아닌 선택된 증거를 제공한다. 청크 경계는 모델이 무엇을 볼 수 있는지 결정하는 데 도움이 되지만, 답변 품질의 유일한 요소는 아니다.
나의 출발점은 정확한 소스 텍스트, 구조 인식적 경계(structure-aware boundaries), 합리적인 크기 제한, 출처 참조, 그리고 실제 질문을 사용한 테스트이다. 그러한 테스트가 필요성을 보여주는 곳에 복잡성을 추가하라.
최고의 청크는 반드시 가장 작은 청크일 필요는 없다. 그것은 시스템이 찾아서 답변을 유효하게 만드는 것을 잃지 않고 사용할 수 있는 조각이어야 한다.
만약 RAG를 구축하고 있다면, 어떤 문서 유형이 누락된 조건을 야기하는지, 그리고 파이프라인의 어느 단계에서 이를 포착하는지 공유하라.
NEXT4I 여정을 탐색하고 원본 기사를 다음 링크에서 읽어보세요: [https://go.next4i.com/next4i-devto-en]
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기