문서를 일정 길이로 나눴다고 검색 가능한 근거가 완성되는 것은 아닙니다. “전원을 끈 후 덮개를 여세요”에서 조건과 행동이 서로 다른 청크로 분리되면, 검색 결과에 행동만 남을 수 있습니다. 청킹의 목표는 작은 조각을 많이 만드는 것이 아니라, 질문에 답할 수 있는 문맥과 원문 위치를 함께 보존하는 것입니다.
이 글은 Python 3으로 실행할 수 있는 문자 단위 기준선을 만들고 그 한계를 검사하는 방법을 설명합니다. 아래 크기와 겹침은 실험용 값이며 RAGO-X의 운영 기본값이 아닙니다.
분할 전에 추출 결과부터 확인하기
PDF의 다단 편집, 반복 머리말, 표 셀 순서가 추출 과정에서 무너지면 청크 크기를 바꿔도 원문 의미는 돌아오지 않습니다. 실제 문서에서 제목, 본문, 표, 각주가 올바른 순서인지 먼저 확인하세요. 가능하면 제목 경로와 문단을 기본 단위로 삼고, 긴 문단에만 추가 분할을 적용합니다.
표는 행에 열 이름과 단위가 함께 있어야 이해할 수 있습니다. 표가 길다면 제목과 열 머리글을 각 조각에 연결하고 페이지 경계를 기록하세요. 머리글을 덧붙이는 경우 원문 그대로의 구간과 검색을 위해 추가한 문맥을 구분해서 저장해야 합니다.
원문 오프셋을 유지하는 기준선
아래를 chunk_demo.py로 저장하고 python3 chunk_demo.py로 실행하세요. 반열린 구간 [start, end)를 사용하므로 text[start:end]가 청크 본문과 같습니다.
def split_text(text, size=80, overlap=15):
if size <= 0 or not 0 <= overlap < size:
raise ValueError("require size > 0 and 0 <= overlap < size")
start = 0
while start < len(text):
end = min(start + size, len(text))
yield {"start": start, "end": end, "text": text[start:end]}
if end == len(text):
break
start = end - overlap
text = "Pump X17: disconnect power. Wait 30 seconds. Check the inlet filter."
chunks = list(split_text(text, size=40, overlap=10))
print([(c["start"], c["end"]) for c in chunks])
assert [(c["start"], c["end"]) for c in chunks] == [(0, 40), (30, 68)]
assert all(text[c["start"]:c["end"]] == c["text"] for c in chunks)
assert set().union(*(set(range(c["start"], c["end"])) for c in chunks)) == set(range(len(text)))
assert list(split_text("")) == []
출력은 [(0, 40), (30, 68)]입니다. 두 구간은 10문자가 겹치며 원문 전체를 덮습니다. 빈 입력은 청크를 만들지 않고, 잘못된 겹침 값은 오류를 냅니다. 원문을 미리 strip()하거나 공백을 바꾸지 않아 위치 비교를 유지합니다.
이 함수의 단위는 Python 문자열의 문자 수입니다. 바이트, 화면상 글자 묶음, 모델의 토큰 수와 같지 않습니다. 실제 모델 입력 한도는 사용하는 토크나이저로 별도 계산해야 합니다. 제목이나 문장 경계도 인식하지 않으므로 이 기준선 자체를 최종 분할기로 간주하면 안 됩니다.
검색용 메타데이터 설계
| 정보 | 보존하는 이유 |
|---|---|
| 문서 ID와 개정 버전 | 같은 문서의 이전 내용과 구분 |
| 청크 ID와 분할 설정 버전 | 재처리한 청크를 추적 |
| 페이지·절·시작/끝 위치 | 사용자가 원문 근거를 확인 |
| 조직·문서함·접근 범위 | 허용된 문서만 검색 |
| 원문 구간과 추가 문맥 | 인용문과 검색 보조 텍스트를 구분 |
원문 오프셋은 어떤 추출 텍스트 버전을 기준으로 하는지도 필요합니다. OCR이나 공백 정규화가 바뀌면 같은 위치가 다른 내용을 가리킬 수 있습니다. 문서를 교체할 때는 새 청크와 검색 인덱스를 일관되게 전환하고, 이전 버전이 함께 검색되지 않는지 확인하세요. 위 표는 설계 항목이며 공개 API의 필드 계약을 의미하지 않습니다.
크기를 바꾸기 전에 정답 근거를 정하기
실제 질문에 대해 답이 있는 원문 구간을 표시한 뒤 두 가지 분할 설정을 비교하세요. 상위 검색 결과가 정답 구간을 포함하는지, 예외 조건까지 포함하는지, 출처를 열면 같은 버전이 보이는지 확인합니다. 청크 수나 답변 길이만 늘어난 것을 품질 개선으로 보지 마세요.
| 관찰한 문제 | 먼저 시도할 변경 |
|---|---|
| 조건과 결론이 분리됨 | 문단·문장 경계를 우선하고 필요한 인접 문맥 추가 |
| 큰 청크에 여러 주제가 섞임 | 제목별 분리 후 검색 결과 비교 |
| 중복 근거가 문맥 창을 차지함 | 겹침을 줄이거나 인접 후보 중복 정리 |
| 표의 숫자를 오해함 | 열 머리글·단위·각주 연결 |
| 출처 위치가 어긋남 | 추출 텍스트 버전과 위치 매핑 확인 |
겹침은 경계 손실을 줄일 수 있지만 저장량과 중복 후보도 늘립니다. 고정된 최적 크기는 없으므로 질문 집합, 입력 토큰 수, 처리 시간, 인용 정확도를 함께 기록하세요. 다음 단계는 하이브리드 검색 비교와 근거에서 답변까지의 설계입니다.



