# Task-511 완료 보고서: Docling 문서 파싱 도입

**팀**: dev2 (오딘) | **일시**: 2026-03-13

---

## SCQA

**S**: InsuRo 서버의 `ai_parser.py`가 pdfplumber만으로 PDF를 파싱하고 있어 텍스트 PDF는 정상 추출되나, 표 구조 보존과 스캔 PDF/다양한 포맷 지원이 불가하다.

**C**: Docling(v2.79.0)을 도입하여 `/home/jay/workspace/libs/doc_parser.py` 공통 모듈을 구현하고, `ai_parser.py`를 Docling 기반으로 교체(fallback 유지)했다. 금소법 PDF(35페이지) 대상 비교 테스트에서 Docling이 7% 더 많은 텍스트를 추출하고 항 번호 감지 21% 우세하나, 11.68배 느린 것으로 확인되었다.

**Q**: Docling 도입으로 파싱 품질이 실질적으로 향상되었는가, 그리고 속도 저하를 감수할 만한가?

**A**: 텍스트 추출량 +7%(64,833 vs 60,310자), 항 번호 감지 +21%(631 vs 519건), 조항 131개 동일 감지로 품질 향상 확인. 속도(47.7초 vs 4.1초)는 느리지만 fallback으로 안정성 확보. 표 구조 보존 기능은 금소법 PDF에 표가 없어 실전 검증 미완료 — 약관 PDF로 후속 테스트 필요. 테스트 34건 전체 통과, pyright 에러 0건.

---

## 생성/수정 파일 목록

- `/home/jay/workspace/libs/doc_parser.py` — Docling 기반 문서 파싱 공통 모듈 (ParseResult, parse_pdf, parse_document)
- `/home/jay/projects/InsuRo/server/ai_parser.py` — Docling 통합 + pdfplumber fallback (type: ignore 주석 추가)
- `/home/jay/workspace/libs/tests/test_doc_parser.py` — doc_parser 단위 테스트 10건 (기존)
- `/home/jay/workspace/libs/tests/test_comparison.py` — pdfplumber vs Docling 비교 테스트 13건 (신규)
- `/home/jay/workspace/libs/tests/test_ai_parser_fallback.py` — ai_parser fallback + 유틸리티 테스트 11건 (신규)

---

## pdfplumber vs Docling 비교 결과 (금소법 PDF, 35페이지)

### 1. 텍스트 추출 정확도

- pdfplumber: 60,310자 / Docling: 64,833자 (차이 6.98%, Docling +4,523자)
- 필수 키워드 5종 중 4종 양쪽 동일 검출 (금융소비자, 금융상품, 금융상품판매업자, 손해배상)
- "청약철회" 양쪽 미검출 — PDF 원본에서 "청약의 철회"로 분리 표기 가능성
- Docling이 법률 본문 구조(장/절/조)를 더 깔끔하게 정리 (불필요 헤더 제거)

### 2. 표(table) 구조 보존

- 양쪽 모두 테이블 0건 감지 — 금소법 PDF에 표 구조 없음
- 테이블 추출 기능 실전 검증 미완료 (표가 포함된 약관 PDF로 후속 테스트 필요)

### 3. 조항 번호 정확성

- pdfplumber: unique 조항 131개 / Docling: unique 조항 131개 (동일)
- pdfplumber: 줄바꿈 아티팩트 발생 ("제\n3조" 등) / Docling: 공백 아티팩트 ("제 3조" 등)
- 정규화 후 차집합: 0건 (동일)

### 4. 특수문자 처리

- 「」: 양쪽 동일 183회, 쌍 일치 True
- ㆍ: 양쪽 동일 237회
- ①②③: 양쪽 동일 51/53/36회
- 7개 특수문자 중 6개 양쪽 동일 커버 (·(중점)만 미발견 — PDF 원본 미포함)

### 5. 처리 속도

- pdfplumber: 4.085초 (페이지당 0.117초)
- Docling: 47.690초 (페이지당 1.363초)
- Docling이 11.68배 느림 (CPU 모드, 모델 로딩 포함)

### 6. 항 번호 감지

- pdfplumber: 519건 / Docling: 631건 (**Docling +21.6%**)
- Docling이 원문자 항 번호를 더 정확하게 보존

---

## 테스트 결과

### doc_parser 단위 테스트: 10/10 통과 (408초)
- ParseResult 인스턴스 생성, 필드 기본값
- parse_pdf: 반환 타입, 텍스트 비어있지 않음, 페이지 리스트, 메타데이터, 잘못된 입력 예외
- parse_document: PDF 감지, 미지원 확장자 예외, 대소문자 무관

### 비교 테스트: 13/13 통과 (57초)
- 텍스트 길이, 키워드 검출, 샘플 비교
- 테이블 수/구조/셀 내용
- 조항 번호, 항 번호
- 특수문자, 유니코드 정규화
- 처리 속도, 페이지당 속도
- 종합 요약

### fallback 테스트: 11/11 통과 (20초)
- Docling 정상 경로: 텍스트 추출, 한국어 포함 확인
- Docling 실패 fallback: RuntimeError/Exception/ValueError 3종 mock → pdfplumber 전환 성공
- _table_to_markdown: 기본 구조, 구분선, 빈 헤더, 열 패딩, 인덱스, 행 없는 경우
- 빈 bytes 예외: 2건 통과

### pyright: 0 errors, 0 warnings (4개 파일)
### 전체: 34건 통과, 0건 실패

---

## 발견 이슈 (3건)

1. **[속도] Docling CPU 모드 11.68배 느림** — 35페이지 PDF에 47.7초 소요. 실시간 요청에서 부담될 수 있음. 캐싱 또는 비동기 처리 검토 권장. GPU 환경 시 개선 예상. fallback이 있어 운영 안정성은 확보.
2. **[테이블 미검증] 금소법 PDF에 표 없음** — Docling의 핵심 장점인 테이블 추출이 실전 검증 불가. 보험 약관 PDF 등 표 포함 문서로 후속 테스트 필요.
3. **[키워드] "청약철회" 양쪽 미검출** — PDF 원본에 "청약의 철회"로 분리 표기되어 있을 가능성. 키워드 검색 시 조사 포함/분리 패턴 고려 필요.

---

## 비고

- Docling 첫 실행 시 모델 다운로드 포함하여 약 7분 소요 (이후 캐시로 ~1분)
- GPU 없이 CPU 모드로 동작 확인 (AcceleratorDevice.CPU)
- OCR은 비활성화 (CPU 환경 속도 최적화). 스캔 PDF 지원 시 OCR 활성화 필요
- 보험 약관 PDF 샘플을 찾지 못해 금소법 PDF로만 테스트 수행
- Docling `generate_table_images` 관련 DeprecationWarning 발생 — 기능 영향 없으나 향후 업데이트 시 대응 필요
