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. Asset brain and menu extraction added September 2026.
- 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, because 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.
Images, menus and the asset brain
September 2026 extended it past text. Standalone images are captioned by a local vision model and indexed alongside the documents, with an honest '[illegible]' convention when the model can't read the file. Every ingested asset carries a type (menu, deck, campaign creative, brand guideline, EDM) set explicitly at ingest and never inferred from content, plus a caption confidence derived from how the file was actually read, not from the model grading itself. Queries can filter on that type, which is what turns a document tool into a brand asset brain. A separate menu extractor takes an image-only PDF, the kind that is invisible to crawlers and answer engines alike, renders each page and pulls sections, dishes and prices into structured JSON for human review. A golden set caught a real bug on the first run: the schema allowed one section per page, so a five-section menu scored one in nine on recall. Fixed, re-run, nine in nine, zero invented prices.
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