| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Java
- MIPS
- github
- react
- DB
- php
- architecture
- mysql
- Linux
- AI
- system
- html
- XML
- DATAPATH
- Class
- DS
- computer
- web
- function
- for
- Algorithm
- python
- control
- data structure
- instruction
- openai
- CSS
- javascript
- Pipelining
- Rag
- Today
- Total
YYYEJI
[MAC] 데이터 로더 후 텍스트 분할(Text Splitting) 하는 과정 본문
안녕하세요! 송로지입니다 🌷
어제는 데이터를 로더하는 방법에 대해 알아보았는데요 :)
[MAC] RAG 기술 사용할 때 웹 문서(WebBaseLoader), CSV(CSVLoader), PDF 파일(PyPDFLoader) 로더하는 방법
↓↓↓ RAG 기본 개념 관련해서 살펴보기 ↓↓↓ RAG 개념 알아보기RAG란 무엇일까요??Retrieval-Augmented Geteration의 줄임말이며,LLM의 한계를 보완하기 위해 외부 지식 베이스에서 정보를 검색(Retrieval)
yyyeji.tistory.com
오늘은 가져온 데이터들을 어떻게 분할할건지 정리해보겠습니다!! 🤩
텍스트 분할은 대규모 텍스트 문서를 처리할 때 매우 중요한 전처리 단계라고 할 수 있는데요!
문서의 구조와 형식, 원하는 청크 크기, 문맥 보존의 중요도, 처리 속도를 고려해야 됩니다.
우선 pdf파일의 데이터들을 로더하고 데이터를 분할해보도록 하겠습니다!
(데이터 로더는 위 사이트를 참고해주세요 ><)
1. CharacterTextSplitter
이 함수는 가장 기본적인 분할 방식입니다!
문자 수를 기준으로 텍스트를 분할하게 되는데 문맥을 고려하지 않는다는 단점이 존재해요,,
설치는 pip install langchain_text_splitters 또는 uv add langchain_text_splitters로 하시면 됩니다 ㅎ
from langchain_text_splitters import CharacterTextSplitter
# 텍스트 분할기 초기화 (기본 설정값 적용 )
text_splitter = CharacterTextSplitter(
separator="\n", # 구분자: 개행문자 (문장 단위로 쪼개기)
chunk_size=10, # 청크 크기
chunk_overlap=2, # 청크 중첩
length_function=len, # 글자 수를 기준으로 분할
)
# 텍스트 분할 - split_text() 메서드 사용
texts = text_splitter.split_text(long_text)
# 분할된 텍스트 개수 출력
print(f"분할된 텍스트의 수: {len(texts)}")
# 첫 번째 분할된 텍스트 출력
print(f"첫 번째 분할된 텍스트: {texts[0]}")
CharacterTextSplitter()는 데이터를 분할하는 함수이고 그 안에 요소들을 살펴보면
separator은 어디서 자를지에 대한 기준,
chunk_size는 한 번에 담을 최대 길이,
chunk_overlap은 다음 청크와 겹치는 부분의 길이를 나타냅니다!
(length_function은 길이를 계산하는 기준 함수에요)
texts = text_splitter.split_text(long_text)는
long_text라는 긴 문자열을 지정한 기준대로 잘라서 리스트로 반환하게 돼요
len(texts)는 분할된 청크의 개수,
texts[0]는 분할된 텍스트의 첫 번째 내용을 출력합니다.
2. RecursiveCharacterTextSplitter
RecursiveCharacterTextSplitter()는 재귀적으로 텍스트를 분할하게 됩니다!
구분자를 순차적으로 적용하여 큰 청크에서 시작하여 점진적으로 더 작은 단위로 분할합니다.
이 함수의 장점은 문맥을 더 잘 보존할 수 있다는 점입니다!!
문단 → 문장 → 단어 → 글자 순으로 잘게 나누는 코드를 살펴보겠습니다!
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 재귀적 텍스트 분할기 초기화
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 청크 크기
chunk_overlap=200, # 청크 중 중복되는 부분 크기
length_function=len, # 글자 수를 기준으로 분할
separators=["\n\n", "\n", " ", ""], # 구분자 - 재귀적으로 순차적으로 적용 [문단, 문장, 띄어쓰기, 공백]
)
# split_documents() 메서드 사용 : Document 객체를 여러 개의 작은 청크 문서로 분할
chunks = text_splitter.split_documents(pdf_docs)
print(f"생성된 텍스트 청크 수: {len(chunks)}")
print(f"각 청크의 길이: {list(len(chunk.page_content) for chunk in chunks)}")
print()
# 각 청크의 시작 부분과 끝 부분 확인 - 5개 청크만 출력
for chunk in chunks[:5]:
print(chunk.page_content[:200])
print("-" * 100)
print(chunk.page_content[-200:])
print("=" * 100)
print()
RecursiveCharacterTextSplitter()은 큰 덩어리부터 자르고,
chunk_size를 넘어가면 점점 더 작은 단위로 쪼개는 방식이며 안에 요소들을 살펴보면!
chunk_size는 한 청크(조각)의 최대 길이,
chunk_overlap은 현재 청크와 다음 청크가 (문맥 유지를 위해) 200자씩 겹치게 됩니다
length_function=len은 글자 수 기준으로 길이를 계산
separators는 재귀적으로 자를 때의 기준
(\n\n → 문단, \n → 줄바꿈 " " → 단어, " " → 글자)
을 나타냅니다!
3. 정규표현식 사용
RechursiveCharacterTextSplitter()을 사용하면서
일반적인 문자 길이(len) 대신 토큰 단위로 청크를 나눠볼건데요!
분할하는 정규표현식을 살펴볼게요!
from langchain_text_splitters import RecursiveCharacterTextSplitter
# TikToken 인코더를 사용하여 재귀적 텍스트 분할기 초기화
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
#encoding_name="cl100k_base",
model_name="gpt-4o-mini",
chunk_size=10,
chunk_overlap=0,
)
# split_documents() 메서드 사용 : Document 객체를 여러 개의 작은 청크 문서로 분할
chunks = text_splitter.split_documents([pdf_docs[0]]) # 첫 번째 문서만 분할
print(f"생성된 청크 수: {len(chunks)}")
print(f"각 청크의 길이: {list(len(chunk.page_content) for chunk in chunks)}")
# 각 청크의 시작 부분과 끝 부분 확인
for chunk in chunks[:5]:
print(chunk.page_content[:50])
print("-" * 50)
print(chunk.page_content[-50:])
print("=" * 50)
print()
.from_tiktoken_encoder은 OpenAI의 토큰화 방식이고
model_name 해당 모델의 토큰 규칙에 마춰 분할을 하게 되고
chunk_size=10은 한 청크 최대 10 토큰,
chunk_overlap=0은 청크 간 겹침 없음을 의미합니다!
문자 단위가 아니라 토큰 단위여서 영어 단어 하나가 여러 토큰으로 나뉠 수도 있으며,
한글 한 글자는 보통 1토큰입니다.!!
이 방식을 사용하면 토큰 단위로 자르기 때문에
모델 입력 제한(token limit)에 맞춰서 안전하게 청크를 만들 수 있고,
같은 1000자라도 토큰 개수가 달라질 수 있으니, 모델 기준에 맞추는 게 더 정확합니다!

