Skip to main content

시맨틱 청킹 (Semantic Chunking)

시맨틱 청킹은 임베딩 유사도를 기반으로 의미적으로 관련된 문장을 하나의 청크로 묶는 방식입니다. 문자 수나 구분자가 아닌, 내용의 의미적 연결성을 기준으로 분할합니다.

원리

  1. 문서를 문장 단위로 분리
  2. 각 문장의 임베딩 벡터 생성
  3. 인접 문장 간 코사인 유사도 계산
  4. 유사도가 임계값보다 낮은 지점에서 분할

LangChain SemanticChunker

from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# Percentile 방식 (기본 추천)
splitter = SemanticChunker(
    embeddings=embeddings,
    breakpoint_threshold_type="percentile",
    breakpoint_threshold_amount=95,  # 유사도 95분위수 이하에서 분할
)
chunks = splitter.split_documents(docs)

for i, chunk in enumerate(chunks[:3]):
    print(f"청크 {i+1}: {len(chunk.page_content)}자")

breakpoint_threshold_type 옵션

유사도 분포의 백분위수를 기준으로 분할합니다.
splitter = SemanticChunker(
    embeddings=embeddings,
    breakpoint_threshold_type="percentile",
    breakpoint_threshold_amount=95,
    # 유사도가 하위 5%에 해당하는 지점에서 분할
)
효과
90더 많이 분할 (작은 청크)
95균형 잡힌 기본값
99덜 분할 (큰 청크)

성능 트레이드오프

항목Recursive CharacterSemantic Chunking
분할 기준문자 수 + 구분자임베딩 유사도
청크 크기균일불균일
의미 보존보통우수
처리 속도빠름느림 (임베딩 API 호출)
비용무료임베딩 API 비용
적합한 경우대부분의 일반 사용높은 검색 정확도 필요 시

비용 추정

# text-embedding-3-small 기준
# 1000 토큰당 약 $0.00002
# 10만자 문서 ≈ 25,000 토큰 ≈ $0.0005

# 대규모 문서 처리 시
# 1000개 문서 × 10만자 = $0.50
시맨틱 청킹은 문서의 모든 문장에 대해 임베딩을 생성하므로, 대용량 문서에서는 비용과 시간이 크게 증가합니다. 프로토타이핑에서는 Recursive Character Splitting으로 시작하고, 검색 품질 개선이 필요한 경우에만 전환하세요.
breakpoint_threshold_type="percentile", breakpoint_threshold_amount=95로 시작하세요. 청크가 너무 크면 값을 낮추고(90), 너무 작으면 높이세요(99).