Overview
How It Works
- A document gets tagged ocr-redo in Paperless (manually or through automation rules)
- The container polls for documents with that tag, downloads the original PDF
- Each page is rendered as a high-resolution image at 300 DPI using PyMuPDF
- The page image is sent to an LLM vision API with a specialized OCR prompt
- The system writes the extracted text back to Paperless's content field for full-text search, and also builds a searchable PDF artifact internally for validation and future replacement workflows
- The trigger tag is swapped for ocr-complete (or ocr-failed if something went wrong)
Multi-Page Context Awareness
- Immediate context: The last portion of the previous page's text, so the model knows what it just read
- Rolling summary: An accumulated understanding of the document built from context notes the model generates after each page
- Automatic condensation: Every few pages, older context notes get compressed to keep the prompt size manageable for long documents
Multi-Model Fallback Chain
- Primary model processes the page (I currently run Gemini Flash, but any supported provider works)
- If blocked by content filters or the response is empty, it falls through to Fallback 1 (Anthropic in my deployment)
- If that also fails, it tries Fallback 2 (xAI in my deployment)
- Each tier has its own retry logic with exponential backoff (5 retries, starting at 2 seconds, doubling each attempt) for transient errors including rate limits, timeouts, and server errors
Concurrent Processing
Why Not Just Use Tesseract?
- Handwritten notes scribbled on printed forms
- Complex tables where Tesseract loses column alignment and merges cells
- Low-contrast scans where faded text becomes unreadable
- Checkboxes and form fields that Tesseract ignores entirely
- Mixed content with printed text, stamps, signatures, and handwriting on the same page
Configuration
Tech Stack
- Python with async/await for concurrent document processing
- PyMuPDF for 300 DPI page rendering and internal searchable PDF artifact generation
- OpenAI-compatible, Anthropic, and Google Gemini SDKs for OpenAI, xAI, Anthropic, and Gemini vision OCR
- Paperless-ngx REST API for document retrieval and content updates
- Docker / Kubernetes with automated GitHub Actions CI/CD publishing to GHCR
- Exponential backoff retry logic (5 retries, 2s base) for resilient API interaction