본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 18. 23:49

RAG를 위한 표 구조 보존 PDF 파서 구축 및 그 중요성

요약

기존 RAG 파이프라인의 고질적인 문제인 PDF 내 표 구조 및 문맥 손실을 해결하기 위한 새로운 문서 정규화 엔진 DOCNEST를 소개합니다. DOCNEST는 표를 JSON 형식으로 보존하고 문서를 섹션 단위로 구조화하여, 단순 청킹 방식보다 정확한 데이터 추출과 계층적 쿼리를 가능하게 합니다.

핵심 포인트

  • 단순 텍ext 청킹은 표 데이터와 문맥(헤더, 캡션 등)을 파괴하여 RAG 성능을 저하시킴
  • DOCNEST는 문서를 섹션 단위로 정규화하고 표를 구조화된 JSON으로 변환하여 데이터 무결성을 유지함
  • Unified Document Format(.udf)을 통해 독립적이고 휴대 가능한 지식 베이스 구축 가능
  • 사전 계산된 요약부터 BM25, 코사인 유사도 등을 활용한 5계층 쿼리 엔진으로 효율적인 답변 제공

모든 RAG (Retrieval-Augmented Generation) 튜토리얼은 동일한 파이프라인을 보여줍니다: PDF → 텍스트 추출 → 512 토큰마다 분할 → 임베딩 (Embedding) → 저장 → 쿼리 (Query). 블로그 포스트에는 잘 작동합니다. 하지만 구조화된 데이터에 대해서는 완전히 무너집니다.

아무도 말하지 않는 문제
재무 보고서를 예로 들어보겠습니다. 여기 매출 표가 있습니다:

지역 | Q2 매출 | Q3 매출 | 변동
유럽 | 38.1% | 45.2% | +7.1pp
아시아 | 29.3% | 41.7% | +12.4pp
미주 | n/a | 52.1% | —

맹목적인 청킹 (Chunking) 이후, 당신의 LLM (Large Language Model)은 다음과 같은 내용을 받게 됩니다: "45.2% Q3 유럽 38.1% Q2 유럽 41.7% Q3 아시아 29.3%"
열 헤더도, 캡션도, 문맥도 없는 숫자들뿐입니다. "어느 지역이 가장 많이 성장했나요?"라고 물으면, 답변이 아닌 대략적인 추측을 얻게 됩니다.

동일한 문제가 다음 상황에서도 발생합니다:

  • 법률 계약서 (문장 중간에서 조항이 분할됨)
  • API 문서 (코드 예시가 설명과 분리됨)
  • 연구 논문 (그림 캡션이 분석 내용과 단절됨)

이것은 검색 (Retrieval)의 문제가 아닙니다. 인제스션 (Ingestion, 데이터 수집/주입)의 문제입니다.

내가 만든 것
지난 몇 달 동안 저는 콘텐츠를 건드리기 전에 구조를 먼저 읽는 문서 정규화 엔진인 DOCNEST를 구축하는 데 시간을 보냈습니다.

  • 청크 (Chunk) 대신, 모든 헤딩 (Heading)은 탐색 가능한 섹션 (§section)이 됩니다.
  • 모든 표는 구조화된 JSON 형식으로 보존됩니다.
  • 모든 섹션은 인제스션 시점에 한 번 계산되어 한 문장 요약과 키워드 인덱스를 갖게 됩니다.
  • 출력물은 .udf 파일 (Unified Document Format)로, 독립적이고 휴대 가능한 지식 베이스입니다.
from docnest.parsers.pymupdf_pdf import PyMuPDFParser
from docnest.normalizer import SectionNormaliser
from docnest.writer import UDFWriter
from docnest.reader import UDFIndex

# 파싱(Parse) → 정규화(Normalise) → 저장 (API 키 불필요)
raw = PyMuPDFParser().parse("report.pdf")
doc = SectionNormaliser().normalise(raw)
UDFWriter().write(doc, "report.udf")

# 쿼리(Query)
idx = UDFIndex.load("report.udf")
result = idx.query(
    "Which region had the highest Q3 growth?",
    llm_provider = "groq",
    llm_model = "llama-3.3-70b-versatile",
    llm_api_key = "gsk_..." # console.groq.com에서 무료로 제공
)
print(result.answer)
# "Asia grew the most at +12.4pp"
print(result)

