7차시. 텍스트 분할 이해
10. 이번 차시 완성 코드
출처: 원본 PDF 07차시_텍스트분할이해.pdf 20~21쪽 · 쪽 그림 20쪽 21쪽
6차시의 로딩과 오늘의 분할을 하나로 합칩니다. 8차시에서 이 결과를 바로 씁니다.
📝 src/prepare.py — 로딩 + 분할
from langchain_text_splitters import RecursiveCharacterTextSplitter
from ingest import load_documents
CHUNK_SIZE = 100
CHUNK_OVERLAP = 20
def prepare_chunks(path: str):
# 문서를 읽고 조각으로 나눠서 돌려준다
docs = load_documents(path)
splitter = RecursiveCharacterTextSplitter(
chunk_size=CHUNK_SIZE,
chunk_overlap=CHUNK_OVERLAP,
separators=["\n\n", "\n", ". ", " ", ""],
length_function=len,
)
chunks = splitter.split_documents(docs)
# 조각마다 번호를 매겨둔다 (나중에 추적용)
for i, c in enumerate(chunks):
c.metadata["chunk_id"] = i
lengths = [len(c.page_content) for c in chunks]
print(f"✓ 조각 {len(chunks)}개 생성 "
f"(평균 {sum(lengths)//len(lengths)}자, "
f"최소 {min(lengths)}자, 최대 {max(lengths)}자)")
if min(lengths) < 50:
print("⚠ 50자 미만 조각이 있습니다. chunk_size 확인 권장")
return chunks
if __name__ == "__main__":
chunks = prepare_chunks("data/manual.pdf")
for c in chunks[:3]:
print(f"\n[{c.metadata['chunk_id']}] "
f"p.{c.metadata['page_no']}")
print(c.page_content[:100])실행 결과 예시 (코드를 읽고 만든 예상 화면입니다. 실제 실행 결과, 특히 모델의 답은 다를 수 있습니다)
✓ 3쪽 로딩 완료 (총 1529자)
✓ 조각 21개 생성 (평균 77자, 최소 47자, 최대 99자)
⚠ 50자 미만 조각이 있습니다. chunk_size 확인 권장
[0] p.1
1
제품 사용 설명서
가정용 공기청정기 AP-3300
목차
1. 제품 개요
2. 설치 방법
3. 사용 방법
4. 환불 및 교환 규정
5. 보증 및 무상 A/S
[1] p.1
5. 보증 및 무상 A/S
6. 문제 해결(FAQ)
7. 고객센터 안내
8. 제품 사양
9. 품질보증서
[2] p.2
가정용 공기청정기 AP-3300
2
1. 제품 개요
본 제품은 가정용 공기청정기로서, 초미세먼지·유해가스·생활 악취를 효과적으로 제거합니다.💡 chunk_id를 넣어둔 이유
나중에 "몇 번 조각이 검색됐는지" 추적할 수 있습니다.
12차시에서 RAG가 이상한 답을 할 때
"아, 17번 조각이 잘못 걸렸구나" 하고
바로 원인을 찾을 수 있게 됩니다.
실습 코드 · 07/prepare.py
실습 코드: 실습/src/07/prepare.py · 위의 원본 PDF 7차시 20~21쪽 「이번 차시 완성 코드」과 이어집니다.
# ============================================================
# 7차시 | PPT: 07차시_텍스트분할이해.pptx
# 역할: 설명서를 chunk로 나누고 각 조각에 chunk_id를 붙이는 함수
# 입력: ../../data/manual.pdf
# 출력: 로딩 문장, 조각 개수, 앞 3개 본문과 chunk_id
# 흐름:
# (import 시) manual.pdf -> load_documents
# prepare_chuncks(경로)
# -> load_documents -> splitter -> chunk_id 부여 -> 반환
# ============================================================
# Document: 본문(page_content)과 metadata 딕셔너리를 담는 객체
# chunk: 검색에 쓰려고 잘라 낸 문서 조각
# overlap: chunk_overlap. 이웃 조각이 이 글자 수만큼 겹칩니다.
# metadata: 본문 밖의 부가 정보. 여기서 chunk_id(조각 번호)를 추가합니다.
from langchain_community.document_loaders import PyPDFLoader
import os
import sys
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.documents import Document
# split_basic.py와 같은 방법으로 06 폴더의 ingest.py를 찾게 합니다.
CURRENT_DIR = os.path.dirname(__file__)
INGEST_DIR = os.path.join(CURRENT_DIR, "..", "06")
sys.path.insert(0, INGEST_DIR)
from ingest import load_documents
# 이 모듈을 import하기만 해도 아래 한 줄이 실행되어 PDF를 한 번 읽습니다.
docs = load_documents("../../data/manual.pdf")
# 값을 맨 위 상수로 빼 두면, 비교 실험 때 이 두 줄만 고치면 됩니다.
CHUNK_SIZE = 200
CHUNK_OVERLAP = 50
def prepare_chuncks(path):
# 함수 안에서도 같은 로더로 다시 읽습니다. 이름 철자는 chuncks입니다.
docs = load_documents(path)
# 자르는 기준은 split_basic.py와 같고, 크기와 겹침만 상수에서 가져옵니다.
splitter = RecursiveCharacterTextSplitter(
chunk_size = CHUNK_SIZE,
chunk_overlap = CHUNK_OVERLAP,
separators=["\n\n", "\n", ". ", " ", ""],
length_function = len,
)
chunks = splitter.split_documents(docs)
# 0부터 번호를 매겨 metadata에 넣습니다. 검색 결과를 구분할 때 씁니다.
for index, chunk in enumerate(chunks):
chunk.metadata["chunk_id"] = index
print(f"{len(chunks)} 개")
return chunks
# 직접 실행할 때만 아래가 돕니다. 위의 docs 줄 때문에 로딩 문장은 두 번 찍힙니다.
if __name__ == "__main__":
chunks = prepare_chuncks("../../data/manual.pdf")
# 전체 대신 앞 3개만 출력합니다.
for chunk in chunks[:3]:
print(chunk.page_content)
print(chunk.metadata["chunk_id"])
print()실행 결과 샘플 (교안 기록. API 키가 필요한 코드는 키 없이 맞춘 예시이고, 모델의 답은 실행할 때마다 달라집니다)
===== 실행 결과 샘플 =====
실행: cd 실습/src/07
python prepare.py
3쪽 로딩 완료 (총 1529 자)
3쪽 로딩 완료 (총 1529 자)
11 개
1
제품 사용 설명서
가정용 공기청정기 AP-3300
목차
1. 제품 개요
2. 설치 방법
3. 사용 방법
4. 환불 및 교환 규정
5. 보증 및 무상 A/S
6. 문제 해결(FAQ)
7. 고객센터 안내
8. 제품 사양
9. 품질보증서
0
가정용 공기청정기 AP-3300
2
1. 제품 개요
본 제품은 가정용 공기청정기로서, 초미세먼지·유해가스·생활 악취를 효과적으로 제거합니다.
HEPA 13 등급 필터와 활성탄 필터를 함께 사용하여 실내 공기질을 쾌적하게 유지합니다.
권장 사용 면적은 33㎡ 이내이며, 저소음 설계로 취침 시에도 사용할 수 있습니다.
2. 설치 방법
1
2. 설치 방법
벽면에서 30cm 이상 떨어진 곳에 제품을 설치해 주세요.
바닥이 평평하고 통풍이 잘 되는 곳에 두시는 것이 좋습니다.
전원 코드는 접지가 된 콘센트에 연결해 주세요.
커튼이나 가구 등으로 흡입구·배출구가 가려지지 않도록 주의해 주세요.
3. 사용 방법
전원 버튼을 눌러 제품을 켜고, 원하는 풍량 단계(약/중/강/자동)를 선택하세요.
2코드 해설
설명서를 chunk로 나누고 각 조각에 chunk_id를 붙이는 함수입니다. 입력은 ../../data/manual.pdf이고, 출력은 로딩 문장, 조각 개수, 앞 3개 본문과 chunk_id입니다.
주석에 적힌 흐름입니다.
(import 시) manual.pdf -> load_documents
prepare_chuncks(경로)
-> load_documents -> splitter -> chunk_id 부여 -> 반환코드 앞에서 고정해 두는 말입니다.
- Document: 본문(page_content)과 metadata 딕셔너리를 담는 객체
- chunk: 검색에 쓰려고 잘라 낸 문서 조각
- overlap: chunk_overlap. 이웃 조각이 이 글자 수만큼 겹칩니다.
- metadata: 본문 밖의 부가 정보. 여기서 chunk_id(조각 번호)를 추가합니다.
함수와 클래스로 나누어 읽습니다.
prepare_chuncks: 이름 그대로 한 가지 일만 합니다. 본문 주석을 같이 읽습니다.
파일 맨 아래 실행 결과 샘플 주석은 실행되지 않습니다. 화면 출력은 다음 절에 다시 적어 두었습니다.