PDF를 vault 잉게스트 가능한 MD로 변환해 Clippings/에 투입한다. 페이지별 텍스트 밀도를 측정해 변환 전략(S2 pymupdf4llm / S6 로컬 OCR / S4 Claude 비전 전사)을 제안하고 사용자 확인 후 실행한다. wiki화는 하지 않는다 — 기존 vault-ingest가 이어받는다. 커밋 불가 문서(고객사·개인)는 vault 밖 변환 모드로 변환만 수행한다. 근거: projects/pdf2md-bench/outputs/verdict-report.md
Scanned 9/3/2026
Install to Claude Code
npx -y skills add lemoncloud-io/2nd-brain --skill pdf2md-ingest --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Pdf2md Ingest?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lemoncloud-io-pdf2md-ingest)More formats (shields.io, HTML) on the badges page.
---
name: pdf2md-ingest
description: >
PDF를 vault 잉게스트 가능한 MD로 변환해 Clippings/에 투입한다. 페이지별 텍스트
밀도를 측정해 변환 전략(S2 pymupdf4llm / S6 로컬 OCR / S4 Claude 비전 전사)을
제안하고 사용자 확인 후 실행한다. wiki화는 하지 않는다 — 기존 vault-ingest가
이어받는다. 커밋 불가 문서(고객사·개인)는 vault 밖 변환 모드로 변환만 수행한다.
근거: projects/pdf2md-bench/outputs/verdict-report.md
origin: lemoncloud-io/knowledge@01f358b:projects/second-brain/config/skills/pdf2md-ingest/SKILL.md
---
# pdf2md-ingest (PDF → Clippings MD)
## 언제 사용하는가
- 사용자가 "이 PDF 잉게스트해줘" / "PDF를 vault에 넣어줘"라고 요청할 때
- PDF 내용을 wiki 지식으로 만들고 싶은데 원본이 md가 아닐 때
이 스킬은 **변환과 Clippings 투입까지만** 담당한다. 개념 추출·wiki 생성·커밋·PR은
하지 않는다 (기존 vault-ingest / vault-ingest-claude 몫).
## 전제 도구 (없으면 안내 후 중단 — 자동 설치 금지)
| 도구 | 확인 | 설치 안내 |
|---|---|---|
| poppler (`pdfinfo`·`pdftotext`·`pdftoppm`) | `command -v pdftoppm` | `brew install poppler` |
| uv (S2 — pymupdf4llm 자동 준비) | `command -v uv` | `brew install uv` |
| Node 18+ (S6) | `node --version` | nvm 등으로 설치 |
| S6 런타임 (1회) | `ls ~/.cache/ppu-paddle-ocr-runtime/node_modules/ppu-paddle-ocr` | 아래 셋업 절 |
**S6 런타임 1회 셋업** (~330MB, vault 밖):
```bash
mkdir -p ~/.cache/ppu-paddle-ocr-runtime && cd ~/.cache/ppu-paddle-ocr-runtime
npm init -y && npm install ppu-paddle-ocr onnxruntime-node
```
**스킬 발견용 설치** (머신별 1회): `$VAULT_DIR/.claude/skills/`에 심링크
```bash
mkdir -p "$VAULT_DIR/.claude/skills"
ln -s "$VAULT_DIR/projects/second-brain/config/skills/pdf2md-ingest" \
"$VAULT_DIR/.claude/skills/pdf2md-ingest"
```
## 절차
### 0. 게이트 (변환 전 — 하나라도 실패하면 아무것도 쓰지 않고 보고)
1. **커밋 가능성**: 사용자에게 확인 — "이 PDF는 팀 공유 vault에 커밋 가능한 문서인가?"
고객사·개인 문서면 정식 잉게스트(§3 산출·마무리)는 중단한다. 변환 자체가 필요한
경우에는 § vault 밖 변환 모드를 제안하고, 사용자가 그 모드를 명시적으로 선택한
경우에만 진행한다.
2. **VAULT_DIR resolve**: 사용자 명시값 > vault 구조(`VAULT_RULES.md`, `wiki/`, `raw/`,
`Clippings/`, `templates/`)가 확인된 현재 루트 > 그 외에는 사용자에게 질문.
`~/knowledge` 조용한 fallback 금지. 절대경로로 resolve.
3. **중복**: `raw/pdf/<원본파일명>.pdf`가 이미 있으면 중단·보고 (raw/는 append-only).
### 1. 밀도 측정 → 전략 제안
```bash
SKILL_DIR="$VAULT_DIR/projects/second-brain/config/skills/pdf2md-ingest"
"$SKILL_DIR/scripts/measure-density.sh" <pdf>
```
출력의 `image-dominant: <n>/<pages>`로 제안을 정한다 (기준: 페이지당 공백 제거
300자 미만 = image-dominant, pdf2md-bench §5.2 실측 기반):
| 밀도 프로파일 | 제안 | 근거 (pdf2md-bench 실측) |
|---|---|---|
| image-dominant 0페이지 | **S2** | 텍스트 문서 T1·T2 만점, 무료·초 단위 |
| image-dominant ≥1페이지 | **S6 기본**, S4 옵션 병기 | 둘 다 QA 15/15. S6=무료·초 단위 / S4=구조·서술 우위, 약 0.045 USD/페이지·수 분 |
| 전 페이지 텍스트 0자 (스캔) | **S6 기본**, S4 옵션 | 텍스트 추출 계열 원리적 불가 |
측정 결과(총 페이지·image-dominant 수)와 제안·예상 비용을 사용자에게 보여주고
**확인받은 뒤** 변환한다. 표지·간지만 image-dominant로 걸린 경우(본문은 전부
텍스트)는 그 사실을 함께 보여주고 S2도 선택지로 남긴다. S5(하이브리드)는 제안하지
않는다 — 텍스트 뼈대의 구조 손상을 상속하는 맹점 (verdict-report §5.3).
### 2. 변환 (산출은 스크래치 디렉토리에 — 완성 전 vault에 쓰지 않는다)
- **S2**: `uv run "$SKILL_DIR/scripts/s2-convert.py" <pdf> <scratch>/converted.md`
(PEP 723 메타데이터로 uv가 pymupdf4llm을 자동 준비)
- **S6**: 스크립트를 런타임으로 복사 후 실행 (bare import 해석 때문에 필수):
```bash
RUNTIME=~/.cache/ppu-paddle-ocr-runtime
cp "$SKILL_DIR/scripts/s6-ocr.mjs" "$RUNTIME/"
node "$RUNTIME/s6-ocr.mjs" <pdf> <scratch>/converted.md # 한글 문서 (기본)
node "$RUNTIME/s6-ocr.mjs" <pdf> <scratch>/converted.md --model v6-tiny # 영문 전용
```
- **S4** (클코 자신이 수행): `pdftoppm -png -r 150 <pdf> <scratch>/pages/p`로 렌더 후
페이지 이미지를 순서대로 Read로 정독하며 전사한다. 규칙:
- 보이는 것만 충실히 전사 — 추측·보완·요약 금지 (환각 방지)
- 표는 MD 표로 재구성
- 다이어그램·그림은 내부 라벨을 모두 옮기고, 화살표·흐름 등 관계를 텍스트로 서술
- 페이지마다 `<!-- page N -->` 마커
- 시작 전 예상 비용(약 0.045 USD/페이지)을 사용자에게 고지
### 3. 산출·마무리
1. 원본 보존: `cp <pdf> "$VAULT_DIR/raw/pdf/<원본파일명>.pdf"` (디렉토리 없으면 생성)
2. frontmatter를 붙여 `Clippings/<원본파일명 확장자만 .md>`로 이동:
```yaml
---
source_pdf: "raw/pdf/<원본파일명>.pdf"
source_sha256: "<shasum -a 256 결과>"
converted_by: S2|S4|S6
converted_at: "YYYY-MM-DD"
pages: N
---
```
본문 첫 줄은 원제목 H1 (`# <문서 제목>`).
3. 완료 보고: 전략·페이지 수·MD 크기·경로 + "잉게스트는 vault-ingest(-claude)로
별도 실행" 안내.
### 4. 검증 (완료 선언 전)
- `<!-- page N -->` 마커 수 = 페이지 수 (S6/S4)
- MD 0바이트면 실패 처리. 페이지당 평균 100자 미만이면 경고 + 사용자 확인
(희소 텍스트 문서일 수 있음)
- frontmatter 필수 키 5종 존재 (`source_pdf`·`source_sha256`·`converted_by`·`converted_at`·`pages`)
- 모든 산출 경로가 `$VAULT_DIR` 아래인지 (vault 밖 변환 모드에서는 반대 — 아래 § 참고)
## vault 밖 변환 모드 (커밋 불가 문서용)
게이트 1(커밋 가능성) 실패 — 고객사·개인 문서 — 인데 변환 산출물 자체는 필요한 경우의
공식 경로. 게이트가 이 모드를 **제안**할 수는 있지만, 진입은 사용자의 명시적 선택으로만
한다 (기본값 아님).
정식 절차와의 차이:
| 단계 | 정식 잉게스트 | vault 밖 변환 모드 |
|---|---|---|
| §0 게이트 2·3 (VAULT_DIR·중복) | 수행 | 중복 검사 생략 (raw/에 아무것도 안 들어가므로) |
| §1 밀도 측정·전략 제안 | 동일 | 동일 |
| §2 변환 | 동일 | 동일 |
| §3 산출·마무리 | raw/pdf/ 보존 + Clippings/ 투입 | **전부 생략** — vault 아래에 아무것도 쓰지 않는다 |
| §4 검증 | 산출 경로가 `$VAULT_DIR` 아래 | 산출 경로가 `$VAULT_DIR` **밖** (스크래치 또는 사용자 지정 경로) |
추가 규칙:
- 산출 MD는 세션 스크래치 디렉토리 또는 사용자가 지정한 vault 밖 경로에만 둔다.
frontmatter 부착은 선택이며, 붙이더라도 vault 밖 산출물에만 붙인다.
- 산출 MD는 파생 작업(노트 재정리·수치 대조 등)의 **입력**으로만 쓴다. 파생 결과물이
vault로 들어갈 때는 커밋 전에 개인정보(연락처·이메일·사업자번호·상세 주소) 미유입을
diff 기준으로 검증한다 (`VAULT_RULES.md` § Core Rules의 개인 데이터 금지 조항).
- 완료 보고에 모드 명칭("vault 밖 변환")과 산출 경로를 명시해, 정식 잉게스트로
오인되지 않게 한다.
- 실증: 2026-08-20 클라우드 바우처 심화 컨설팅 계획서 9건 (S2 변환 → 기업 노트 재대조,
vault 커밋은 파생 노트 수정분만).
## 에러 처리 (fail-closed)
- 도구·런타임 부재 → 위 셋업 명령 안내 후 중단. 자동 설치 금지.
- 변환 실패 → 스크래치만 정리하고 `Clippings/`·`raw/`는 건드리지 않는다.
- 게이트 실패 → 아무것도 쓰지 않고 사유 보고.
## 근거·주의 (요약)
- 전략별 강점: `projects/pdf2md-bench/outputs/verdict-report.md` (S6 §7, 라우팅 §7.4)
- ppu-paddle-ocr 실측 주의점: `wiki/pp-ocrv6.md` § Setup Notes (한글=v5-korean-mobile,
ArrayBuffer 입력, 모델 캐시 `~/.cache/ppu-paddle-ocr`)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!