5.3 KiB
5.3 KiB
아키텍처
기본 원칙
- 1차 목표는 UI가 아니라 안정적인 CLI/라이브러리 변환 엔진이다.
- PDF parser는
Marker를 기본 엔진으로 사용한다. - 변환 파이프라인은 Marker 출력에 직접 결합하지 않고 내부 중간 표현(Document Model)을 거친다.
- 출력은 Obsidian 친화 Markdown을 우선하되, 표준 Markdown과의 호환성을 가능한 한 유지한다.
- 긴 문서는 20페이지 단위 chunk로 처리하고, chunk별 상태/캐시/로그를 남겨 재시도가 가능해야 한다.
목표 디렉토리 구조
venv/ # 가상 환경
samples/ # 품질 검증용 샘플 PDF
src/
├── converter/ # PDF to Markdown 변환 핵심
│ ├── engines/ # Marker 및 향후 parser adapter
│ ├── model/ # 내부 Document Model
│ ├── renderers/ # Obsidian Markdown 출력
│ ├── indexer/ # index 파일 생성
│ └── diagnostics/ # 로그, 경고, 변환 상태
├── ui/ # 2차 목표: PyQt UI 컴포넌트
└── utils/ # 유틸리티 + 헬퍼
주요 컴포넌트
Converter Core
- PDF 입력, 사전 분석, chunk 분할, parser 실행, 중간 표현 생성, 출력 렌더링을 조율한다.
- UI와 분리되어 CLI와 테스트에서 직접 호출 가능해야 한다.
Parser Engine Adapter
- 1차 구현은
MarkerEngine만 대상으로 한다. - 향후
Nougat,Docling,PyMuPDF등 다른 엔진을 붙일 수 있도록 adapter 경계를 둔다. - parser adapter는 원본 parser 결과와 프로젝트 내부 Document Model 사이의 변환을 담당한다.
Document Model
내부 중간 표현은 최소한 다음 정보를 담아야 한다.
- document id, title, source path, output slug
- chunk id, page range, conversion status
- block id, block type, text/content
- heading level, paragraph, list, quote, equation, table, figure
- source page, bbox, confidence, parser metadata
- image/table asset path
- warnings/errors
Obsidian Renderer
- Document Model을 Obsidian 친화 Markdown 파일로 렌더링한다.
- 수식은
$ ... $,$$ ... $$형식을 지킨다. - 이미지는 Obsidian 내부 링크 또는 프로젝트에서 정한 표준 이미지 링크 형식으로 연결한다.
- 복잡한 표는 Markdown table에 억지로 맞추지 않고 HTML table 또는 별도 CSV 링크를 허용한다.
Index Builder
- 단순 목차가 아니라 AI Agent가 문서 내부로 진입하기 위한 탐색 index를 만든다.
- heading, 주요 문단, 표, 그림, 수식에 대해 Markdown 파일, heading, line 위치, 원본 page 정보를 연결한다.
- 가능한 경우 block id와 bbox를 metadata에 보존한다.
Diagnostics & Recovery
- 변환 설정, Marker 버전, GPU/CPU 사용 여부, 처리 시간, 경고, 실패 chunk를 기록한다.
- 완료된 chunk는 재사용하고 실패한 chunk만 재시도할 수 있어야 한다.
- 원본 Marker 결과와 내부 Document Model snapshot은 디버깅 가능한 형태로 보존한다.
프로그램 흐름
PDF 파일 입력
-> 사전 분석: 페이지 수, 텍스트 포함 여부, 스캔 여부, 예상 chunk 수 확인
-> 20페이지 단위 chunk 분할
-> chunk별 Marker 변환
-> Marker 결과를 내부 Document Model로 변환
-> reading order, paragraph stitching, semantic mapping 보정
-> 이미지/표/수식 asset 정리
-> Obsidian 친화 Markdown 렌더링
-> index 파일 생성
-> metadata/log 저장
상태 관리
- 문서 단위 상태와 chunk 단위 상태를 분리한다.
- chunk 상태는
pending,running,completed,error,skipped같은 값으로 관리한다. - 변환 중 실패가 발생해도 완료된 chunk 결과는 유지한다.
- 최종 index는 chunk 결과를 기준으로 재생성 가능해야 한다.
변환 결과 출력 구조
output/
└── document-slug/
├── document-slug_index.md
├── document-slug_001.md
├── document-slug_002.md
├── document-slug_003.md
├── images/
│ ├── page-001_fig-001.png
│ └── page-012_fig-003.png
├── tables/
│ ├── page-005_table-001.csv
│ └── page-008_table-002.html
└── metadata/
├── document.json
├── chunks.json
├── parser-output/
└── conversion.log
Obsidian 출력 규칙
- 파일명은 Windows와 Obsidian에서 안전한 slug 기반 이름을 사용한다.
- 원본 PDF 파일명은 metadata에 보존한다.
- heading은 Obsidian 내부 링크 대상이 될 수 있도록 안정적으로 생성한다.
- 이미지는 상대 경로 또는 Obsidian 내부 링크 중 프로젝트 표준을 정해 일관되게 사용한다.
- index 파일은 각 chunk 파일과 주요 heading으로 이동할 수 있어야 한다.
- 수식은 Obsidian에서 렌더링 가능한 Markdown math 문법을 사용한다.
검증 전략
- TDD를 기본으로 한다.
- 전체 Markdown snapshot 비교보다 부분 품질 검증을 우선한다.
- 샘플 PDF별로 heading 추출, 수식 block 수, 이미지 파일 생성, 표 구조 보존, index 링크 생성, 예외 발생 여부를 확인한다.
- Windows native, 한글 경로, 긴 파일명, 8GB VRAM 제한을 검증 항목에 포함한다.