| name | vercel-rag |
| classification | capability |
| classification-reason | Reference guide capturing architecture decisions and bug fixes for a specific integration (PDF RAG ingestion on Vercel + Supabase), not a repeatable multi-step user workflow. |
| deprecation-risk | none |
| effort | medium |
| description | Vercel(Next.js Route Handlers + Python serverless functions) + Supabase(Storage, pgvector)
환경에서 PDF 업로드 → 표/다이어그램까지 포함한 RAG 파이프라인을 만들 때 실제로 부딪혔던
플랫폼 제약과 버그, 그리고 그 해결책을 정리한 레퍼런스.
Triggers: PDF RAG, PDF 업로드, pdfplumber, Vercel Python function, Supabase Storage 업로드,
413 Request Entity Too Large, 504 timeout, DOMMatrix is not defined, pdf-parse
Keywords: RAG, PDF, pdfplumber, pdf-parse, Vercel serverless, Python function, Supabase Storage,
signed URL, maxDuration, timeout, middleware, DOMMatrix
|
| argument-hint | (no args — reference this skill when building or debugging PDF ingestion on Vercel+Supabase) |
| user-invocable | true |
| allowed-tools | ["Read","Write","Edit","Glob","Grep","Bash"] |
vercel-rag
Vercel(Next.js) + Supabase 스택에서 PDF를 업로드해 표/다이어그램까지 포함한 RAG 파이프라인을 만들 때
실제로 겪은 5개의 서로 다른 실패와 그 원인/해결책을 정리한 가이드. 처음부터 이 문서를 읽고 시작하면
같은 시행착오를 반복하지 않는다.
언제 이 스킬을 참고하는가
- PDF/문서를 업로드해서 벡터DB에 넣는 RAG 기능을 Vercel + Supabase로 만들 때
- "표가 잘 안 뽑혀요", "이미지/다이어그램 설명이 필요해요" 같은 요구가 있을 때
pdf-parse를 썼는데 DOMMatrix is not defined 같은 에러가 날 때
- 파일 업로드에서
413 Request Entity Too Large 또는 504 타임아웃이 날 때
최종 아키텍처 (검증됨)
브라우저
│ 1. PDF를 Supabase Storage에 "직접" 업로드 (Next.js 서버를 거치지 않음)
▼
Supabase Storage (private bucket, RLS: 본인 폴더만 read/write/delete)
│
│ 2. 브라우저 → Next.js Route Handler: { storagePath, filename } 만 JSON으로 전달 (파일 본문 없음)
▼
Next.js Route Handler (app/api/rag/ingest/route.ts)
│ 3. Storage signed URL 생성 (createSignedUrl, 120초 유효)
│ 4. Python 함수에는 signed URL만 JSON으로 전달 (파일 본문을 절대 다시 실어나르지 않음)
▼
Vercel Python 함수 (api/pdf_extract.py, pdfplumber)
│ 5. signed URL로 직접 PDF 다운로드 (urllib.request — outbound fetch라 inbound body 제한과 무관)
│ 6. 페이지별 text / table(마크다운 변환) / 페이지 이미지(base64, JPEG) 추출
▼
Next.js Route Handler로 결과 반환
│ 7. 페이지 이미지가 있으면 비전 LLM 호출(동시성 4~6개로 제한)해 다이어그램만 설명
│ 8. 페이지별 [텍스트 + 표 + 다이어그램 설명]을 합쳐 청킹 → 임베딩 → pgvector insert
│ 9. finally 블록에서 Storage 원본 PDF 삭제 (처리 후 폐기 — 추출된 텍스트/임베딩만 남김)
겪은 문제 5가지와 원인/해결
1. pdf-parse v2 → ReferenceError: DOMMatrix is not defined
- 원인:
pdf-parse v2.x는 내부적으로 pdfjs-dist를 쓰는데, 브라우저 전용 API(DOMMatrix 등)를
참조하는 코드 경로를 Node.js 서버리스 환경에서도 타는 경우가 있다.
- 1차 해결:
pdf-parse@1.1.1(구버전, 순수 텍스트 추출)로 다운그레이드.
- 2차 문제: v1은 webpack으로 번들링하면
index.js의 디버그 코드가 실행되어
ENOENT: .../test/data/05-versions-space.pdf를 찾으려는 별개의 버그가 있다.
→ import pdfParse from "pdf-parse/lib/pdf-parse.js"처럼 내부 lib 경로로 직접 import해서 우회.
타입 선언이 없으므로 declare module "pdf-parse/lib/pdf-parse.js" ambient d.ts 파일을 하나 추가해야 한다.
- 최종 해결(이 프로젝트): 표/레이아웃 품질이 중요해서 아예
pdf-parse 자체를 걷어내고
Python pdfplumber로 교체했다. 단순 텍스트만 필요하면 위의 v1 우회 방식으로 충분하다.
2. 표/다이어그램 품질이 필요하면 Node엔 답이 없다 → Vercel Python 함수
- LangChain.js의 PDF 로더도 결국
pdf-parse를 감싼 것일 뿐이라, 표 구조 복원 능력은 없다.
- PDFPlumber(Python) 는 위에서 문자 좌표를 분석해 표를 복원하는데, JS 포트가 없다.