· 청킹(chunking)은 긴 문서를 검색·임베딩에 적합한 작은 조각으로 나누는 작업으로, RAG의 검색 품질을 좌우하는 숨은 핵심 단계입니다.
· 모든 문서에 똑같은 크기로 자르는 방식은 자주 실패합니다. 코드·표·논문·대화 등 문서 특성에 따라 분할 기준이 달라져야 합니다.
· 핵심은 의미 단위를 깨지 않게 나누고, 겹침(overlap)으로 맥락을 이어 주며, 메타데이터로 조각의 출처를 남기는 것입니다.
→
🧭 구조 파악
→
✂️ 의미 단위 분할
→
🔁 겹침 추가
→
🏷️ 메타데이터 부착
RAG(검색 증강 생성)를 만들어 본 사람이라면 한 번쯤 겪는 일이 있습니다. 임베딩 모델도 좋은 것을 썼고 벡터 데이터베이스도 제대로 붙였는데, 정작 검색된 내용이 엉뚱해서 답이 부실한 경우입니다. 원인을 따라가 보면 의외로 청킹(chunking), 즉 문서를 어떻게 잘라 저장했는가에서 문제가 시작되는 때가 많습니다. 청킹은 눈에 잘 띄지 않는 전처리 단계지만, 검색 품질의 상한선을 사실상 여기서 결정합니다. 이번 글에서는 단순히 ‘몇 글자씩 자른다’를 넘어, 문서의 특성에 맞춰 분할 전략을 고르는 방법을 개념 중심으로 정리합니다.
🎯 청킹이 왜 중요한가
RAG의 동작은 간단히 말해 ‘질문과 비슷한 조각을 찾아, 그 조각을 근거로 답하기‘입니다. 여기서 검색의 대상이 바로 청크(chunk), 곧 문서를 잘라 만든 작은 조각입니다. 즉 모델이 참고할 수 있는 지식의 최소 단위가 청크이므로, 조각을 어떻게 나눴는가가 검색 결과의 질을 직접 좌우합니다.
조각이 너무 크면 한 조각에 여러 주제가 뒤섞여, 질문과 무관한 내용까지 함께 끌려옵니다. 임베딩이 하나의 벡터로 뭉뚱그려져 초점이 흐려지는 것입니다. 반대로 너무 작으면 문맥이 끊겨, 정작 필요한 설명의 앞뒤 맥락이 다른 조각으로 흩어집니다. 좋은 청킹은 이 둘 사이에서 하나의 완결된 의미를 담은 크기를 찾는 일입니다.
한 줄 정리 — 청크는 RAG가 참고하는 지식의 최소 단위입니다. 조각을 잘못 나누면, 그 뒤의 임베딩·검색이 아무리 좋아도 품질의 천장이 낮아집니다.
⚠️ 고정 크기 분할의 한계
가장 흔히 쓰는 방법은 고정 크기 분할입니다. “500자마다 자른다”처럼 글자 수나 토큰 수를 기준으로 기계적으로 나누는 방식입니다. 구현이 쉽고 빠르지만, 문서의 의미 구조를 무시하기 때문에 다음과 같은 문제가 자주 생깁니다.
이 때문에 실무에서는 단순 고정 크기 대신, 문단·문장 같은 자연스러운 경계를 우선 따르는 방식이 널리 쓰입니다. 흔히 ‘재귀적 문자 분할(recursive character splitting)‘이라 불리는 방법으로, 먼저 큰 경계(문단)로 나누고, 그래도 길면 작은 경계(문장, 단어)로 점점 쪼개 가능한 한 의미 단위를 보존합니다.
🧩 문서 특성별 분할 전략
핵심은 문서마다 ‘자연스러운 경계’가 다르다는 점입니다. 같은 전략을 모든 문서에 적용하면 어딘가에서 반드시 깨집니다. 대표적인 문서 유형별로 어떤 기준을 쓰면 좋은지 정리해 보겠습니다.
첫째, 일반 산문·기사는 문단과 문장이 의미 경계와 잘 맞습니다. 문단 단위를 우선하고, 너무 길면 문장 단위로 쪼개는 방식이 무난합니다. 둘째, 마크다운·기술 문서는 제목 계층(h1·h2·h3)이 훌륭한 경계입니다. 헤딩을 기준으로 나누면 한 조각이 하나의 소주제를 담아 검색 적합도가 높아집니다. 셋째, 코드는 함수·클래스 같은 구문 단위로 나눠야 합니다. 줄 수로 자르면 함수가 반 토막 나므로, 언어 구조를 아는 분할기가 필요합니다. 넷째, 표·스프레드시트는 행이 의미 단위인 경우가 많아, 헤더를 각 조각에 반복해 붙여야 맥락이 유지됩니다. 다섯째, 대화·로그는 발화 턴이나 세션을 경계로 삼아, 질문과 답이 한 조각 안에 머물도록 하는 편이 좋습니다.
한 줄 정리 — 분할 기준은 문서가 원래 가진 구조에서 가져옵니다. 산문은 문단, 문서는 제목, 코드는 함수, 표는 행처럼 그 문서의 의미 단위를 따르세요.
📐 겹침·크기를 정하는 기준
분할에서 자주 묻는 두 가지가 ‘조각을 얼마나 크게‘, ‘겹침은 얼마나‘ 둘 것인가입니다. 정답인 숫자는 없지만, 결정에 쓰는 기준은 분명합니다. 크기는 임베딩 모델이 한 번에 잘 담아낼 수 있는 범위 안에서, 하나의 완결된 생각을 담을 만큼으로 잡습니다. 너무 크면 초점이 흐려지고, 너무 작으면 맥락이 끊깁니다.
겹침(overlap)은 인접한 조각이 서로 일부 문장을 공유하게 하는 장치입니다. 경계에서 끊긴 맥락을 이어 주어, 질문과 관련된 내용이 조각 경계에 걸쳐 있어도 놓치지 않게 합니다. 아래는 겹침이 동작하는 방식을 개념적으로 표현한 예시입니다.
# 겹침이 있는 분할 (개념 예시) chunk_size = 500 # 조각 하나의 목표 길이 chunk_overlap = 80 # 이웃과 겹치는 길이 # 결과: 각 조각의 끝 80자가 다음 조각의 앞부분에 다시 포함 [ 조각 A : 0 ~ 500 ] [ 조각 B : 420 ~ 920 ] # 420~500 구간을 공유 [ 조각 C : 840 ~ ... ]
겹침을 늘리면 맥락 보존에 유리하지만, 같은 내용이 여러 조각에 중복 저장되어 저장량과 비용이 늘고 검색 결과에 비슷한 조각이 겹쳐 나올 수 있습니다. 보통 조각 크기의 10~20% 정도를 출발점으로 삼아, 데이터 특성에 맞게 조정하는 식으로 접근합니다. 중요한 것은 숫자 자체가 아니라, 실제 질문으로 검색 품질을 측정하며 조정하는 태도입니다.
🔗 분할 파이프라인 흐름
문서 특성을 반영한 청킹은 몇 단계를 거칩니다. 실제 구현은 더 복잡하지만, ‘유형 판별 → 구조 기반 분할 → 크기 보정 → 메타데이터 부착‘이라는 뼈대는 공통적입니다.
# 문서 특성에 맞춘 청킹 흐름 (의사코드) kind = detect_type(doc) # 산문·마크다운·코드·표 등 splitter = choose_splitter(kind) # 유형별 분할기 선택 chunks = [] for part in splitter.split(doc): # 구조 경계로 1차 분할 if too_long(part): # 여전히 길면 part = split_smaller(part) # 더 작은 경계로 재분할 part = add_overlap(part) # 이웃과 겹침 부여 part.meta = {source, section, kind} # 출처·위치 기록 chunks.append(part)
마지막 단계의 메타데이터 부착은 흔히 간과되지만 매우 중요합니다. 각 조각에 출처 문서·섹션 제목·유형 같은 정보를 함께 저장하면, 검색 뒤에 “이 내용은 어느 문서 어느 절에서 왔는가”를 밝힐 수 있어 답변의 근거 제시(출처 표기)가 쉬워지고, 특정 문서로 검색 범위를 좁히는 필터링도 가능해집니다.
📊 전략별 비교
대표적인 청킹 전략은 간편함과 의미 보존에서 차이가 납니다. 성격을 표로 정리하면 문서에 맞게 고르기 편합니다.
| 전략 | 적합한 문서 | 특징·주의 |
|---|---|---|
| 고정 크기 | 형식 없는 일반 텍스트 | 빠르고 단순하나 의미 단위가 쉽게 깨짐 |
| 재귀적 문자 분할 | 일반 산문·기사 | 문단→문장 순으로 경계 보존, 기본값으로 무난 |
| 구조 기반(제목·구문) | 마크다운·기술 문서·코드 | 제목·함수 단위로 나눠 소주제가 또렷해짐 |
| 의미 기반(semantic) | 주제가 자주 바뀌는 글 | 내용 유사도로 경계를 찾아 자연스러우나 비용 큼 |
정리하면, 단순한 텍스트라면 재귀적 문자 분할만으로도 충분한 경우가 많고, 구조가 뚜렷한 문서일수록 그 구조를 활용하는 전략이 유리합니다. 처음부터 가장 정교한 방법을 쓰기보다, 기본 전략으로 시작해 품질을 측정하며 필요한 부분만 특수 전략으로 바꾸는 접근이 효율적입니다.
💡 실무 팁
- 문서 유형부터 파악 — 자르기 전에 산문·문서·코드·표 중 무엇인지 먼저 확인하면 전략이 저절로 정해집니다.
- 의미 단위를 깨지 말 것 — 문장·함수·표의 행이 중간에서 끊기지 않게 경계를 우선하세요.
- 겹침은 10~20%에서 출발 — 맥락 보존과 중복 사이의 균형점을 데이터로 조정하세요.
- 메타데이터를 꼭 남기기 — 출처·섹션 정보를 저장해야 근거 제시와 필터링이 가능합니다.
- 실제 질문으로 평가 — 숫자를 감으로 정하지 말고, 검색 품질을 측정하며 크기·겹침을 튜닝하세요.
❓ 자주 묻는 질문(FAQ)
Q. 청크는 무조건 작을수록 검색이 정확한가요?
아닙니다. 조각이 너무 작으면 문맥이 끊겨 질문에 필요한 설명이 여러 조각으로 흩어집니다. 하나의 완결된 생각을 담을 만한 크기가 좋고, 너무 작지도 너무 크지도 않은 균형이 핵심입니다.
Q. 겹침은 많을수록 좋은가요?
맥락 보존에는 유리하지만, 같은 내용이 여러 조각에 중복 저장되어 저장량·비용이 늘고 검색에 비슷한 조각이 겹쳐 나올 수 있습니다. 대개 조각 크기의 10~20%를 출발점으로 조정합니다.
Q. 모든 문서에 한 가지 전략만 쓰면 안 되나요?
가능은 하지만 품질이 떨어지기 쉽습니다. 코드·표·대화처럼 구조가 뚜렷한 문서는 그 구조를 활용하는 전략이 확연히 유리하므로, 유형별로 분할기를 달리 하는 편이 좋습니다.
🧷 마무리
청킹은 RAG에서 가장 눈에 안 띄지만 가장 영향이 큰 단계입니다. 임베딩과 벡터 검색이 아무리 좋아도, 조각을 잘못 나누면 검색 품질의 천장이 그만큼 낮아지기 때문입니다. 핵심은 ‘몇 글자씩 자른다’는 기계적 발상에서 벗어나, 문서가 원래 가진 의미 구조를 따라 나누는 것입니다. 산문은 문단, 문서는 제목, 코드는 함수, 표는 행으로 경계를 잡고, 겹침으로 맥락을 잇고, 메타데이터로 출처를 남기세요. 그리고 무엇보다, 숫자를 감으로 확정하지 말고 실제 질문으로 검색 품질을 측정하며 조정해 나가는 것이 좋은 청킹에 이르는 가장 확실한 길입니다.
답글 남기기