npm i @llamaindex/liteparse 한 줄로 시작할 수 있다. RAG 파이프라인의 첫 단계 "문서 → 텍스트" 변환을 클라우드 호출 없이 처리하려는 개발자를 위한 가벼운 무료 옵션이다.LLM에 문서를 통째로 던지려면 우선 텍스트와 좌표 정보로 분해해야 한다. LiteParse는 그 첫 단계만 담당하는 도구다. 복잡한 표·다단 레이아웃·필기는 약하지만, 평범한 PDF·DOCX·이미지 같은 "깨끗한 문서"는 빠르게 처리한다.
LiteParse는 식당의 "재료 손질 담당"이다. 손님(LLM)이 요리(요약·질문 답변)를 먹기 전에, 누군가는 양파 껍질을 까고 당근을 썰어야 한다. 그게 문서 파싱이다.
같은 회사(LlamaIndex)의 LlamaParse는 미슐랭 셰프 손질(클라우드, 유료, 손글씨·복잡 표까지)이라면, LiteParse는 집에서 직접 칼질하는 무료 옵션이다. 깔끔한 야채면 충분히 쓸 만하지만, 닭 한 마리를 통째로 분해하려면 셰프를 부르라는 게 README가 대놓고 하는 이야기다.
RAG(Retrieval-Augmented Generation, 검색 증강 생성)는 "외부 문서를 LLM에 붙여 답변하게 하는" 패턴이다. 그 파이프라인의 첫 단계가 문서 → 텍스트 변환인데, 여태 무료로 쓸 만한 옵션은 pdfplumber, PyPDF2 같은 파이썬 라이브러리들이었다. LiteParse는 CLI 한 방으로 PDF·DOCX·XLSX·이미지를 다 처리하고, 결과를 LLM이 바로 먹을 수 있는 마크다운/JSON으로 내보낸다. LlamaIndex 입장에선 무료 사용자가 익숙해진 다음 LlamaParse 유료 서비스로 자연 이동시키려는 깔때기 전략이기도 하다.
요즘 사내 문서를 LLM으로 처리할 때 가장 큰 걸림돌이 데이터 유출 우려다. AWS Textract·Google Document AI·Adobe API는 다 클라우드로 파일을 올려야 한다. LiteParse는 PDFium + tesseract-rs를 플랫폼 바이너리에 정적 링크해, 파일이 절대로 외부로 나가지 않는다. 사내 보안 정책상 외부 API가 금지된 팀에게는 강력한 미끼다.
한 패키지로 세 가지 방식이 동시에 열린다 — (1) 터미널에서 lit parse로 단발 처리, (2) JS/TS 코드에서 import { LiteParse }로 라이브러리 사용, (3) Claude·Codex 같은 에이전트에 npx skills add run-llama/llamaparse-agent-skills/liteparse로 스킬로 끼워 넣기. 특히 마지막은 2026년 트렌드인 "AI 에이전트 스킬" 흐름을 정확히 탔다.
DOCX/PPTX/XLSX·이미지 파싱을 직접 구현하지 않고 LibreOffice·ImageMagick에 위임한다. 두 도구가 깔려 있으면 LiteParse가 자동으로 PDF로 변환한 뒤 PDFium으로 처리한다. 코드량은 줄이면서 지원 포맷은 늘리는 트레이드오프 — 다만 의존성이 무거워지는 단점이 있다.
| 항목 | LiteParse | LlamaParse (유료) | pdfplumber (Python) | AWS Textract |
|---|---|---|---|---|
| 가격 | 완전 무료 | 크레딧 과금 | 완전 무료 | 페이지당 과금 |
| 실행 위치 | 로컬 | 클라우드 | 로컬 | 클라우드 |
| OCR 내장 | O (Tesseract, native) | O | X (별도 설치) | O |
| 표·복잡 레이아웃 | 약함 | 강함 | 중간 | 강함 |
| 지원 포맷 | PDF/DOCX/XLSX/이미지 등 | 광범위 | PDF만 | PDF/이미지 |
| 설치 | npm i | API 키 발급 | pip install | AWS 계정 |
| 출력 | JSON · Text | JSON · 마크다운 | Python 객체 | JSON |
| 스크린샷 기능 | O (LLM 에이전트용) | O | X | X |
LiteParse가 직접 작성한 코드는 의외로 적다. 무거운 작업은 전부 검증된 네이티브 라이브러리 두 개가 처리한다. 전체 코어는 Rust로 작성됐으며, TypeScript는 napi-rs로 Node.js 바인딩을 노출하는 얇은 래퍼다.
| 라이브러리 | 역할 | 출신 |
|---|---|---|
PDFium (liteparse-pdfium 크레이트) | PDF 텍스트·좌표·이미지 추출 엔진. extract.rs에서 use pdfium::Library로 직접 사용 | Google (Chrome에 내장된 그 PDF 렌더러). C 라이브러리를 Rust로 래핑 |
tesseract-rs | 이미지에서 글자를 인식하는 OCR 엔진 — 네이티브 Tesseract를 Rust 크레이트로 정적 링크 | 구글 Tesseract의 Rust 네이티브 바인딩. WASM이 아닌 플랫폼 바이너리로 번들링 |
image (Rust crate) | PNG 인코딩 / 이미지 처리 | Rust 이미지 처리 생태계 |
crates/pdfium Rust 래퍼 크레이트를 통해 이 엔진을 직접 사용한다.실제로 LiteParse 팀이 작성한 코드는 PDFium과 tesseract-rs를 호출하면서 "공간 정보를 유지한 채" 결과를 합치는 Rust 로직이다. 핵심은 다음 네 가지:
npm 글로벌 설치 시 생기는 lit 커맨드는 Commander 라이브러리로 만들었다. Express 만든 사람이 만든 라이브러리로, Node.js CLI 도구의 사실상 표준이다.
# 빠르게 살펴보는 lit 커맨드 3종
lit parse document.pdf --format json -o output.json
lit batch-parse ./input-dir ./output-dir --extension .pdf
lit screenshot document.pdf --dpi 300 -o ./screenshots
npm 패키지에 같이 들어오지 않는다. 시스템에 따로 설치해야 DOCX/XLSX/이미지 변환이 동작한다. 없으면 PDF만 처리 가능.
| 도구 | 처리 포맷 | 설치 |
|---|---|---|
libreoffice | doc/docx/odt/rtf · ppt/pptx/odp · xls/xlsx/ods/csv/tsv | brew install --cask libreoffice 또는 apt-get install libreoffice |
imagemagick | jpg/png/gif/bmp/tiff/webp/svg | brew install imagemagick 또는 apt-get install imagemagick |
기본 내장 Tesseract 정확도가 모자란 사용자를 위해 LiteParse는 HTTP OCR API 스펙을 정의해뒀다. 누구나 자기 OCR 엔진을 그 스펙에 맞춰 HTTP 서버로 감싸면 --ocr-server-url 플래그로 LiteParse에 끼울 수 있다. 레포의 ocr/ 폴더에는 EasyOCR과 PaddleOCR을 감싼 Python 서버 예제가 들어있다.
OCR 시스템은 "USB-C 포트" 같다. 본체(LiteParse)는 정해진 모양의 단자(POST /ocr, multipart/form-data)만 약속하고, 어떤 OCR 엔진을 꽂든 동작하게 만들었다. EasyOCR이 더 정확하면 EasyOCR을 꽂고, PaddleOCR이 한국어를 더 잘하면 PaddleOCR을 꽂는다.
같은 레포 안에 Python 바인딩도 있다. pip install 한 뒤 Python에서 from liteparse import LiteParse로 호출하면, 내부적으로는 PyO3(Rust→Python 네이티브 바인딩)를 사용하여 Rust 코어를 직접 호출한다. Node.js나 subprocess가 필요 없고 순수 Python + 네이티브 확장으로 동작한다. "Python 위주의 RAG 파이프라인에 끼우기 위한 얇은 어댑터"라고 보면 된다.
Claude·Codex 같은 AI 에이전트가 SKILL.md 파일을 읽고 "이 도구를 언제 어떻게 호출하는지" 배우는 새 표준이 있는데, LiteParse도 그 형태로 배포된다. 별도 레포 run-llama/llamaparse-agent-skills에 PDF 파싱이 필요할 때 자동으로 lit parse를 호출하는 스킬이 들어있다.
LiteParse는 DOCX·XLSX·이미지마다 별도 파서를 구현하지 않는다. 모든 입력을 PDF로 변환한 다음 PDF 파이프라인 하나에 태운다. 이게 가능한 이유는 두 가지:
libreoffice --headless --convert-to pdf file.docx 한 줄로 거의 모든 오피스 파일이 PDF가 된다convert image.png output.pdf로 이미지를 단일 페이지 PDF로 감싼다새 포맷을 지원하려면 변환기만 추가하면 된다. PDF 처리 로직은 건드릴 필요가 없어 코드 복잡도가 일정하게 유지된다. RAW 카메라 파일·EPUB·HWP 같은 새 포맷을 미래에 추가할 때도 같은 패턴이 그대로 통한다.
LibreOffice가 깔려 있어야 DOCX가 처리되고, 그 LibreOffice 자체가 수백 MB짜리다. 또 DOCX → PDF 변환 과정에서 코멘트·트랙 변경·복잡한 차트가 깨질 수 있어, "원본 정보를 100% 보존"하는 게 아니라 "PDF 수준의 시각 정보로 환원"하는 트레이드오프가 있다.
OCR은 무겁다. 페이지마다 tesseract-rs를 돌리면 50페이지 PDF가 10분씩 걸린다. LiteParse는 PDF의 텍스트 레이어가 비어 있는 페이지·영역만 골라서 OCR을 돌린다.
구체적으로는 — PDFium이 추출한 텍스트 조각이 페이지에 거의 없으면 "이 페이지는 스캔본일 가능성이 높다" → OCR 대상. 텍스트는 충분하지만 중간에 이미지 박스가 있으면 "그 이미지 영역만" OCR. 이렇게 해서 일반 텍스트 PDF는 OCR을 거의 안 돌리고, 스캔 PDF만 OCR로 처리해 평균 속도를 유지한다.
OCR을 코드 안에 묶어버리면 다른 엔진(Korean OCR이 강한 PaddleOCR, 손글씨 잘하는 TrOCR 등)으로 갈아끼울 수 없다. LiteParse는 HTTP API 스펙을 정의하고, 기본 tesseract-rs는 그 스펙을 in-process로 흉내내고, 외부 OCR은 진짜 HTTP 서버를 띄워 같은 API로 호출하게 만들었다.
// OCR_API_SPEC.md 요약 — 이 인터페이스만 맞추면 어떤 엔진이든 OK
POST /ocr
Content-Type: multipart/form-data
file: 이미지 바이너리
language: ISO 639-1 코드 ("en", "ko", "ja", ...)
Response 200:
{
"results": [
{
"text": "Hello",
"bbox": [10, 20, 60, 40],
"confidence": 0.98
}
]
}
PDFium이 추출하는 텍스트 조각은 읽는 순서가 보장되지 않는다. "Hello World"라는 문장도 "World"가 먼저 나오고 "Hello"가 나중에 나올 수 있다 (PDF 생성 도구의 변덕). LiteParse는 각 조각의 (x, y) 좌표를 보고 격자에 다시 배치해서 사람이 읽는 순서로 정렬한다.
책상 위에 글자가 적힌 포스트잇 100장이 무작위로 뿌려져 있다. PDFium은 그 포스트잇을 한 장씩 집어 던져주는 사람이고, Spatial Projection은 그걸 받아서 왼쪽에서 오른쪽, 위에서 아래 순서로 다시 책상에 정렬하는 사람이다. 다단 신문 기사라면 1단을 위에서 아래로 다 읽은 뒤 2단으로 넘어가도록 격자 컬럼도 감지한다.
전체 정확도를 좌우하는 핵심 파일. PDFium이 던지는 텍스트 조각을 좌표 기반 격자에 다시 배치하는 알고리즘이 여기 있다. 다단 레이아웃·표·회전 텍스트를 살리는 모든 로직이 이 파일에 모여 있어, 새 PDF에서 출력이 이상하면 거의 항상 여기를 의심해야 한다.
"내가 가진 OCR 엔진을 LiteParse에 끼우려면?" 답이 이 파일에 있다. POST /ocr 엔드포인트, multipart/form-data 입력, JSON 출력 형식, 좌표 시스템(top-left origin), confidence 정규화 등 6쪽짜리 사양이라 한 번 읽으면 자기 엔진을 호스팅하는 데 무리가 없다.
각각 EasyOCR·PaddleOCR을 FastAPI로 감싼 작은 Python 서버. Dockerfile까지 포함되어 있어 docker build → docker run 하면 즉시 OCR 서버가 뜬다. 자기 OCR을 끼우고 싶으면 이 폴더를 통째로 복사한 뒤 server.py 안의 모델 부분만 바꾸면 된다.
Node.js를 직접 다루기 싫은 사용자를 위한 Python 래퍼. 내부에서는 PyO3 네이티브 확장(liteparse._liteparse)으로 Rust 코어를 직접 호출한다. Node.js나 subprocess가 전혀 필요 없으며, 사용자는 from liteparse import LiteParse만 하면 된다. RAG 파이프라인이 이미 LangChain·LlamaIndex Python으로 짜여 있을 때 끼우기 좋다.
요즘 트렌드 — 사람이 읽는 README와 별도로 AI 에이전트가 읽을 문서를 따로 둔다. 디렉토리 구조, 데이터 흐름, 새 기능을 추가할 때 어떤 파일을 건드려야 하는지 등을 명세 형태로 정리. Claude Code·Cursor·Codex 같은 도구가 이 파일을 자동으로 읽고 컨텍스트로 활용한다.
PDFium은 Chrome/Chromium에 내장된 PDF 렌더링 엔진이다. LiteParse는 crates/pdfium Rust 래퍼를 통해 이 엔진을 직접 호출해 텍스트·좌표·이미지를 추출한다. C 라이브러리를 Rust FFI로 감싸는 패턴을 실제 프로덕션 코드에서 볼 수 있는 좋은 사례다.
실습 아이디어 — pdfium-render 크레이트(Rust)나 pypdfium2(Python 바인딩)로 PDF 한 페이지를 PNG로 렌더링하는 미니 도구를 만들어보자. 좌표계(origin, DPI 스케일)를 출력해보면 PDF가 내부적으로 좌표를 어떻게 다루는지 직관이 생긴다.
1985년 HP에서 시작된 C 라이브러리가 2026년 Rust에서 직접 돌아간다. 비밀은 Rust FFI + build-tesseract feature. WASM 포팅과 달리 플랫폼 바이너리에 정적 링크되어 추가 설치가 필요 없고 네이티브 속도를 그대로 낸다. 같은 패턴(C 라이브러리 → Rust 크레이트 바인딩)으로 libz, openssl, sqlite 등 수많은 C 라이브러리가 Rust 생태계에 흘러들어왔다.
실습 아이디어 — tesseract-rs 크레이트로 영수증·명함 사진에서 글자를 뽑는 Rust CLI를 30분 안에 만들어보자. 그다음 한국어 데이터(kor 언어 코드)를 추가해 정확도를 비교해보면 OCR의 한계를 체감할 수 있다.
LiteParse의 OCR_API_SPEC.md는 짧은 사양으로 거대한 확장성을 얻은 좋은 사례다. "우리 본체는 정해진 인터페이스만 약속하고, 구현은 외부에 맡긴다" 패턴은 LSP(Language Server Protocol, VSCode·Vim 모두 같은 LSP를 쓰는 이유), Kubernetes CRD, OpenTelemetry 등 곳곳에 등장한다.
실습 아이디어 — 자기 프로젝트에서 "사용자가 갈아끼울 수 있는" 부분을 하나 골라(예: 알림 전송, 결제 처리), 그 부분을 HTTP API 스펙으로 정의한 뒤 기본 구현체 1개 + 외부 구현체 1개를 만들어보자.
"DOCX 파서를 직접 작성한다"는 1년 프로젝트지만, "LibreOffice를 spawn한다"는 30줄짜리 함수다. 호스트 시스템의 강력한 CLI를 활용해 자기 도구의 책임 범위를 줄이는 패턴은 Pandoc, Sharp, Imagemin 등에서도 흔하다.
실습 아이디어 — Node.js의 child_process.spawn으로 LibreOffice를 호출해 DOCX → PDF로 변환하는 함수를 직접 짜보자. stderr를 어떻게 처리하는지, 변환 실패 시 어떻게 폴백할지 고민해보면 production-grade 외부 도구 호출의 디테일을 배운다.
LiteParse의 AGENTS.md는 잘 짜인 예시다. "새 OCR 엔진 추가 시 건드릴 파일 3개"처럼 작업 단위로 정리된 게 핵심. AI 에이전트가 큰 코드베이스를 처음 만났을 때 막막함을 줄여준다.
실습 아이디어 — 자기 프로젝트에 AGENTS.md를 한 장 추가해보자. (1) 디렉토리 구조 (2) 데이터 흐름 (3) 새 기능 추가 시 작업 순서 — 이 세 가지만 채우면 충분하다. Claude Code에 같은 코드베이스를 두 번(있을 때 vs 없을 때) 물어보고 답변 품질 차이를 비교해보면 효과를 체감할 수 있다.
| 항목 | 요구사항 | 비고 |
|---|---|---|
| Node.js | v18+ 권장 | npm 글로벌 설치 시 필수 |
| OS | Linux · macOS (Intel/ARM) · Windows | standalone 바이너리도 제공 |
| 메모리 | 2GB+ | 대용량 PDF(100MB+) 처리 시 더 필요 |
| 디스크 | 패키지 ~200MB | tesseract-rs 번들 바이너리 포함 |
| 설치 시 추가로 지원되는 포맷 | 설치 방법 |
|---|---|
| LibreOffice — DOCX·PPTX·XLSX·ODT·CSV 등 | brew install --cask libreoffice / apt-get install libreoffice / choco install libreoffice-fresh |
| ImageMagick — JPG·PNG·GIF·BMP·TIFF·WebP·SVG | brew install imagemagick / apt-get install imagemagick / choco install imagemagick.app |
soffice.exe 경로(C:\Program Files\LibreOffice\program)를 PATH 환경변수에 추가하고 재부팅해야 LiteParse가 LibreOffice를 찾는다. 안 그러면 DOCX를 던졌을 때 "command not found" 류 에러가 난다.기본 내장 Tesseract 정확도로 부족하면 외부 OCR 서버를 띄울 수 있다. ocr/easyocr/ 또는 ocr/paddleocr/를 Docker로 실행하면 GPU 가속 OCR을 끼울 수 있는데, 이때는 다음 환경이 필요하다:
아무 PDF (최근 다운받은 청구서·논문·매뉴얼)를 골라 lit parse my.pdf -o out.txt로 처리한다. 결과 텍스트를 PDF 원본과 비교해 어떤 부분이 잘 살았고 어떤 부분(표·다단·이미지 캡션)이 깨졌는지 관찰한다. 학습 목표: 로컬 파서의 강점·약점을 직접 느끼기.
lit parse my.pdf --format json -o out.json으로 JSON을 받아본 뒤, jq나 Python으로 각 텍스트 조각의 bbox 좌표를 파싱해본다. 같은 페이지의 좌표값 범위를 출력해 페이지 너비·높이를 추론해보자. 학습 목표: 텍스트 + 좌표가 어떤 데이터 구조로 나오는지 손에 익히기.
로컬 PDF 5장을 lit batch-parse로 텍스트로 변환한 뒤, LangChain·LlamaIndex·또는 직접 짠 코드로 임베딩 → 벡터 DB(Chroma·FAISS) → 질문 답변 흐름을 만든다. OpenAI API 한 번도 안 쓰고 끝까지 가는 게 목표면 임베딩은 sentence-transformers 로컬 모델을, LLM은 llama.cpp나 Ollama를 쓰자. 학습 목표: RAG 파이프라인 전체에서 LiteParse가 차지하는 위치 체감하기.
ocr/paddleocr/ 폴더를 복사해서 모델 부분을 한국어용으로 바꾼다(PaddleOCR이 한국어 모델을 제공). Docker로 빌드하고 localhost:8828에 띄운 뒤, lit parse 한글문서.pdf --ocr-server-url http://localhost:8828/ocr --ocr-language ko로 호출. 기본 내장 Tesseract 결과와 정확도 차이를 비교한다. 학습 목표: 외부 OCR 플러그인 시스템을 실제로 가동해보기.
현재 LiteParse는 JSON과 Text만 출력한다. 마크다운 포맷터를 직접 추가하는 PR을 짠다. 단계: (1) src/output/에 markdown.ts 추가, (2) --format markdown CLI 플래그 처리, (3) 표·헤더를 마크다운 문법으로 변환하는 로직, (4) 테스트 추가. 학습 목표: 오픈소스 컨트리뷰션 흐름 + LiteParse 내부 구조 완전 이해.
PDF는 텍스트 포맷이 아니라 "화면에 그릴 명령어들의 시퀀스"다. 무료 PDF 명세서(PDF 1.7, ISO 32000)에서 7장(Content Streams)과 9장(Text)을 훑는다. pdfinfo, pdftotext(poppler) 같은 CLI도 함께 실습.
pdfium-render(Rust) 또는 pypdfium2(Python) 크레이트를 손으로 다 호출해본다. 페이지 텍스트 추출 → 좌표 파싱 → PNG 렌더링 API를 순서대로 실습하고, 자기 PDF에 텍스트 박스·이미지 영역을 빨강 사각형으로 오버레이하는 도구를 만들어본다.
OCR이 왜 어려운지(글자 모양 변동, 폰트 다양성, 노이즈), 어떤 알고리즘(투영 프로파일·CRNN·CTC)이 쓰이는지 개념을 잡는다. Tesseract 5.x를 로컬에 직접 설치하고, tesseract image.png out로 CLI를 써본 다음 tesseract-rs(LiteParse 내장)와 비교한다. 정확도가 같은지, 속도는 어떤지.
EasyOCR(PyTorch), PaddleOCR(Baidu PaddlePaddle), TrOCR(Hugging Face Transformer 기반)을 각각 Docker로 띄워 같은 PDF로 정확도·속도·메모리를 비교한다. 어떤 게 한국어를 잘하고, 어떤 게 손글씨를 잘하는지 직접 측정.
LangChain Tutorial 또는 LlamaIndex Quickstart를 따라가며 — 문서 로드 → 청크 분할 → 임베딩 → 벡터 DB 저장 → 검색 → LLM 호출 → 답변까지 한 번 끝낸다. 청크 크기·오버랩·임베딩 모델 선택이 답변 품질에 미치는 영향을 직접 실험.
Chroma, FAISS, Qdrant, Pinecone, pgvector(Postgres)를 같은 데이터로 띄워보고 검색 정확도·속도·운영 난이도를 비교한다. "처음 만들 땐 Chroma, 본격적이면 Qdrant, 사내 인프라에 묶으려면 pgvector" 같은 선택 기준 직관을 만든다.
OpenAI API 없이 RAG를 돌리는 길 — llama.cpp·Ollama·LM Studio로 Llama 3·Mistral·Qwen 같은 모델을 로컬에 띄우고, LiteParse + 로컬 임베딩 + 로컬 LLM으로 완전 오프라인 RAG를 만든다. 회사 보안 정책상 클라우드를 못 쓰는 환경에서 가장 유용한 스택.
Claude의 SKILL.md, Codex의 같은 패턴, MCP(Model Context Protocol)를 비교 학습. LiteParse의 agent-skill 패키지(run-llama/llamaparse-agent-skills)를 뜯어보고, 자기 도구도 한 페이지짜리 SKILL.md로 노출시켜본다.
[x1, y1, x2, y2]로 표현한 좌표. PDF·OCR 결과에서 "이 글자가 페이지의 어디에 있었는지"를 추적할 때 필수.libreoffice --headless --convert-to pdf file.docx 한 줄로 DOCX/XLSX/PPTX/ODT 같은 거의 모든 오피스 파일을 PDF로 변환할 수 있다. 서버 환경에서 자주 쓰인다.convert, magick 커맨드로 PNG ↔ JPG, 크기 조정, 회전, 필터 적용을 다 할 수 있다. 1987년부터 있어서 거의 모든 리눅스 배포판에 표준으로 들어있다..command() · .option() · .action() 체이닝으로 CLI를 짠다. Vue CLI, ESLint, npm 자체 등이 모두 commander 또는 그 후예를 쓴다.