NSIG_

Paperless-ngx mit eigener KI

Vom Themen KI · Ollama · Homelab · Datenschutz

Paperless-ngx nimmt eingescannte Papiere entgegen, liest sie per Texterkennung und sortiert sie nach Schlagwort, Absender und Art. Seit einiger Zeit steckt darin auch ein Sprachmodell, und das ist der Teil, der eine Entscheidung verlangt: Die KI-Funktionen sind ab Werk aus, und sie ersetzen die eingebaute Zuordnung ohne Sprachmodell nicht. Sie kommen daneben.

Diese Notiz sagt, was das Aufsetzen kostet, was die drei KI-Funktionen tatsächlich tun, und wo die Grenze liegt, an der die eigenen Dokumente das Haus verlassen.

Vier Wege hinein

Die Doku führt sie mit dem Aufwand daneben auf:

Weg Wofür Aufwand
Installationsskript Der schnellste erste Aufbau, mit Rückfragen. Empfehlung der Doku für die meisten gering
Docker-Compose-Vorlagen Wer die Compose-Dateien und die Einstellungen selbst in der Hand behalten will mittel
Bare Metal Fortgeschrittenes, Paketbau, Arbeit nahe an der Entwicklung hoch
Gehostete Anbieter Von der Gemeinschaft gepflegte Liste im Wiki. Die Doku sagt dazu, man solle die Einzelheiten sorgfältig prüfen wechselnd

Der vierte Weg gehört in diese Liste, obwohl der Rest der Notiz vom Selbstbetrieb handelt. Bei ihm liegen die Papiere von vornherein auf einem fremden Server, und das ist genau die Frage, um die es weiter unten geht.

Beim ersten Weg legt ein Skript die nötigen Dateien an, holt das Abbild, startet die Container und legt das Administratorkonto an. Es automatisiert genau den zweiten Weg. Die Doku setzt selbst einen Hinweis dazu, und er gehört hierher: Wer ein Skript ungern direkt aus dem Netz in eine Shell leitet, soll es sich vorher ansehen.

Der zweite Weg besteht aus fünf Schritten, und nur zwei davon sind Befehle:

  1. Eine docker-compose.*.yml passend zur Datenbank herunterladen und als docker-compose.yml ablegen, dazu docker-compose.env und .env in dasselbe Verzeichnis. Für neue Installationen empfiehlt die Doku PostgreSQL. Wer Office-Dateien einlesen will, nimmt die Datei mit -tika im Namen.

  2. In der docker-compose.yml die Verzeichnisse für consume und media auf eigene Ordner umbiegen. Wer die Oberfläche auf einen anderen Anschluss legen will, ändert die Zahl links vom Doppelpunkt:

    ports:
      - 8010:8000
  3. In der docker-compose.env die Einstellungen setzen. Dazu gehören USERMAP_UID und USERMAP_GID, damit Container und Benutzer beide in den Eingangsordner schreiben dürfen. Die Werte liefern id -u und id -g; bei 1000 passt es meistens ohne Zutun. Für die meisten empfiehlt die Doku zwei weitere Werte, und der erste entscheidet über die Brauchbarkeit der Texterkennung: PAPERLESS_OCR_LANGUAGE auf die Sprache, in der die eigenen Papiere geschrieben sind, und PAPERLESS_TIME_ZONE auf die eigene Zeitzone.

  4. docker compose pull

  5. docker compose up -d

Danach steht die Oberfläche unter http://127.0.0.1:8000, und beim ersten Aufruf legt man das Administratorkonto an.

Zwei Randnotizen der Doku, die später Ärger sparen: Liegt der Eingangsordner auf einem Netzlaufwerk ohne inotify, etwa NFS, merkt Paperless-ngx neue Dateien nicht; dann muss PAPERLESS_CONSUMER_POLLING_INTERVAL auf eine positive Zahl. Und weil ein Administratorkonto Zugriff auf alle Dokumente hat, schlägt die Doku vor, für den Alltag ein zweites, gewöhnliches Konto zu nehmen.

Was 3.1.0 dazugelegt hat

Die Ausgabe vom 27. August ist groß: Die Release-Seite führt 23 Einträge unter Features und Enhancements auf und weist insgesamt 91 Änderungen an der Anwendung aus. Die folgenden sechs sind hier ausgewählt, nicht von der Quelle so zusammengestellt; die ersten zwei betreffen den KI-Teil, um den es weiter unten geht.

Änderung Was sie bedeutet
Apply AI suggestions workflow action KI-Vorschläge lassen sich als Schritt in einen Arbeitsablauf hängen, statt sie je Dokument von Hand anzustoßen
prefer existing tags, types, correspondents, and storage paths in AI suggestions Die Vorschläge greifen bevorzugt auf das zurück, was schon angelegt ist, statt Neues danebenzustellen
support using remote OCR engines selectively Entfernte Texterkennung gezielt einsetzen statt alles oder nichts
merge documents as versions Mehrere Dokumente werden zu Versionen desselben zusammengeführt
sync OIDC groups to superuser and staff roles Gruppen aus der Anmeldung werden auf Rollen abgebildet
Upgrade Docker image to Python 3.14 Der Unterbau des Abbilds

