12장 · 문서 로딩과 청킹왜 RAG가 필요한가 — 규정은 모델의 머릿속이 아니라 문서에 있다RAG의 두 시점 — 미리 해 두는 일과 질문마다 하는 일PDF에서 텍스트 꺼내기 — 눈에 보이는 대로 나오지 않는다청킹 — 어디서, 얼마나 크게 자를 것인가메타데이터 — 조각에 출처를 적어 둔다따라하기 — 정책 문서 로딩과 청킹정리와 체크리스트실습문제와 해답
12장. 문서 로딩과 청킹
정리와 체크리스트
12장에서 배운 것
- RAG(검색 증강 생성) — 질문과 관련된 문서 조각을 찾아 프롬프트에 붙이고, 그것을 근거로 답하게 하는 방법.
- 인덱싱 시점 / 질의 시점 — 문서를 미리 준비해 두는 때와, 질문마다 찾아 답하는 때.
- 로딩 — 파일에서 글을 꺼내는 일. PDF는
pypdf로 꺼냅니다. - 청크 / 청킹 — 검색 단위가 되는 조각 / 글을 조각으로 자르는 일.
chunk_size/chunk_overlap— 청크의 최대 글자 수 / 이웃 청크와 겹치는 글자 수.- 재귀적 분할 — 빈 줄, 줄바꿈, 문장, 띄어쓰기 순으로 자를 자리를 찾는 방식.
- 메타데이터 — 청크가 어디서 왔는지 적어 둔 정보. 답변에 근거를 붙이는 재료입니다.
한눈에 보는 핵심
reader = PdfReader(pdf_path) # 로딩
text = "\n".join(page.extract_text() for page in reader.pages)
splitter = RecursiveCharacterTextSplitter( # 청킹
chunk_size=500, chunk_overlap=100,
separators=["\n\n", "\n", ". ", " ", ""])
for chunk in splitter.split_text(text): # 문서마다 따로
documents.append({"id": ..., "text": chunk,
"metadata": {"source": ..., "doc_title": ...,
"article": find_articles(text, chunk)}})
| 정한 것 | 값 | 근거 |
|---|---|---|
| 청크 크기 | 500자 | 조항 한두 개가 들어가는 크기 |
| 겹침 | 100자 | 경계에 걸친 표와 문장을 양쪽에 남긴다 |
| 자르는 단위 | 문서마다 따로 | 두 정책이 한 청크에 섞이지 않게 |
| 메타데이터 | 파일 이름, 문서 제목, 청크에 담긴 조항 전부 | 답변에 근거를 붙이려고 |
| 화면 출력의 자리 | if __name__ == "__main__": 아래 |
다른 장이 가져다 쓸 때 출력이 섞이지 않게 |
이 값들은 모두 사람이 정한 것입니다. 모델은 이번 장에서 아무 일도 하지 않았습니다.
체크리스트
- [ ] 3장에서 환불액이 실행마다 달랐던 이유를 RAG의 필요와 연결해 설명할 수 있다.
- [ ] 규정 질문을 도구(Function Calling)로 풀기 어려운 이유를 설명할 수 있다.
- [ ] RAG의 세 단계(검색·증강·생성)와 두 시점(인덱싱·질의)을 말할 수 있다.
- [ ] PDF에서 꺼낸 글의 줄바꿈과 표가 흐트러지는 이유를 설명할 수 있다.
- [ ] 꺼낸 글을 눈으로 확인해야 하는 이유를 설명할 수 있다.
- [ ] 청크가 너무 작을 때와 너무 클 때 각각 무슨 일이 생기는지 말할 수 있다.
- [ ] 겹침이 무엇을 해결하는지 실제 청크를 예로 들어 설명할 수 있다.
- [ ]
separators의 순서가 뜻하는 바를 설명할 수 있다. - [ ] 두 문서를 따로 자르는 이유를 설명할 수 있다.
- [ ] 메타데이터를 자를 때 붙여야 하는 이유를 설명할 수 있다.
- [ ] 제목 줄 없이 시작하는 청크의
article에 직전 조항이 들어가는 이유를 설명할 수 있다. - [ ] 화면 출력을
if __name__ == "__main__":아래에 두는 이유를 설명할 수 있다.
한 줄 핵심
규정은 모델이 외우게 하지 않고, 문서에서 찾아 건넵니다. 무엇을 건넬 수 있는지는 문서를 어떻게 꺼내고 잘랐는지에서 정해집니다.