그렇다면 왜 분할을 할까요?
LLM은 한 번 처리할 수 있는 토큰 수가 제한되어 있어서,
긴 문서를 RAG나 검색에 쓰려면 이렇게 잘게 나누고 중복을 조금 포함시켜
문맥이 끊기지 않게 해야 됩니다!!
이러한 분할은
긴 문서를 LLM이 처리할 수 있게 잘라주며
문맥이 끊기지 않도록 일부 겹치게 overlap하며
문단 → 문장 → 단어 → 글자 순으로 유연하게 쪼개며
RAG(검색+생성) 구조에서 거의 필수적으로 사용된다고 보시면 됩니다!!
'인공지능 챗봇' 카테고리의 다른 글
| [MAC] 벡터 저장소 ChromaDB 사용한 코드 살펴보기 (2) | 2025.08.05 |
|---|---|
| [MAC] 문서 임베딩(Document Embedding) 코드 파해치기 (6) | 2025.08.05 |
| [MAC] RAG 기술 사용할 때 웹 문서(WebBaseLoader), CSV(CSVLoader), PDF 파일(PyPDFLoader) 로더하는 방법 (10) | 2025.08.04 |
| [MAC] LangChain 주요 컴포넌트 파해치기 (16) | 2025.08.01 |
| [MAC] OpenAI를 통해 이미지 분석해보기 (6) | 2025.07.31 |