Skip to main content

문서 구조 청킹 (Document-Specific Chunking)

문서의 구조적 특성(헤딩, 태그, 문법)을 활용하여 의미 단위로 분할하는 방식입니다. 구조화된 문서에서는 범용 청킹보다 훨씬 높은 품질을 제공합니다.

Markdown 청킹

헤딩(#, ##, ###)을 기준으로 분할하며, 각 청크에 헤딩 계층 메타데이터가 자동으로 포함됩니다.
from langchain_text_splitters import MarkdownHeaderTextSplitter

headers_to_split_on = [
    ("#", "h1"),
    ("##", "h2"),
    ("###", "h3"),
]

splitter = MarkdownHeaderTextSplitter(
    headers_to_split_on=headers_to_split_on,
)
chunks = splitter.split_text(markdown_text)

# 각 청크에 헤딩 메타데이터가 포함됨
for chunk in chunks:
    print(chunk.metadata)  # {"h1": "RAG", "h2": "검색", "h3": "벡터 검색"}
    print(chunk.page_content[:100])

HTML 청킹

HTML 태그 구조를 기반으로 분할합니다.
from langchain_text_splitters import HTMLHeaderTextSplitter

headers_to_split_on = [
    ("h1", "h1"),
    ("h2", "h2"),
    ("h3", "h3"),
]

splitter = HTMLHeaderTextSplitter(
    headers_to_split_on=headers_to_split_on,
)
chunks = splitter.split_text(html_text)

코드 청킹

프로그래밍 언어의 문법 구조(함수, 클래스, 블록)를 기준으로 분할합니다.
from langchain_text_splitters import (
    RecursiveCharacterTextSplitter,
    Language,
)

# Python 코드 전용 분할기
python_splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON,
    chunk_size=2000,
    chunk_overlap=200,
)
chunks = python_splitter.split_documents(code_docs)

# JavaScript 코드 전용 분할기
js_splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.JS,
    chunk_size=2000,
    chunk_overlap=200,
)

지원 언어

LangChain은 다양한 프로그래밍 언어에 대한 전용 분할기를 제공합니다.
언어Language 값분할 기준
PythonLanguage.PYTHON클래스, 함수, 데코레이터
JavaScriptLanguage.JS함수, 클래스, 화살표 함수
TypeScriptLanguage.TS인터페이스, 클래스, 함수
JavaLanguage.JAVA클래스, 메서드, 어노테이션
GoLanguage.GO함수, 구조체, 인터페이스
RustLanguage.RUSTfn, impl, struct

Chonkie — 경량 청킹 라이브러리

Chonkie는 RAG 파이프라인을 위한 경량 청킹 전용 라이브러리입니다. 문자 수 대신 토큰 수 기반 분할을 기본으로 지원하여 LLM 컨텍스트 관리에 유리합니다.
pip install chonkie[all]

Chunker 종류

Chonkie는 5가지 청킹 전략을 통일된 API로 제공합니다.
토큰 수 기반 고정 크기 분할입니다. 가장 빠르고 단순한 방식으로, 토큰 예산이 엄격한 경우에 적합합니다.
from chonkie import TokenChunker

chunker = TokenChunker(
    tokenizer="gpt-4o",    # 사용할 토크나이저
    chunk_size=512,         # 최대 토큰 수
    chunk_overlap=64,       # 겹침 토큰 수
)
chunks = chunker.chunk(text)

for chunk in chunks:
    print(f"토큰 수: {chunk.token_count}")
    print(f"위치: [{chunk.start_index}:{chunk.end_index}]")
    print(chunk.text[:100])
파라미터설명기본값
tokenizer토크나이저 이름 또는 객체"gpt2"
chunk_size청크당 최대 토큰 수512
chunk_overlap연속 청크 간 겹침 토큰 수128

Chunker 비교

Chunker분할 기준속도품질적합한 경우
TokenChunker토큰 수매우 빠름보통토큰 예산 엄격, 대량 처리
SentenceChunker문장 경계빠름좋음문장 완결성이 중요한 텍스트
RecursiveChunker계층적 구분자빠름좋음범용 (기본 추천)
SemanticChunker임베딩 유사도느림매우 좋음의미적 일관성이 중요한 경우
SDPMChunker이중 패스 유사도매우 느림최상흩어진 관련 내용 병합 필요 시

LangChain 연동

Chonkie 청크를 LangChain Document 객체로 변환하여 기존 RAG 파이프라인에 통합할 수 있습니다.
from chonkie import RecursiveChunker
from langchain_core.documents import Document

chunker = RecursiveChunker(tokenizer="gpt-4o", chunk_size=512)
chunks = chunker.chunk(text)

# LangChain Document로 변환
documents = [
    Document(
        page_content=chunk.text,
        metadata={
            "start_index": chunk.start_index,
            "end_index": chunk.end_index,
            "token_count": chunk.token_count,
        },
    )
    for chunk in chunks
]