- Python 84.8%
- JavaScript 15.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| RAG | ||
| .gitignore | ||
| DEPLOYMENT.md | ||
| LICENSE | ||
| README.md | ||
| THIRD_PARTY_NOTICES.md | ||
RAG – Dokumentverarbeitung und unabhängige Dokumentabfragen
Dieses Projekt verarbeitet Dokumente mit lokalen Sprachmodellen und macht ihren Inhalt für eine quellenbasierte Fragebeantwortung zugänglich. Es besteht aus zwei eigenständigen Anwendungen:
- RAG-OCR konvertiert PDFs, erkennt Text, erstellt Chunks und speichert Dokument-Embeddings in PostgreSQL.
- RAG-CHAT durchsucht einen importierten Dokumentbestand, bewertet Treffer optional mit einem Reranker und erzeugt Antworten mit Quellenangaben.
Die Übergabe erfolgt über einen versionierten PostgreSQL-Dump. Beide Anwendungen können auf getrennten Hosts laufen. Nach dem Import benötigt RAG-CHAT keine Verbindung zur OCR-Instanz.
Der eigene Anwendungscode steht unter der MIT-Lizenz.
Projektstatus
Das Projekt befindet sich in Entwicklung. Isolierte Regressionstests für Dokumentverarbeitung und Chat-Pipeline sind vorhanden. Ein vollständiger Integrationstest mit echten Modellservern sowie PostgreSQL/pgvector steht noch aus. Die dokumentierten Versionskombinationen sind deshalb als Ausgangsbasis zu verstehen, nicht als bestätigte Produktionsfreigabe.
Architektur
Instanz A: Dokumentverarbeitung
PDF → PNG → OCR → Chunking → Dokument-Embedding → PostgreSQL / pgvector
└──────┬──────┘ │
gemeinsames LLM │
Port 8081 versionierter DB-Dump
│
Instanz B: Dokumentabfragen ▼
Frage ─┬─ Query-Embedding → Vektorsuche ─┐ PostgreSQL / pgvector
└────────────────→ Volltextsuche ┤ ▲
│ liest importierten Bestand
▼
Zusammenführung per RRF
│
optionales Reranking
│
Chatmodell → Antwort
+ Quellen
Der Dump überträgt Tabellen, Dokumenttexte, Metadaten, Embeddings und Indexdefinitionen. PostgreSQL, die pgvector-Erweiterung und Modellgewichte werden auf der Zielinstanz separat bereitgestellt.
Funktionen
| Bereich | Funktionen |
|---|---|
| PDF-Verarbeitung | PDF-Seiten in PNGs konvertieren und als ZIP ausgeben |
| OCR | Bildseiten mit einem Vision-Modell in Markdown übertragen |
| Chunking | LLM-basiert, heuristisch oder mit fester Abschnittsgröße |
| Indexierung | JSONL einlesen, Embeddings in Batches erzeugen und speichern |
| Retrieval | Vektor- und deutsche Volltextsuche, Zusammenführung per Reciprocal Rank Fusion (RRF) |
| Reranking | Gemeinsame Suchkandidaten erneut anhand der Frage bewerten |
| Antwortgenerierung | Antwort mit Dokument-, Seiten- und Chunk-Referenzen |
| Nachvollziehbarkeit | Verarbeitungsprotokolle, Quellhashes und Chunk-Metadaten |
RAG-OCR bietet eine Gradio-Weboberfläche. RAG-CHAT stellt eine HTTP-API bereit; eine eigene Chat-Weboberfläche ist derzeit nicht enthalten. Audit-Logs dokumentieren die Verarbeitung und sind kein rechtlicher Konformitätsnachweis.
Modellaufteilung
| Instanz | Aufgabe | Standardmodell | Lokaler Port |
|---|---|---|---|
| Dokumentverarbeitung | OCR und LLM-Chunking gemeinsam | qwen3.5-4b-vl |
8081 |
| Dokumentverarbeitung | Dokument-Embeddings | qwen3-embedding-0.6b, 1024 Dimensionen |
8083 |
| Dokumentabfragen | Query-Embeddings | Dasselbe Embedding-Modell wie beim Dokumentbestand | 8083 |
| Dokumentabfragen | Reranking | qwen3-reranker-0.6b |
8084 |
| Dokumentabfragen | Chat-Antwort | qwen3-8b, konfigurierbar |
8081 |
Dokument- und Query-Embedder müssen zusammenpassen: Modellrevision, Vektordimensionen und Vorverarbeitung gehören zur Beschreibung des Datenbestands. Der Chat prüft die Länge zurückgegebener Embeddings; eine automatische Prüfung der Modellrevision ist noch nicht implementiert.
OCR und Chunking verwenden dasselbe Vision-Modell. Das Chatmodell ist unabhängig davon austauschbar. Auch ein Wechsel des Rerankers erfordert keine neuen Dokument-Embeddings; sein Modellname ist derzeit im Chat-Client fest eingetragen.
CPU-/GPU-Zuweisung erfolgt beim Start der llama.cpp-Server. Beispielsweise können die kleinen Embedding- und Reranking-Modelle auf der CPU laufen, während das Vision- oder Chatmodell die GPU verwendet. Das ist eine feste Aufgabenverteilung; automatisches Load Balancing ist nicht implementiert.
Die Ports gelten pro Host. Wenn beide Instanzen auf demselben Host laufen, müssen getrennte Server mit kollidierenden Ports entsprechend umkonfiguriert werden.
Verzeichnisstruktur
.
├── README-MAIN.md # Diese Projektübersicht
├── LICENSE # MIT-Lizenz des eigenen Anwendungscodes
├── THIRD_PARTY_NOTICES.md # Hinweise zu Drittsoftware und Daten
├── DEPLOYMENT.md # Ergänzende Deployment-Hinweise
└── RAG/
├── RAG-OCR/
│ ├── main.py # Gradio-Anwendung
│ ├── config/ # Gemeinsame OCR-/Chunking-Konfiguration
│ ├── core/ # Dokumentverarbeitung und Indexierung
│ ├── ui/ # Oberfläche und Event-Handler
│ ├── utils/ # Datei-, Prompt- und Validierungsfunktionen
│ ├── tests/ # Python-Regressionstests
│ └── requirements.txt
├── RAG-CHAT/
│ ├── src/ # Datenbank, Modell-Client, Retrieval und API
│ ├── test/ # Node.js-Regressionstests
│ ├── .env.example
│ └── package.json
└── pgvector/ # Separater Drittanbieter-Quellcode
Voraussetzungen
Dokumentverarbeitung
- Python 3.12 oder neuer und die Pakete aus
RAG/RAG-OCR/requirements.txt - Poppler für die PDF-Konvertierung
- llama.cpp-Server für das gemeinsame Vision-Modell und den Embedder
- PostgreSQL mit installierter pgvector-Erweiterung
Dokumentabfragen
- Node.js mit den im Code verwendeten APIs, mindestens Version 18; für den Betrieb eine noch gepflegte Version verwenden
- npm und die Abhängigkeiten aus
RAG/RAG-CHAT/package-lock.json - Eigene PostgreSQL-/pgvector-Installation mit importiertem Dokumentbestand
- llama.cpp-Server für Query-Embedding, optionales Reranking und Chat
PostgreSQL und pgvector installiert und administriert der Betreiber. Als Ausgangsbasis ist PostgreSQL 16 mit pgvector 0.8.5 dokumentiert. Für eine Freigabe sollten beide Instanzen dieselbe PostgreSQL-Hauptversion und pgvector-Version verwenden und mit einem echten Dump geprüft werden.
Bei eigenen Builds wird derselbe festgelegte pgvector-Quellstand auf jedem Host passend zur dortigen PostgreSQL-Installation und CPU kompiliert. Mitgelieferte Quellen ersetzen keine Installation. Offizielle Anleitungen: PostgreSQL und pgvector.
Modellgewichte und deren Serverkonfiguration werden separat bereitgestellt. Startparameter, Bildprojektoren und Reranking-Unterstützung hängen vom gewählten Modell und der llama.cpp-Version ab.
RAG-OCR installieren und starten
Die folgenden Befehle beginnen im Wurzelverzeichnis des ausgecheckten Repositorys:
cd RAG/RAG-OCR
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt
python main.py
Anschließend ist die Oberfläche unter http://localhost:7860 erreichbar. Die Modellserver und die Datenbank müssen für die jeweiligen Verarbeitungsschritte bereits laufen.
Optional eine user_config.json im Verzeichnis RAG/RAG-OCR anlegen:
{
"LLAMA_OCR_URL": "http://localhost:8081/v1/chat/completions",
"CHUNKING_DEFAULT_MODEL": "qwen3.5-4b-vl",
"MAX_THREADS": 1,
"MAX_IMAGE_SIZE_MB": 10,
"API_TIMEOUT": 120
}
CHUNKING_DEFAULT_MODEL bezeichnet trotz des historischen Namens das gemeinsame Modell für OCR und Chunking. Der Chunking-Endpunkt wird an LLAMA_OCR_URL angeglichen. Diese Endpunkte sind in der Konfiguration auf localhost beziehungsweise 127.0.0.1 beschränkt.
Die Datenbankverbindung und die Embedding-Batch-Größe werden im Indexing-Tab eingestellt. RAG-OCR liest nicht die .env der Chat-Anwendung.
Dokumente verarbeiten
- PDF im Konverter hochladen und das erzeugte PNG-ZIP entpacken.
- Bildseiten im OCR-Tab verarbeiten.
- Die Markdown-Ausgabe im Chunking-Tab aufteilen.
- Die erzeugte JSONL-Datei im Indexing-Tab hochladen; ein ZIP zuvor entpacken.
- Embedding-Server und Datenbankverbindung einstellen und indexieren.
- Den fertigen Datenbestand als versionierten Dump exportieren.
Beim erneuten Indexieren werden bestehende Chunk-IDs aktualisiert. Ältere IDs, die im neuen Import nicht mehr vorkommen, werden nicht automatisch gelöscht. Für einen vollständigen neuen Dokumentstand deshalb eine frische Datenbank verwenden.
Datenbestand an die Abfrageinstanz übergeben
Der Betreiber richtet Datenbanken, Rollen und Berechtigungen auf beiden Hosts ein. pgvector muss auf dem Zielhost verfügbar sein; das Erstellen der Extension kann zusätzliche Datenbankrechte benötigen.
Verbindungsdaten für die folgenden Werkzeuge beispielsweise über PGHOST, PGPORT, PGUSER und .pgpass konfigurieren.
Auf der Verarbeitungsinstanz exportieren:
pg_dump --dbname=rag_db --format=custom --no-owner --no-acl --file=rag-v1.dump
sha256sum rag-v1.dump
Dump und Versionsmanifest auf die Abfrageinstanz übertragen. Die Prüfsumme dort mit dem dokumentierten Wert vergleichen.
Auf der Abfrageinstanz in eine zuvor angelegte, leere Datenbank importieren:
pg_restore --dbname=rag_import --no-owner --no-acl --exit-on-error rag-v1.dump
DB_NAME der Chat-Anwendung anschließend auf rag_import setzen. Der Import in eine neue Datenbank ermöglicht es, einen neuen Dokumentstand vor dem Umschalten zu prüfen.
Versionsmanifest
Zu jedem Dump eine separate Datei mit folgenden Angaben archivieren:
- Release-Kennung, Erstellungszeit, Dump-Dateiname und SHA256
- Tatsächliche PostgreSQL- und pgvector-Version
- Schema-Version und Beschreibung des Dokumentbestands
- Embedding-Modell, genaue Revision oder Dateiprüfsumme, Quantisierung und Dimensionen
- Textvorverarbeitung, llama.cpp-Version und Embedding-Serverparameter
Das Manifest wird derzeit manuell gepflegt. Es wird nicht automatisch vom Import oder der Anwendung ausgewertet.
Nach dem Import kontrollieren:
SHOW server_version;
SELECT extversion FROM pg_extension WHERE extname = 'vector';
SELECT format_type(atttypid, atttypmod)
FROM pg_attribute
WHERE attrelid = 'document_chunks'::regclass AND attname = 'embedding';
SELECT count(*) FROM document_chunks;
Für die aktuelle Konfiguration wird vector(1024) erwartet. Danach eine bekannte Frage samt erwarteter Dokumentquelle prüfen. Ein Wechsel des Chatmodells erfordert keinen neuen Dump; ein Wechsel des Embedding-Modells erfordert neue Dokument-Embeddings.
RAG-CHAT installieren und starten
Ausgehend vom Wurzelverzeichnis:
cd RAG/RAG-CHAT
npm ci
cp .env.example .env
Die .env vor dem Start an die eigene Installation anpassen. Beispielsweise:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=rag_import
DB_USER=rag_user
DB_PASSWORD=CHANGE_ME
LLAMA_EMBEDDING_URL=http://localhost:8083/v1/embeddings
LLAMA_RERANK_URL=http://localhost:8084/v1/rerank
LLAMA_CHAT_URL=http://localhost:8081/v1/chat/completions
EMBEDDING_MODEL=qwen3-embedding-0.6b
EMBEDDING_DIM=1024
CHAT_MODEL=qwen3-8b
RETRIEVE_TOP_K=20
RERANK_CANDIDATES=30
RERANK_TOP_K=5
LLM_TOP_K=5
PORT=3000
CHANGE_ME ist ein Platzhalter für das selbst eingerichtete Datenbankpasswort.
npm start
Für Entwicklung mit automatischem Neustart steht npm run dev bereit.
Suchverhalten
Vektor- und Volltextsuche liefern jeweils bis zu 20 Treffer. RRF führt die Treffer anhand ihrer Rangpositionen zusammen, entfernt doppelte Chunk-IDs und begrenzt den gemeinsamen Bestand auf 30 Kandidaten.
Mit Reranking werden diese Kandidaten erneut bewertet und bis zu fünf Treffer zurückgegeben. Das Chatmodell erhält höchstens fünf Textabschnitte. Ohne Reranking bleibt die Reihenfolge der RRF-Suche erhalten. RRF-Scores sind keine Relevanzwahrscheinlichkeiten; ein früherer MIN_RELEVANCE-Grenzwert wird nicht mehr verwendet.
API
| Methode | Pfad | Funktion |
|---|---|---|
GET |
/health |
Status des API-Prozesses |
GET |
/documents |
Dokumente im importierten Bestand auflisten |
POST |
/rag/retrieve |
Suchtreffer, optional mit Reranking |
POST |
/rag/query |
Antwort mit Quellen erzeugen |
/health prüft derzeit nicht die Erreichbarkeit der Datenbank oder Modellserver.
Antwort mit Reranking:
curl -X POST http://localhost:3000/rag/query \
-H 'Content-Type: application/json' \
-d '{"question":"Welche Themen behandelt das Dokument?","withRerank":true}'
Nur hybride Suche ohne Antwortgenerierung:
curl -X POST http://localhost:3000/rag/retrieve \
-H 'Content-Type: application/json' \
-d '{"question":"Netzwerkkonfiguration","withRerank":false}'
Das optionale Feld documentId beschränkt die Suche auf eine vorhandene Dokument-ID. Verfügbare IDs liefert /documents. withRerank in Anfragen ausdrücklich setzen, um das gewünschte Verhalten festzulegen.
Tests
Ausgehend vom Wurzelverzeichnis, nach Installation der jeweiligen Abhängigkeiten:
RAG/RAG-OCR/.venv/bin/python -m unittest discover -s RAG/RAG-OCR/tests -v
npm test --prefix RAG/RAG-CHAT
Die Tests prüfen unter anderem Chunk-Grenzen und Überlappungen, PDF-Uploadverarbeitung, Embedding-Dimensionen, SQL-Parameter und den gemeinsamen Kandidatenbestand für Reranking. Externe Dienste werden dabei durch Testdoubles ersetzt.
Für eine Freigabe zusätzlich einen vollständigen Durchlauf durchführen: Dokument verarbeiten, indexieren, Dump übertragen, importieren und eine bekannte Frage mit überprüfbarer Quelle beantworten.
Betrieb und bekannte Grenzen
- Die OCR-Oberfläche bindet derzeit an
0.0.0.0; die Anwendungen enthalten keine eigene Benutzeranmeldung. Zugriff im vorgesehenen privaten Netz beziehungsweise über vorgeschaltete Zugriffskontrolle bereitstellen. - Zugangsdaten gehören in die lokale Konfiguration, nicht ins Repository.
- CPU-Reranking kann je nach Kandidatenzahl und Textlänge die Antwortzeit erhöhen. Die Suchparameter anhand eigener Dokumente messen und anpassen.
- Chunkpositionen können
nullsein, wenn ein erzeugter Textabschnitt nicht zuverlässig im Original lokalisiert werden kann. - Bei Fehlern des Chunking-Modellservers kann die Verarbeitung auf feste Split-Positionen zurückfallen.
- Generierte Antworten sollten anhand der angegebenen Quellen überprüft werden.
Weiterführende Dokumentation
- RAG-OCR: Anwendung und Konfiguration
- RAG-OCR: Architektur
- RAG-OCR: Änderungsprotokoll
- RAG-CHAT: API und Konfiguration
- Deployment und Versionsvertrag
- Drittsoftware und Daten
Die ergänzenden Dokumente stammen aus unterschiedlichen Projektständen und können noch ältere Pfadangaben enthalten. Die Befehle dieser Übersicht verwenden die aktuelle Struktur unter RAG/.
Beiträge
Fehlerberichte und Verbesserungsvorschläge können über die Issues des Forgejo-Repositorys eingereicht werden. Für reproduzierbare Fehlerberichte sind Anwendungsschritt, Modell- und Softwareversionen sowie eine bereinigte Fehlermeldung hilfreich. Zugangsdaten und vertrauliche Dokumentinhalte aus Beispielen entfernen.
Änderungen können als Pull Request mit kurzer Beschreibung und passenden Tests vorgeschlagen werden.
Lizenz
Der eigene Anwendungscode von RAG-OCR und RAG-CHAT steht unter der MIT-Lizenz.
Der separat enthaltene pgvector-Quellcode behält seine PostgreSQL-Lizenz. Python-/Node-Abhängigkeiten und separat bezogene Modellgewichte unterliegen ihren jeweiligen Lizenzen. Die Anwendungslizenz erfasst keine hochgeladenen Dokumente oder daraus erzeugten Daten.