Die drei KI-Funktionen

Sie hängen alle an einem Hauptschalter und sind ab Werk aus.

Vorschläge. Mit eingeschalteter KI schlägt Paperless-ngx Titel, Schlagworte, Absender, Art, Ablagepfad und Daten vor, indem es das Dokument an das Sprachmodell schickt. Das geschieht je Anfrage einzeln, über ein Bedienelement auf der Detailseite eines Dokuments, und es steht neben den klassischen Vorschlägen aus dem Klassifikator, ohne sie abzuschalten.

Der LLM-Index und ähnliche Dokumente. Setzt man zusätzlich einen Einbettungs-Dienst, entsteht ein Vektor-Index über die eigenen Dokumente. Das ist der RAG-Teil: Vorschläge stützen sich dann auf ähnliche vorhandene Dokumente statt nur auf das eine vor der Nase, und der Chat findet darüber seinen Zusammenhang. Der Index entsteht nur, wenn die KI eingeschaltet ist und ein Einbettungs-Dienst gesetzt ist.

Nachgeführt wird er nach einem Zeitplan aus PAPERLESS_LLM_INDEX_TASK_CRON, ab Werk 10 2 * * *, also einmal am Tag. Das ist die Stelle, an der man am ehesten einen Abend verliert: Wer die KI einschaltet und den Chat sofort ausprobieren will, wartet sonst auf den nächsten Durchlauf; wann der Index zum ersten Mal entsteht, sagt die Doku nicht. Sie nennt dafür den Ausweg: Der Index lässt sich von Hand neu bauen oder verdichten, beschrieben unter „Managing the LLM index“.

Der Dokumenten-Chat. Steht der Index, beantwortet ein Bedienelement in der Kopfleiste Fragen über die eigenen Dokumente, je nach Ansicht über eines oder über mehrere. Die Antworten verlinken die Dokumente, aus denen sie stammen.

Alle dreizehn Schalter mit PAPERLESS_AI_ davor

Nachgetragen am 05.09.2026: Hier standen bis dahin acht Schalter, ohne dass dabeistand, wie viele die Doku führt. Mit diesem Präfix sind es dreizehn, und die fünf, die fehlten, stehen jetzt mit drin. Zwei davon sind mehr als Beiwerk, siehe unten. Der Abschnitt „AI“ der Doku führt einen vierzehnten Eintrag ohne dieses Präfix, PAPERLESS_LLM_INDEX_TASK_CRON; der steht oben beim Index.

Alle Werte gehen als PAPERLESS_AI_* in die Umgebung oder in der Verwaltung unter Settings, Application Configuration. Steht ein Wert an beiden Stellen, gewinnt der aus der Datenbank.

Schalter Werte Ab Werk
PAPERLESS_AI_ENABLED der Hauptschalter false
PAPERLESS_AI_LLM_BACKEND ollama oder openai-like nicht gesetzt
PAPERLESS_AI_LLM_MODEL frei llama3.1 bei Ollama, gpt-3.5-turbo beim OpenAI-artigen
PAPERLESS_AI_LLM_ENDPOINT die Adresse des Dienstes nicht gesetzt, bei Ollama Pflicht
PAPERLESS_AI_LLM_API_KEY der Schlüssel beim Anbieter nicht gesetzt, beim OpenAI-artigen meist nötig
PAPERLESS_AI_LLM_OUTPUT_LANGUAGE die Sprache der Vorschläge nicht gesetzt, dann die Oberflächensprache des Benutzers oder gar nichts
PAPERLESS_AI_LLM_CONTEXT_SIZE Kontextfenster 8192
PAPERLESS_AI_LLM_REQUEST_TIMEOUT Sekunden bis zum Abbruch 120
PAPERLESS_AI_LLM_ALLOW_INTERNAL_ENDPOINTS ob Adressen auf private Netze zeigen dürfen true
PAPERLESS_AI_LLM_EMBEDDING_BACKEND huggingface, ollama, openai-like nicht gesetzt
PAPERLESS_AI_LLM_EMBEDDING_MODEL frei je nach Dienst, siehe unten
PAPERLESS_AI_LLM_EMBEDDING_ENDPOINT eigene Adresse für die Einbettung nicht gesetzt, dann die des Sprachmodells
PAPERLESS_AI_LLM_EMBEDDING_CHUNK_SIZE Größe der Textstücke für die Einbettung 1024

Pflicht sind der Hauptschalter und der Dienst. Beim lokalen Weg über ollama kommt PAPERLESS_AI_LLM_ENDPOINT mit der Adresse des eigenen Servers dazu; einen Standardwert dafür nennt die Doku nicht, sie muss also gesetzt werden. Beim Weg über einen fremden Anbieter ist stattdessen meist PAPERLESS_AI_LLM_API_KEY nötig.

