Pragmatische Technik aus der Praxis

AI Office. Wie ich mein Dokumentenarchiv mit Paperless und KI erweitert habe

Papier ist selten das eigentliche Problem. Das Problem ist das Wiederfinden.

Rechnungen. Verträge. Bescheide. Sitzungsunterlagen. Alles wird heute zwar digital abgelegt, aber die klassische Dateisuche bleibt mühsam. Man erinnert sich selten an Dateinamen. Man erinnert sich an Inhalte.

Genau hier setzt mein Projekt an. Ein persönliches AI Office.

Die Basis bildet Paperless ngx. Darauf läuft eine zusätzliche KI Ebene, die Dokumente automatisch analysiert, zusammenfasst, verschlagwortet und für semantische Suche vorbereitet. Alles läuft auf eigener Infrastruktur.


Ziel
Dokumente nicht mehr suchen. Dokumente fragen.


Architektur

Das System besteht aus wenigen klar getrennten Komponenten.

Scanner oder Upload
→ Paperless ngx
→ Dokumentexport über API
→ KI Verarbeitung
→ Vektor Datenbank
→ RAG API
→ Fragen und Antworten

Das bedeutet konkret

Paperless übernimmt

OCR
Dokumentenverwaltung
Originaldateien
Metadaten

Die KI übernimmt

Zusammenfassungen
automatische Tags
semantische Suche
Fragen über Dokumente

Das Ergebnis ist ein Dokumentenarchiv, das nicht nur speichert, sondern Inhalte versteht.


Paperless als Grundlage

Paperless ngx ist ein Dokumentenmanagementsystem für selbstgehostete Umgebungen. Dokumente werden automatisch importiert, per OCR erkannt und archiviert.

Ein typisches Docker Setup sieht zum Beispiel so aus.

docker compose

version: "3.8"

services:

  redis:
    image: redis:7
    restart: unless-stopped

  db:
    image: postgres:15
    restart: unless-stopped
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - redis
      - db
    ports:
      - 8000:8000
    environment:
      PAPERLESS_REDIS: redis://redis:6379
      PAPERLESS_DBHOST: db
      PAPERLESS_DBNAME: paperless
      PAPERLESS_DBUSER: paperless
      PAPERLESS_DBPASS: paperless
    volumes:
      - ./data:/usr/src/paperless/data
      - ./media:/usr/src/paperless/media
      - ./consume:/usr/src/paperless/consume
Code-Sprache: JavaScript (javascript)

Der consume Ordner ist dabei entscheidend. Alles was dort abgelegt wird, wird automatisch von Paperless importiert.

Scanner, Mailregeln oder Automationen können Dokumente dort einfach ablegen.


Zugriff auf Dokumentinhalte

Für die KI Verarbeitung müssen die OCR Texte der Dokumente verfügbar sein. Paperless stellt dafür eine API bereit.

Ein einfaches Python Beispiel zeigt, wie Dokumente abgefragt werden können.

import requests

URL = "http://paperless:8000/api/documents/"
TOKEN = "API_TOKEN"

headers = {
    "Authorization": f"Token {TOKEN}"
}

r = requests.get(URL, headers=headers)

for doc in r.json()["results"]:
    print(doc["title"], doc["content"])
Code-Sprache: JavaScript (javascript)

Das Feld content enthält den vollständigen OCR Text eines Dokuments. Genau dieser Text wird später von der KI analysiert.


Konfiguration der KI Umgebung

Alle zentralen Einstellungen werden in einer Konfigurationsdatei zusammengefasst.

config/settings.py

import os
from dotenv import load_dotenv

load_dotenv()

PAPERLESS_URL = os.getenv("PAPERLESS_URL")
PAPERLESS_TOKEN = os.getenv("PAPERLESS_TOKEN")

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

CHROMA_PATH = os.getenv("CHROMA_PATH", "./vector_db")

EMBEDDING_MODEL = "text-embedding-3-small"
CHAT_MODEL = "gpt-4o-mini"
Code-Sprache: JavaScript (javascript)

Die sensiblen Werte liegen in einer .env Datei.

Beispiel

PAPERLESS_URL=http://paperless:8000
PAPERLESS_TOKEN=

OPENAI_API_KEY=

CHROMA_PATH=./vector_db
Code-Sprache: JavaScript (javascript)

Dokumente für semantische Suche vorbereiten

Der erste KI Schritt ist die Erstellung eines semantischen Indexes.

Dabei werden Dokumente in kleinere Textabschnitte zerlegt und für jeden Abschnitt sogenannte Embeddings erzeugt. Diese numerischen Vektoren repräsentieren die Bedeutung des Textes.

scripts/index_documents.py

from openai import OpenAI
import chromadb
from scripts.export_documents import get_documents
from config.settings import *

client = OpenAI(api_key=OPENAI_API_KEY)

