기본 개념
- RecursiveCharacterTextSplitter는 텍스트의 자연스러운 구조를 존중하며 분할하는 고급 텍스트 스플리터임
- 단순히 글자 수로 자르는 것이 아니라, 텍스트의 계층적 구조(문단, 문장, 단어 등)를 고려함
작동 방식
이름에서 알 수 있듯이 '재귀적(Recursive)' 방식으로 작동한다.
- 먼저 가장 큰 단위(예: 문단)로 텍스트를 분할
- 나눈 조각이 지정한 크기(chunkSize)보다 크면, 그 다음 작은 단위(예: 문장)로 분할
- 여전히 크기가 초과하면, 더 작은 단위(예: 단어)로 계속 분할
- 최종적으로 지정된 크기에 맞는 청크들을 생성
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000, // 각 청크의 최대 크기
chunkOverlap: 200, // 청크 간 겹치는 부분
separators: ["\n\n", "\n", " ", ""] // 분할 기준 (우선순위 순)
});
const chunks = await textSplitter.splitText(longDocument);
주요 매개변수
- chunkSize: 각 청크의 최대 크기(문자 또는 토큰 수)
- chunkOverlap: 연속된 청크 간에 겹치는 부분의 크기. 맥락 유지에 중요
- separators: 텍스트를 나눌 때 사용할 구분자 목록. 앞에 있을수록 우선순위가 높음
- lengthFunction: 텍스트 길이를 계산하는 함수. 기본값은 문자 수이지만, 토큰 수로 변경 가능
기본 구분자(separators)
기본적으로 다음 순서로 구분자를 사용:
"\n\n"
(빈 줄) - 문단 구분"\n"
(줄바꿈) - 줄 구분"."
(마침표) - 문장 구분"!"
(느낌표) - 문장 구분"?"
(물음표) - 문장 구분" "
(공백) - 단어 구분""
(빈 문자열) - 문자 구분
특화된 버전들
언어나 문서 형식에 따라 특화된 RecursiveCharacterTextSplitter도 있음
// Python 코드를 위한 스플리터
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
const pythonSplitter = RecursiveCharacterTextSplitter.fromLanguage("python", {
chunkSize: 1000,
chunkOverlap: 200
});
// HTML용 스플리터
const htmlSplitter = RecursiveCharacterTextSplitter.fromLanguage("html", {
chunkSize: 1000,
chunkOverlap: 200
});
실전 팁
- 최적의 chunkSize 찾기: 너무 작으면 맥락이 손실되고, 너무 크면 검색 정확도가 떨어짐
- chunkOverlap 활용: 청크 간 맥락 유지를 위해 약 10-20% 정도의 겹침을 두는 것이 좋음
- 문서 특성에 맞는 구분자: 기술 문서, 소설, 법률 문서 등 문서 타입에 따라 구분자를 조정
- 토큰 기반 분할 고려: LLM과 함께 사용할 때는 문자 수보다 토큰 수 기준으로 분할하는 것이 효과적임
- 이 스플리터를 사용하면 단순히 기계적으로 나누는 것보다 훨씬 더 자연스럽고 의미 있는 텍스트 조각을 얻을 수 있음
- RAG(Retrieval-Augmented Generation) 시스템 구축에 특히 유용