Data & Research

[LLM & RAG] Langchain 기초 - Splitter

물박사의 저장공간 2025. 4. 1. 22:58

langchain.text_splitter 

이 모듈은 긴 문서를 작은 청크(chunks)로 나누는 기능을 제공합니다. 이렇게 쪼개진 정보는 Vector화 되어 Vector DB에 저장이 될 것입니다. 

 

 1. CharacterTextSplitter (기본 텍스트 분할)

특정 문자(예: \n\n 또는 .)를 기준으로 분할합니다. 문장을 일정한 길이로 나누되, 문맥 유지를 위해 겹치는 부분(chunk overlap) 을 포함하는 것이 가능합니다. Argument는 아래와 같습니다. 

  • separator: 분할된 각 청크를 구분할 때 기준이 되는 문자열입니다. 여기서는 빈 문자열('')을 사용하므로, 각 글자를 기준으로 분할합니다.
  • chunk_size: 각 청크의 최대 길이입니다. 여기서는 500으로 설정되어 있으므로, 최대 500자까지의 텍스트가 하나의 청크에 포함됩니다.
  • chunk_overlap: 인접한 청크 사이에 중복으로 포함될 문자의 수입니다. 여기서는 100으로 설정되어 있으므로, 각 청크들은 연결 부분에서 100자가 중복됩니다.
  • length_function: 청크의 길이를 계산하는 함수입니다. 여기서는 len 함수가 사용되었으므로, 문자열의 길이를 기반으로 청크의 길이를 계산합니다.
from langchain.text_splitter import CharacterTextSplitter

text = """LangChain은 RAG 시스템을 구축하는 데 유용한 도구입니다.
문서를 벡터 데이터베이스에 저장하기 전에 작은 청크로 나누는 것이 중요합니다.
LangChain의 text_splitter는 여러 가지 방식으로 문서를 나눌 수 있습니다."""

# 문자 단위로 50자씩 청크를 나누고, 10자씩 겹치도록 설정
splitter = CharacterTextSplitter(
    separator="\n",   # 줄바꿈 기준으로 분할
    chunk_size=50,    # 한 청크의 최대 길이
    chunk_overlap=10  # 청크 간 겹치는 길이
)

chunks = splitter.split_text(text)

# 분할된 텍스트 출력
for i, chunk in enumerate(chunks):
    print(f"Chunk {i+1}: {chunk}\n")

 


2. RecursiveCharacterTextSplitter (재귀적 텍스트 분할)

긴 문서를 우선 큰 단위로 나누고, 필요하면 작은 단위로 재귀적으로 분할합니다. 문맥을 최대한 유지하면서 최적의 크기로 나누는 방식입니다. 

from langchain.text_splitter import RecursiveCharacterTextSplitter

text = """LangChain은 다양한 문서 분할 기법을 제공합니다. 
특히 RAG와 같은 검색 기반 생성 모델에서는 문서를 효과적으로 나누는 것이 중요합니다. 
RecursiveCharacterTextSplitter는 문장을 재귀적으로 분석하여 가장 적절한 크기로 나누는 방식입니다."""

# 기본적으로 문장을 우선 분할하고, 단어 단위로 더 작게 쪼갬
splitter = RecursiveCharacterTextSplitter(
    chunk_size=50,    # 한 청크의 최대 길이
    chunk_overlap=10  # 겹치는 부분
)

chunks = splitter.split_text(text)

for i, chunk in enumerate(chunks):
    print(f"Chunk {i+1}: {chunk}\n")

 


3. TokenTextSplitter (토큰 기반 분할)

특정 언어 모델(GPT, BERT 등)의 토큰 개수를 기준으로 분할합니다.
예: OpenAI 모델의 tiktoken 라이브러리를 사용하여 1000토큰 단위로 문서 분할 가능

from langchain.text_splitter import TokenTextSplitter

text = """LangChain의 TokenTextSplitter는 특정 LLM의 토큰 개수를 기준으로 문서를 나눕니다.
이 방식은 토큰 비용을 절약하는 데 효과적이며, OpenAI의 tiktoken을 사용할 수 있습니다."""

splitter = TokenTextSplitter(
    chunk_size=20,   # 한 청크의 최대 토큰 수
    chunk_overlap=5  # 겹치는 토큰 수
)

chunks = splitter.split_text(text)

for i, chunk in enumerate(chunks):
    print(f"Chunk {i+1}: {chunk}\n")

 

4. SemanticChunker

OpenAI embedding 정보를 활용해서 각 문장에 대한 embedding 생성합니다. next sentence와의 embedding distance가 threshold 이하일 때는 chunk를 결합하고, 이상일 때는 chunk 분리하는 방식입니다. 

from langchain_experimental.text_splitter import SemanticChunker


text_splitter = SemanticChunker(OpenAIEmbeddings(api_key=api_key))

documents = text_splitter.split_documents(docs)