실무 Multi-Agent 오케스트레이션 12장 · 문서 로딩과 청킹 3 / 8 ← 이전목차다음 → TechLead Cro

12장. 문서 로딩과 청킹

PDF에서 텍스트 꺼내기 — 눈에 보이는 대로 나오지 않는다

한 줄 요약

PDF는 글이 종이 위 어디에 찍히는지를 저장하는 형식입니다. 그래서 글을 꺼내면 줄이 엉뚱한 데서 끊기고 표가 흩어집니다. 꺼낸 결과는 반드시 눈으로 확인합니다. 이 과정에서는 pypdf 라이브러리로 꺼냅니다.


1. PDF는 글을 어떻게 담는가

워드 문서나 웹 페이지는 "여기가 제목, 여기가 문단, 여기가 표"라는 구조를 가지고 있습니다. PDF는 그렇지 않습니다. PDF 안에 있는 것은 대략 이런 정보입니다.

(72, 540) 위치에 "제2조 (반품 사유별 기준)"을 찍어라
(72, 520) 위치에 "반품 사유"를 찍어라
(180, 520) 위치에 "신청 가능 기간"을 찍어라

사람 눈에는 표로 보이지만 파일 안에는 표라는 정보가 없습니다. 글자와 좌표뿐입니다. 글을 꺼내는 라이브러리는 좌표를 보고 "같은 줄이겠거니, 다음 줄이겠거니" 짐작해 이어 붙입니다.


2. pypdf로 꺼내기

from pypdf import PdfReader

reader = PdfReader(pdf_path)
text = "\n".join(page.extract_text() for page in reader.pages)
코드 하는 일
PdfReader(pdf_path) PDF 파일을 연다
reader.pages 쪽의 목록. len(reader.pages)가 쪽수
page.extract_text() 그 쪽의 글을 문자열로 꺼낸다
"\n".join(...) 쪽마다 꺼낸 글을 줄바꿈으로 이어 하나로 만든다

3. 꺼낸 글에서 보이는 것

하루마켓 멤버십 정책에서 꺼낸 글의 일부입니다. 「따라하기」에서 직접 볼 수 있습니다.

제1조 (등급 체계와 산정 기준)
① 하루클럽 등급은 일반, 실버, 골드, VIP 4단계로 운영한다. ② 등급은 최근 6개월 실결제 금액(취소·환불 제외)을 기준으로
매월 1일 산정하며, 산정된 등급은 해당 월 말일까지 유지된다. ③ 실결제 금액에는 적립금·쿠폰 사용분이 포함되지 않는다.
[표 1] 등급 산정 기준 (최근 6개월 실결제액)
등급 산정 기준 산정 주기
일반 가입 시 기본 등급
매월 1일
실버 10만원 이상
골드 30만원 이상
VIP 60만원 이상

네 가지가 눈에 띕니다.

줄바꿈이 문장의 끝이 아닙니다. "기준으로" 뒤에서 줄이 바뀌었습니다. 문장이 끝나서가 아니라 종이의 오른쪽 끝에 닿았기 때문입니다. 다른 곳에서는 "적립되지 않는"과 "다." 사이에서 끊기기도 합니다.

표의 칸 구분이 사라졌습니다. 등급 산정 기준 산정 주기가 제목 줄인데, 어디까지가 한 칸인지 빈칸만으로는 알 수 없습니다.

표의 줄 순서가 섞였습니다. 매월 1일이 혼자 한 줄로 "일반"과 "실버" 사이에 끼어 있습니다. 제목 줄의 세 번째 칸인 "산정 주기"에 들어갈 내용인데, 어느 등급 줄에도 붙지 못하고 따로 떨어졌습니다. 글자의 위치만 보고 줄을 짐작하다 보니 생긴 일입니다.

문단 사이의 빈 줄이 없습니다. 조항과 조항 사이에 빈 줄이 하나도 없습니다. 이 점은 다음 절의 자르는 방법에 영향을 줍니다.


4. 꺼내지 못하는 경우

PDF의 상태 꺼낸 결과
글자가 글자로 들어 있다 (우리 문서) 글이 나온다. 줄과 표는 위처럼 흐트러질 수 있다
종이를 스캔한 이미지다 거의 아무것도 나오지 않는다. 글자가 아니라 그림이기 때문이다
2단으로 짠 문서다 왼쪽 단과 오른쪽 단이 섞일 수 있다

스캔한 문서에서 글을 얻으려면 이미지에서 글자를 읽어 내는 OCR(Optical Character Recognition, 광학 문자 인식) 이 따로 필요합니다. pypdf는 그 일을 하지 않습니다.


5. 꺼낸 글은 눈으로 확인한다

글이 깨진 채로 다음 단계로 넘어가면 오류가 나지 않습니다. 검색도 되고 답도 나옵니다. 다만 조용히 틀립니다. 그래서 문서를 새로 들일 때마다 가장 먼저 할 일은 이것입니다.

  • 쪽수와 글자 수가 상식에 맞는지 봅니다. 세 쪽짜리 문서에서 50자가 나왔다면 스캔본입니다.
  • 앞부분 몇 줄을 직접 읽어 봅니다. 글자가 깨지지 않았는지, 순서가 맞는지.
  • 표가 있는 자리를 찾아 읽어 봅니다. 표가 가장 잘 흐트러집니다.

「따라하기」의 코드는 문서를 읽을 때마다 쪽수와 글자 수를 출력합니다.

print(f"■ 로딩: {pdf_path.name} — {len(reader.pages)}쪽, {len(text):,}자")

RAG의 답이 이상할 때 모델부터 의심하기 쉽습니다. 먼저 볼 곳은 꺼낸 글입니다.


핵심 정리

  • PDF는 구조가 아니라 글자의 위치를 저장합니다. 표라는 정보는 파일 안에 없습니다.
  • PdfReader로 열고 page.extract_text()로 쪽마다 글을 꺼냅니다.
  • 꺼낸 글은 줄바꿈이 문장의 끝이 아니고, 표의 칸과 줄 순서가 흐트러질 수 있습니다.
  • 스캔한 PDF에서는 글이 나오지 않습니다. OCR이 따로 필요합니다.
  • 꺼낸 결과는 반드시 눈으로 확인합니다. 깨져도 오류가 나지 않기 때문입니다.
← 이전 절RAG의 두 시점 — 미리 해 두는 일과 질문마다 하는 일다음 절 →청킹 — 어디서, 얼마나 크게 자를 것인가
오명운 · macro@prag-ai.com