chroma = chromadb.PersistentClient(path=CHROMA_PATH)

collection = chroma.get_or_create_collection("documents")


def split_text(text, size=500):

    words = text.split()

    for i in range(0, len(words), size):
        yield " ".join(words[i:i+size])


def index_document(doc):

    text = doc["content"]

    chunks = list(split_text(text))

    for i, chunk in enumerate(chunks):

        emb = client.embeddings.create(
            model=EMBEDDING_MODEL,
            input=chunk
        )

        collection.add(
            ids=[f"{doc['id']}_{i}"],
            documents=[chunk],
            embeddings=[emb.data[0].embedding]
        )
Code-Sprache: JavaScript (javascript)

Die erzeugten Vektoren werden in einer lokalen Vektor Datenbank gespeichert.

Ein einfacher Ordner genügt.

mkdir vector_db

Automatische Zusammenfassungen

Beim Import eines neuen Dokuments kann automatisch eine Kurzfassung erzeugt werden.

scripts/summarize.py

from openai import OpenAI
from config.settings import *

client = OpenAI(api_key=OPENAI_API_KEY)


def summarize(text):

    prompt = f"""
    Fasse dieses Dokument in drei Sätzen zusammen.

    {text}
    """

    r = client.chat.completions.create(
        model=CHAT_MODEL,
        messages=[{"role":"user","content":prompt}]
    )

    return r.choices[0].message.content
Code-Sprache: PHP (php)

Die Zusammenfassung kann später direkt im Dokument angezeigt werden.


Automatisches Tagging

Neben der Zusammenfassung werden auch Tags automatisch generiert.

scripts/auto_tag.py

from openai import OpenAI
from config.settings import *

client = OpenAI(api_key=OPENAI_API_KEY)

def generate_tags(text):

    prompt = f"""
    Analysiere das Dokument und gib maximal fünf Tags zurück.
    Nur einzelne Wörter.

    {text}
    """

    r = client.chat.completions.create(
        model=CHAT_MODEL,
        messages=[{"role":"user","content":prompt}]
    )

    tags = r.choices[0].message.content

    return [t.strip() for t in tags.split("\n") if t.strip()]
Code-Sprache: PHP (php)

Diese Tags können anschließend automatisch über die Paperless API im Dokument gespeichert werden.

Damit entsteht mit der Zeit ein sauber strukturiertes Archiv.


Dokumente über Fragen durchsuchen

Der interessanteste Teil ist die RAG API.

RAG steht für Retrieval Augmented Generation.

Zuerst werden passende Dokumentabschnitte gefunden.
Dann erzeugt das Sprachmodell daraus eine Antwort.

api/rag_api.py

from fastapi import FastAPI
import chromadb
from openai import OpenAI
from config.settings import *

app = FastAPI()

client = OpenAI(api_key=OPENAI_API_KEY)

chroma = chromadb.PersistentClient(path=CHROMA_PATH)

collection = chroma.get_collection("documents")


@app.get("/ask")

def ask(q: str):

    emb = client.embeddings.create(
        model=EMBEDDING_MODEL,
        input=q
    )

    results = collection.query(
        query_embeddings=[emb.data[0].embedding],
        n_results=5
    )

    context = "\n".join(results["documents"][0])

    prompt = f"""
    Nutze diese Dokumente um die Frage zu beantworten.

    {context}

    Frage: {q}
    """

    answer = client.chat.completions.create(
        model=CHAT_MODEL,
        messages=[{"role":"user","content":prompt}]
    )

    return {
        "answer": answer.choices[0].message.content
    }
Code-Sprache: PHP (php)

Die API kann anschließend gestartet werden.

uvicorn api.rag_api:app --host 0.0.0.0 --port 9000
Code-Sprache: CSS (css)

Automatische Aktualisierung

Der Dokumentindex sollte regelmäßig aktualisiert werden. Eine einfache Cron Aufgabe reicht aus.

0 3 * * * python3 /srv/paperless_ai/scripts/index_documents.py

Damit wird jede Nacht der semantische Index aktualisiert.


Ergebnis

Nach kurzer Zeit entsteht ein intelligentes Dokumentarchiv.

Dokumente werden automatisch

importiert
analysiert
zusammengefasst
getaggt
semantisch indexiert

Danach können Fragen gestellt werden wie

Welche Rechnungen habe ich vom Energieversorger
Wann war die letzte Heizungswartung
Welche Dokumente betreffen meine Gebäudeversicherung

Die KI durchsucht automatisch alle Dokumente und liefert die Antwort.


Fazit

Paperless löst das Archivierungsproblem.

KI löst das Informationsproblem.

Die Kombination macht aus einem klassischen Dokumentenarchiv ein persönliches Wissenssystem.

Dokumente liegen nicht mehr einfach nur im Speicher.
Sie werden verstanden, strukturiert und jederzeit abrufbar.

Ein echtes AI Office.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.