thenug.net

paperless-ngx with ai document tagging

Paperless-NGX scans, OCRs, and archives documents. adding an AI sidecar means every document that comes in gets automatically titled, tagged, and assigned a correspondent — without any manual sorting.

the problem with documents

PDFs accumulate fast. bank statements, insurance forms, receipts, medical records. manually tagging each one takes time and consistently doesn't happen. the result is a pile of documents named scan_2024_03_14.pdf that can't be found when you need them.

paperless-ngx

Paperless-NGX is a document management system. it watches a consume folder, OCRs anything that lands there, and stores it in a searchable archive. you can tag documents, assign correspondents (who sent it), set document types, and search full text.

it can also pull from email. a Gmail IMAP rule watches for PDF attachments and automatically imports them into the consume pipeline.

the ai sidecar

Paperless-AI runs alongside Paperless-NGX as a separate container. it watches for newly consumed documents, sends the text to an LLM, and applies the returned tags and title back via the Paperless API.

the model here is deepseek/deepseek-chat via OpenRouter — an OpenAI-compatible API endpoint that routes to various models. the AI reads the document content and returns structured metadata: a clean title, relevant tags, and a correspondent name.

the gmail rule

Paperless can poll a Gmail account via IMAP and import attachments automatically. a few settings matter:

gotchas

don't hardcode the API token in the compose file. if you ever delete the stack with volumes, Postgres gets wiped, the admin user is regenerated, and the API token changes. entering it through the Paperless-AI UI wizard means you just update it in one place. hardcoding means broken deploys.

the API URL must use the Docker service name. Paperless-AI needs to reach Paperless-NGX over the Docker network. http://webserver:8000 works. http://10.0.3.21:8010 (the host IP) fails because the request goes out to the host and back in — Docker routing doesn't handle this the way you'd expect.

Paperless-AI settings don't survive a redeploy. the sidecar stores its config (API keys, model settings) in /app/data/.env inside the container. no volume is mounted there by default, so a container recreation wipes the config. the fix is a bind mount to persist the settings file — worth adding to the compose before you need it.

eli5

imagine a mail room (Paperless-NGX) that receives every document you own, scans it, and files it in a cabinet. previously someone had to read each document and write the label on the folder. now there's an assistant (the AI sidecar) who reads each document as it comes in, figures out what it is, and writes the label automatically. if it's a bank statement from Chase, it gets tagged "bank statement," assigned to "Chase," and titled "Chase Statement March 2024." the Gmail rule is like a dedicated inbox that automatically forwards any PDF attachments from your email to the mail room as soon as they arrive.


← back to blog