PDF 문서는 어떻게 처리하는가 — 청킹만 답하지 마라
← 전체 목차 · 이전: 장문서 청킹 — 왜 일률적으로 자르면 안 되나 · 다음: 문서 QA는 왜 파일명만 봐서는 안 되나
핵심 판단: PDF는 순수 텍스트 컨테이너가 아니라 레이아웃 컨테이너다. 안에는 목차, 머리말·꼬리말, 표, 이미지, 스캔 페이지, 2단 조판, 페이지를 넘나드는 내용이 동시에 들어 있다.
"텍스트로 변환하고 청킹해서 적재한다"만 답하면 가장 거친 단계에 머문 것이다. 완전한 답은 여섯 단계의 파이프라인이다.
PDF 유형 식별
→ 텍스트 / OCR / 비전 / 표 파싱
→ 문서 구조 복원
→ 의미 단위로 청킹
→ Chunk에 컨텍스트와 metadata 부여
→ 벡터 + 키워드 + 구조화 필터로 혼합 검색
→ Agent 도구 체인이 온디맨드로 페이지 읽기 / 표 추출 / 그림 보기
→ 인용 + 평가 클로즈드 루프로 결과 신뢰성 보장
1단계: 유형 식별 — 차별화된 처리 파이프라인
텍스트를 먼저 뽑는 것이 아니라 PDF가 어느 유형인지 먼저 판단한다.
| PDF 유형 | 처리 방식 |
|---|
| 원생 텍스트 | 문자와 좌표를 직접 파싱 |
| 스캔본 | 먼저 OCR |
| 도문 혼합(표 / 순서도 / 스크린샷 / 도표) | 문자 추출만으로는 안 되며, 필요 시 비전 모델 또는 전용 표 파싱 능력 도입 |
핵심 경고: 서로 다른 유형이 같은 거친 파이프라인을 타면 마지막에 반드시 정보를 잃는다.
2단계: 구조 복원 — 위치 자체가 정보다
핵심 관점: PDF에서 진짜 가치 있는 것은 문장만이 아니라 문장이 놓인 위치다.
| 문서 유형 | 반드시 지켜야 할 구조 정보 |
|---|
| 계약 문서 | 몇 장 / 몇 조 / 조항 계층 |
| 재무제표 | 소속 표 / 해당 연도 / 구체적 지표 |
| 학술 논문 | 현재 단락이 방법인지 실험인지 결론인지 |
metadata로 뽑아 이후 검색에 쓸 필드: 페이지 번호, 제목 계층, 단락, 각주, 표 번호, 그림 설명.
3단계: 의미 단위 청킹
고정 글자 수로 억지로 자르지 말고 의미 단위로 처리한다.
- 제목과 대응 단락은 되도록 함께 둔다.
- 표는 구조화 텍스트로 변환하거나 행·열 필드를 보존한다.
- 이미지와 도표는 검색 가능한 요약을 생성한다.
- 페이지를 넘나드는 단락은 이어 붙인다.
컨텍스트 보강(Context Enrichment): 각 Chunk에 짧은 컨텍스트 설명을 덧붙인다. 예를 들어 "본 문서 제3장의 지급 조항 설명"처럼 붙이면, 조각이 리콜된 뒤에도 원문 환경에서 이탈하지 않는다.
4단계: 다중 인덱스 아키텍처
| 인덱스 경로 | 무엇을 해결하나 | 커버 내용 |
|---|
| 벡터 인덱스 | 의미 유사 | 자연어 의미 매칭 |
| 키워드 인덱스 | 정확 매칭 | 조항 번호, 지표명, 제품 모델명, 고유명사 |
| 구조화 필드 | 필터링 | 문서 ID, 페이지, 장·절, 버전, 권한, 시간 |
결론: PDF RAG는 단일 경로 검색으로 안정적으로 작동하는 경우가 드물며, 계약·재무보고·매뉴얼 같은 고정밀 시나리오에서는 혼합 검색이 더 믿을 만하다.
5단계: PDF 능력을 Agent 도구 세트로 캡슐화
원칙: 문서 전체를 한 번에 컨텍스트에 밀어 넣지 말고 필요할 때 호출할 수 있는 도구로 만든다.
| 도구명 | 역할 |
|---|
search_pdf | 관련 조각 검색 |
read_page | 지정 페이지 읽기 |
extract_table | 표 추출 |
analyze_chart | 도표 분석 |
quote_source | 인용 반환 |
지능형 라우팅 전략
| 질문 유형 | 라우팅 대상 |
|---|
| 단순 사실 | 검색으로 |
| 장·절을 넘나드는 비교 | 먼저 읽기 경로를 계획 |
| 표 / 도표 | 전용 도구 호출 |
6단계: 소급 가능성과 다차원 평가
소급 가능성: 답변에 페이지, 장·절, 원문 인용 범위를 담아 사용자가 되짚어 볼 수 있게 하는 것이 좋다.
평가는 최종 답만 봐서는 안 된다
| 평가 차원 | 점검 항목 |
|---|
| 리콜 조각 적중 | 검색된 조각이 맞는가 |
| 페이지 위치 정확 | 인용 위치가 정확한가 |
| 표 필드 파싱 | 행·열이 올바로 파싱되었는가 |
| OCR 누락 없음 | 스캔본 문자가 온전한가 |
여기에 한 항목 더: 도표 정보가 정말로 이해되었는가.
그렇지 않으면 모델의 답이 진짜처럼 보여도 잘못된 조각 위에서 지어낸 것일 수 있다.
핵심 통찰
- PDF는 "레이아웃"이지 "텍스트"가 아니며, 레이아웃을 잃는 것은 의미를 잃는 것이다 — 같은 문장이 제3조에 있는 것과 부록에 있는 것은 의미가 완전히 다르다. PDF를 순수 텍스트 흐름으로 처리하는 모든 방안은 원천에서 손실 압축을 하는 것이다.
- 위치 정보는 metadata로 명시적으로 모델링해야지 벡터가 기억해 주기를 기대하면 안 된다 — 페이지, 장·절, 표 번호는 필터링 가능한 필드이지 embedding할 수 있는 의미가 아니다. 벡터에 넣으면 검색도 부정확하고 필터링도 안 되므로 별도의 구조화 인덱스를 만들어야 한다.
- "하나의 파이프라인으로 천하를 통일"하는 것이 PDF RAG의 가장 흔한 아키텍처 오류다 — 원생 텍스트, 스캔본, 도문 혼합 세 유형의 비용과 실패 모드가 완전히 다르다. 먼저 분류하고 나서 분류별로 흘려보내는 편이 하류에서 모델을 쌓는 것보다 훨씬 싸다.
- 청킹의 올바른 입도는 의미 단위이지 token 수가 아니다 — 고정 글자 수 청킹은 제목과 본문을 흩어놓고, 표를 허리에서 자르고, 페이지를 넘나드는 단락을 반으로 나눈다. Chunk의 경계는 문서 구조가 결정해야 한다.
- 컨텍스트 보강은 저비용 고수익 단계다 — 각 Chunk에 "나는 누구이고 어디서 왔는가" 한 문장을 더하면 리콜 후 문맥 이탈로 인한 환각이 뚜렷이 줄어드는데, 비용은 수십 Token뿐이다.
- 문서 능력을 도구로 만들고 컨텍스트에 밀어 넣지 말 것 — 이것이 RAG에서 Agentic RAG로 넘어가는 분수령이다. 모델이 스스로 "한 번 검색할지", "12페이지로 넘길지", "이 표를 뽑을지"를 결정하게 하는 편이 200페이지를 한 번에 먹이는 것보다 절약되고 정확하다.
- 평가는 중간 고리까지 관통해야 한다 — 최종 답만 보는 평가로는 "검색이 틀렸는데 답을 둥글게 잘한 것"과 "검색이 맞고 답도 맞은 것"을 구분할 수 없다. 리콜 적중률, 페이지 정확률, 표 파싱 정확률, OCR 문자 정확률을 각각 따로 채점해야 한다.
- 고정밀 시나리오는 일률적으로 혼합 검색을 쓸 것 — 계약의 조항 번호, 재무보고의 지표명, 매뉴얼의 제품 모델명은 전부 벡터 검색의 구조적 사각지대이므로(고유명사의 의미 유사도는 신뢰할 수 없다) 키워드 인덱스로 받쳐야 한다.
엔지니어링 실전 Tips
- 권한 필드를 구조화 인덱스에 넣을 것: 멀티테넌트·내부 문서 시나리오에서는 검색 층에서 권한으로 필터링할 수 있어야 하며, 생성 후에 막아서는 안 된다(문서 04 참조).
- 버전 필드도 마찬가지로 중요하다: 계약과 매뉴얼은 다중 버전이 흔하며, 구 버전 조항을 검색하는 것은 은밀하면서 치명적인 오류다.
- 표는 행·열 필드를 우선 보존할 것: 평탄한 텍스트 한 단락으로 바꾸면 "이 숫자가 어느 행 어느 열에 속하는지"를 잃어 재무 문답이 거의 반드시 틀린다.
- 도표는 이미지만 저장하지 말 것: 검색 가능한 문자 요약을 생성하지 않으면 벡터 라이브러리에서는 존재하지 않는 것과 같다.
- 페이지를 넘나드는 단락 이어 붙이기는 스캔본과 2단 조판의 고빈도 함정이다. 청킹 전에 레이아웃 재배열을 먼저 할 것.
- 인용 범위는 페이지와 장·절까지 정확히: 사용자가 신뢰를 형성하는 유일한 손잡이이자 bad case 원인 규명의 입구다.
- 구간별 평가셋을 구축할 것: 하나의 case에 "올바른 페이지 / 올바른 조각 / 올바른 표 필드"를 동시에 라벨링해야 검색 문제인지 생성 문제인지 특정할 수 있다.
- 더 파고들 방향: 레이아웃 분석(Layout Analysis) 모델(2단 조판, 페이지를 넘나드는 표의 자동 복원), 표 문답(TableQA —
extract_table의 출력을 구조화 쿼리에 연결하는 편이 LLM이 표를 직접 읽는 것보다 믿을 만하다), Agentic RAG의 계획 층(장·절을 넘나드는 비교 시 읽기 경로를 먼저 계획하는 다단계 검색/ReAct 설계).