BUILD — PAPERLENS
Ask your documents questions, without sending them anywhere
Half the documents worth querying — contracts, supplier quotes, unreleased campaign plans, internal decks — are exactly the documents you can't paste into a chatbot. Paperlens is a retrieval system that runs entirely on the machine: layout-aware parsing, hybrid retrieval, local models, and answers that cite the page they came from.
Personal build. Runs as a module inside Command Center.
- 100%
- on-device — no API keys, nothing leaves the machine
- 2-leg
- retrieval: keyword + vector, fused
- ~450
- token structure-aware chunks, not blind overlap
- Every
- answer carries a clickable page citation
Why I built it
I wanted the obvious thing — ask a question across a folder of PDFs and get a sourced answer — without the obvious tradeoff of uploading the folder to somebody else's server. For anything commercially sensitive that tradeoff isn't a preference, it's a blocker. So the constraint came first: loopback only, no cloud calls, no keys. Everything else was designed around it.
The part most RAG tools get wrong
Retrieval quality is mostly an ingestion problem, not a model problem. A PDF shredded by a naive text extractor produces chunks that split tables down the middle and orphan headings from their content — and no amount of prompt engineering recovers information the parser destroyed. So Paperlens uses a layout-aware parser with a real table-structure model, and chunks on document structure at roughly 450 tokens rather than sliding a fixed window with blind overlap. Retrieval runs two legs always: keyword search and vector search, fused with reciprocal rank fusion, twenty candidates narrowed to six. Keyword search is not a legacy fallback — on documents dense with product codes, figures and proper nouns it routinely beats the embeddings, which is exactly the kind of document a marketer actually has.
The silent-failure list
Local inference has a specific hazard: the failure modes are quiet. Nothing errors — the answers just get worse. Three of them are pinned down in the project's rules. Context length must be set explicitly on every model call, embedding and generation alike, or long inputs are silently truncated. The embedding model's task prefixes are mandatory and applied in exactly one shared function, because getting them wrong degrades retrieval measurably and invisibly. And changing the embedding model means a full re-index — a store embedded with one model is noise under another — so a health check asserts the stored vector dimension matches a fresh probe rather than trusting it. The storage location is a rule too: never inside an iCloud-synced folder, because sync plus a memory-mapped vector store equals corruption.
What it proves
That I understand where AI output actually comes from. Anyone can call an API; knowing that the answer quality was decided at ingestion time — and being able to name the three places it silently degrades — is the difference between using a tool and being able to trust one.
Stack