Eine Falle steckt in der Einbettung: PAPERLESS_AI_LLM_EMBEDDING_ENDPOINT hat eine eigene Adresse, und fehlt sie, benutzt die Einbettung stillschweigend die des Sprachmodells. Wer beides auf verschiedene Dienste legen will, muss sie setzen.

Zwei Zahlen daran wiegen für eine kleine Karte schwerer, als sie aussehen. PAPERLESS_AI_LLM_CONTEXT_SIZE wird bei Ollama als num_ctx weitergereicht, damit ein Modell mit sehr großem nativem Kontextfenster nicht gleich auf voller Länge geladen wird. Und 120 Sekunden sind für langsame lokale Inferenz knapp; die Doku sagt selbst, dass man den Wert dort heraufsetzen soll.

Für die Einbettung nimmt huggingface das Modell sentence-transformers/all-MiniLM-L6-v2, Ollama embeddinggemma, der OpenAI-artige text-embedding-3-small. Der lokale Weg über huggingface lädt sein Modell beim ersten Lauf herunter, in das Datenverzeichnis von Paperless-ngx. Der erste Lauf braucht also Netz und Platz, danach nicht mehr.

Zwei der nachgetragenen Schalter sind mehr als Beiwerk. Der erste ist eine stille Falle: PAPERLESS_AI_LLM_EMBEDDING_CHUNK_SIZE steht ab Werk auf 1024, und die Doku sagt dazu, man solle den Wert senken, wenn der Dienst größere Eingaben ablehnt oder sie stillschweigend abschneidet, was die Suchgüte verdirbt. Abgelehnt merkt man; abgeschnitten nicht, und dann sucht man in Papieren, von denen nur der Anfang eingebettet ist.

Der zweite ist PAPERLESS_AI_LLM_OUTPUT_LANGUAGE, die Sprache der Vorschläge. Ohne Angabe nimmt Paperless-ngx die Oberflächensprache des Benutzers, und wenn auch die fehlt, gar nichts. Die Doku setzt dazu, dass das Ergebnis je nach Modell schwanken kann. Wer deutsche Papiere ablegt und englische Vorschläge zurückbekommt, sucht den Fehler sonst im Modell.

Die Sprache hängt aber nicht nur an diesem Schalter. Die Doku verweist bei beiden Modellangaben auf eine eigene Seite mit Modellempfehlungen: beim Sprachmodell wegen der Wahl zwischen lokal und fremd und wegen der Modellgröße, beim Einbettungsmodell ausdrücklich wegen der Sprache und der benötigten Ressourcen. Die drei Vorgabemodelle oben sind also Startwerte und keine Empfehlung für deutsche Papiere. Wer die Vorgabe übernimmt, bekommt keinen Fehler, sondern eine Suche, die schlechter findet, und das ist dieselbe stille Sorte wie bei der Stückgröße.

Die Stelle, an der es ernst wird

Die Doku schreibt es selbst als Warnung hin, und sie hat recht: Wer die Funktionen einschaltet, schickt Inhalt und Metadaten der Dokumente an den eingerichteten Dienst.

Ist dieser Dienst ein fremder, gehosteter Anbieter, verlassen die eigenen Papiere den eigenen Server, und es können Kosten entstehen. Die Doku rät ausdrücklich zu einem lokalen Dienst, wenn einem das etwas ausmacht: Ollama oder ein selbst betriebenes OpenAI-artiges Tor. Einen bestimmten Anbieter empfiehlt sie nicht und verweist auf dessen Bedingungen.

Bei einer Dokumentenablage ist das keine Formalie. Darin liegen Verträge, Rechnungen, Arztbriefe. Der Unterschied zwischen ollama und openai-like ist an dieser Stelle kein Geschmack, sondern die Frage, ob diese Papiere das Haus verlassen.

Dazu ein Satz aus den Sicherheitshinweisen der Doku, der in die andere Richtung zeigt und genauso schwer wiegt: Der Inhalt eines Dokuments geht als nicht vertrauenswürdige Daten an das Sprachmodell.

Ab Werk erlaubt Paperless-ngx KI-Adressen, die auf private Adressen zeigen, damit lokale Dienste überhaupt funktionieren. PAPERLESS_AI_LLM_ALLOW_INTERNAL_ENDPOINTS auf false schaltet das ab.

Was bleibt

Der lokale Weg führt über ollama als Dienst. Wie man vorher ausrechnet, welches Modell in die eigene Karte passt, steht in Lokale KI auf einer 12-GB-Karte.

Und der Hauptschalter bleibt ein Hauptschalter. Die Zuordnung ohne Sprachmodell läuft weiter, ob man ihn umlegt oder nicht.

Belege: die Dateien setup.md, advanced_usage.md und configuration.md aus dem Repo von Paperless-ngx, dazu die Release-Seite zu 3.1.0. Alle vier primär.

← Alle Notizen