layer_used ) # 1 — index에서 답변됨, 0 LLM 토큰 사용

5계층 쿼리 엔진 (The five-layer query engine)
제가 가장 자랑스럽게 생각하는 부분은 쿼리가 해결되는 방식입니다:

계층 (Layer)메커니즘 (Mechanism)토큰 (Tokens)작동 시점 (When it fires)
0사전 계산됨 (요약, 주요 수치)0직접 일치 (Direct match)
1BM25 + 코사인 유사도 (cosine) → 섹션 (§section)으로 이동0강력한 키워드 일치 (Strong keyword match)
2섹션 범위 LLM (Section-scoped LLM)~300해석 필요 (Needs interpretation)
3다중 섹션 합성 (Multi-section synthesis)~900섹션 간 추론 (Cross-section reasoning)
4전체 문서 폴백 (Full document fallback)~4000다른 방법이 작동하지 않을 때 (Nothing else worked)

0계층과 1계층은 LLM 토큰을 전혀 사용하지 않고도 실제 질문의 약 70%를 답변합니다. 질문이 진정으로 필요로 할 때만 연산 비용을 지불하게 됩니다.

대용량 PDF 처리 방식
Docling (ML 품질의 PDF 파서)은 전체 모델을 RAM에 로드합니다. 600페이지 분량의 PDF는 대부분의 기기에서 메모리를 고갈시킬 것입니다. DOCNEST는 자동 페이지 청킹 (automatic page chunking)을 통해 이 문제를 해결합니다:

from docnest.parsers.pdf import DoclingPDFParser
# 30페이지 이상의 PDF를 자동 청킹 — 피크 RAM = 파일 전체가 아닌 하나의 청크 단위
raw = DoclingPDFParser().parse("600-page-annual-report.pdf")

# 또는 명시적으로 조정
raw = DoclingPDFParser(chunk_pages=10).parse("report.pdf") # 낮은 RAM 사용
raw = DoclingPDFParser(chunk_pages=50).parse("report.pdf") # 높은 RAM 사용

PyMuPDF가 PDF를 N페이지 단위의 임시 파일로 분할합니다. Docling은 각 청크를 완전한 ML 품질로 처리합니다. 이후 섹션들이 병합됩니다. 출력 결과는 파일을 한 번에 처리했을 때와 동일합니다.

실제 문서에서의 정확도
PyMuPDF와 Groq의 무료 티어를 사용하여 500페이지 분량의 오픈 소스 영양학 교과서를 대상으로 25개의 질문을 실행했습니다:

  • 기본 사실 (칼로리, 영양소): 5/5
  • 영양소 상세 정보 (식이섬유, 혈당 지수): 5/5
  • 미량 영양소 (비타민, 미네랄): 4/5
  • 어려운 합성 (BMR, 오메가-3, 항산화제): 5/5
  • 예외 케이스 (환각, 표, 범위를 벗어난 질문): 5/5

24/25 (96%) — 단 하나의 실패는 텍스트 파서가 내용을 추출하지 못한 표로만 구성된 페이지였습니다 (해당 페이지의 경우 DoclingPDFParser로 전환하십시오).

직접 시도해 보세요: pip install docnest-ai

GitHub: https://github.com/tailorgunjan93/docnest
PyPI: https://pypi.org/project/docnest-ai

이 라이브러리는 PDF (Docling + PyMuPDF), DOCX, XLSX, HTML 및 Markdown을 지원합니다. LLM 제공업체로는 Groq, OpenAI, Ollama, Anthropic, Google, Mistral 등이 있습니다. 벡터 백엔드(Vector backends)로는 numpy (기본값), FAISS, ChromaDB를 지원합니다. 저는 이 프로젝트를 공개적으로(in the open) 구축하고 있습니다. 만약 여러분의 RAG 파이프라인(pipeline)에서 이러한 표 구조 문제를 겪으셨다면, 무엇이 문제였는지 진심으로 듣고 싶습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0