LLM에 넣기 좋은 문서를 만들기 위한 LangChain 문서 청크 분할 가이드 (chunk_size & overlap 이해하기)
# ✂️ 문서를 LLM 입력에 맞게 청크(chunk) 단위로 분할하는 단계
# - 긴 문서는 한 번에 LLM에 넣기 어렵기 때문에, 적절한 길이로 잘라야 함
# - LangChain의 CharacterTextSplitter를 사용해 '문자 기준'으로 분할함
text_splitter = CharacterTextSplitter(
chunk_size=1000, # 📏 한 청크당 최대 1,000자까지 포함
chunk_overlap=200 # 🔁 청크 간에 200자씩 겹치도록 설정 (문맥 끊김 방지용)
)
# 🧩 실제 분할 실행: documents 리스트 내 각 문서를 위 설정대로 나눔
chunks = text_splitter.split_documents(documents)
💡 왜 chunk_overlap을 주는 걸까?
- 단락이 청크 중간에 끊기면 의미 전달이 어려워집니다.
- 예를 들어 청크 1 끝부분 내용이 청크 2의 앞부분에도 일부 포함되면
- → LLM이 더 자연스럽고 정확한 답변을 생성해요.
📌 결과 예시 (chunks [0])
Document(
page_content="Shopwise는 2020년 설립된 전자상거래 플랫폼으로, 고객 중심 배송 시스템을 도입했습니다...",
metadata={
'source': 'knowledge-base/staff/jaeyoung.md',
'doc_type': 'staff'
}
)
⚠️ 메시지 의미:
Created a chunk of size 1088, which is longer than the specified 1000
이 메시지는 LangChain의 CharacterTextSplitter를 사용할 때 종종 나타나는 경고인데,
아주 자연스러운 현상이고, 오류는 아닙니다.
→ chunk_size=1000으로 설정했지만, 분할된 결과 중 일부 청크가
1,088자처럼 더 길어졌다는 뜻이에요.
🤔 왜 이런 일이 생길까?
LangChain의 CharacterTextSplitter는 단순히 1000자마다 무조건 자르지 않습니다.
청크를 나눌 때 문장이 갑자기 끊기지 않도록, 아래와 같은 기준을 사용합니다:
- 기본적으로는 개행 문자(\n\n)나 구분자 기준으로 청크를 나누려고 시도함.
- 만약 적절한 위치를 찾지 못하면, 조금 더 길어져서라도 자연스럽게 끊으려고 함
- 그래서 결과 청크가 chunk_size보다 약간 클 수도 있음
✅ 해결책 (선택 사항)
문제가 아니므로 그냥 두어도 괜찮지만,
정말로 엄격하게 1000자 이하로 자르길 원한다면, 아래처럼 설정할 수 있습니다:
text_splitter = CharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len, # 길이 측정 기준
keep_separator=False # 분리자 포함 여부 (기본 True → False로 하면 좀 더 짧아짐)
)
혹은 더 정밀한 제어를 원한다면 RecursiveCharacterTextSplitter를 쓰는 방법도 있어요:
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
📦 문서 청크 수 확인하기
len(chunks)는 앞서 text_splitter.split_documents(documents)로 생성된 청크(Chunk)들의 총개수를 확인하는 코드입니다.
# 📦 전체 청크(문서 조각) 개수 확인
# - chunks는 text_splitter를 사용해 분할된 문서 단위 리스트
# - RAG 파이프라인에서 이 청크들을 벡터화(embedding)하고 검색에 활용함
# - 이 값을 통해 임베딩 작업 규모나 예상 처리량을 가늠할 수 있음
len(chunks)
💡 예시
len(chunks) # 👉 132
→ 총 132개의 문서 청크가 생성되었으며,
이후 벡터 저장소(DB)에도 132개 벡터가 들어갈 예정이에요.
🔍 특정 문서 청크 미리 보기
# 🔍 7번째 문서 청크 확인 (인덱스는 0부터 시작하므로 6번이 실제 7번째)
# - 각 청크는 LangChain의 Document 객체로 구성됨
# - 이 객체는 다음과 같은 구조를 가짐:
# - page_content: 잘려진 문서의 본문 내용
# - metadata: 원래 문서의 경로, 유형(doc_type) 등의 부가 정보
chunks[6]
chunks [6]은 분할된 문서 청크 중 7번째 조각을 가져오는 코드입니다.
이걸 이해하면 RAG에서 실제로 LLM이 참고할 context가 어떤 형태인지 감 잡을 수 있어요.
💡 예시 출력 (실제 형태)
Document(
page_content="Shopwise는 최근 빠른 결제 시스템을 도입하여 고객 편의성을 높였습니다...",
metadata={
'source': 'knowledge-base/products/payment.md',
'doc_type': 'products'
}
)
🗂️ 문서 유형(doc_type) 목록 확인
# 🗂️ 전체 청크에서 사용된 문서 유형(doc_type) 종류만 모아서 집합(set)으로 추출
# - 각 청크에는 'staff', 'products' 등 원래 폴더명을 기반으로 doc_type 메타데이터가 포함됨
# - set을 사용하면 중복 없이 고유한 유형만 추출됨
doc_types = set(chunk.metadata['doc_type'] for chunk in chunks)
# 📢 발견된 문서 유형을 쉼표로 구분해 출력
# - 어떤 종류의 문서가 knowledge base에 포함되어 있는지 확인 가능
print(f"Document types found: {', '.join(doc_types)}")
이 코드는 청크에 포함된 문서들의 유형(doc_type)이 몇 가지인지 확인하는 데 쓰입니다.
💡 예시 출력
Document types found: products, staff
이 출력은 현재 knowledge-base에
- products 관련 문서
- staff 관련 문서
가 있다는 걸 의미해요.
✅ 왜 중요해?
- 벡터 검색 결과를 필터링할 때 활용 가능합니다.
- 특정 유형 문서만 따로 관리하고 싶을 때도 유용해요.
🔎 특정 키워드가 포함된 청크 검색
# 🔍 전체 청크 중에서 'CEO'라는 단어가 포함된 문서만 찾아서 출력
# - chunk.page_content: 각 문서 청크의 본문 내용
# - 특정 키워드(예: 직책, 이름 등)가 들어간 문서를 필터링할 때 유용함
# - 실시간 검색/디버깅 용도로 자주 사용됨
for chunk in chunks:
if 'CEO' in chunk.page_content:
print(chunk) # 해당 청크의 전체 정보 (본문 + 메타데이터)
print("_________") # 시각적으로 청크 구분을 위한 구분선
이 코드는 모든 청크를 순회하면서, 내용 안에 'CEO'라는 단어가 포함된 청크만 필터링해서 출력하는 작업입니다.
💡 예시 출력 형태
Document(
page_content='Jaeyoung is the CEO of Shopwise...',
metadata={'source': 'knowledge-base/staff/jaeyoung.md', 'doc_type': 'staff'}
)
_________
✨ 활용 아이디어
- '배송', '결제 수단', '고객' 같은 키워드로도 필터링 가능
- if keyword.lower() in chunk.page_content.lower()처럼 대소문자 무시하도록 개선 가능
- 조건 추가해서 특정 doc_type만 검색할 수도 있어요.
'🧠 LLM 엔지니어링' 카테고리의 다른 글
LangChain과 Chroma를 활용한 문서 임베딩 시각화 실습 01 (0) | 2025.04.26 |
---|---|
LLM 문서에서 특정 키워드 추출하는 방법 01 (Shopwise 지식기반 예제) (1) | 2025.04.24 |
LangChain으로 시작하는 RAG 파이프라인 구축 여정 (1) | 2025.04.23 |
RAG와 벡터 임베딩 이해하기 (1) | 2025.04.22 |
LLM 챗봇 만들기: 전자상거래 회사 지식 기반 질문응답 시스템 (RAG 구현 예제) (1) | 2025.04.21 |