Skip to content

Repository files navigation

GroundedRAG

RAG-Plattform für Firmendaten — finden und nutzen, ohne Halluzination.

Unternehmen können ihre eigenen Dokumente und Datenbanken abfragen und finden exakt die gesuchte Information, statt sich durch Ordner und Support-Tickets zu wühlen. Der Unterschied zu gewöhnlichem RAG: Halluzination ist hier strukturell ausgeschlossen — nicht per Prompt erhofft, sondern per Code erzwungen.

Lokal-first, DSGVO-bewusst: SQLite statt Cloud-Vektor-DB, LLM via lokalem Ollama, keinerlei externe Requests. Läuft komplett offline — auch ganz ohne LLM (extraktiver Modus).

Das Kernprinzip: LLM schlägt vor, Code entscheidet

Jede Anfrage durchläuft zwei deterministische Gates:

Frage ──► Hybrid-Retrieval (BM25 + Vektor, RRF)
              │
              ├─ Gate 1: Konfidenz < Schwellwert? ──────────► ✘ REFUSED
              │            (keine belastbare Quelle = keine Antwort)
              ▼
          LLM-Vorschlag (strukturiert: Antwort + Zitate)
              │
              ├─ Gate 2: Jedes Zitat wörtlich gegen die
              │          Quelle geprüft. Erfundene chunk_id
              │          oder nicht auffindbares Zitat ⇒ raus.
              │
              ├─ kein Zitat überlebt? ──────────────────────► ≡ EXTRAKTIV
              │            (wörtliche Quellpassagen statt LLM-Text)
              ▼
          ✔ ANSWERED — jede Aussage belegt und verifiziert

Drei mögliche Ausgänge, alle ehrlich:

Status Bedeutung
ANSWERED LLM-Antwort, jedes Zitat deterministisch verifiziert (wörtlich in der Quelle vorhanden)
EXTRACTIVE Wörtliche Passagen aus den Quellen — per Konstruktion halluzinationsfrei (kein LLM beteiligt)
REFUSED Quellenlage unzureichend — das System sagt lieber „weiß ich nicht" als zu raten

Schnellstart für Dritte (ohne Vorwissen)

Ein-Befehl-Installation (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/Rawkeep/grounded-rag/main/install.sh | bash

Der Installer holt den Code nach ~/grounded-rag, startet per Docker (falls vorhanden, sonst per Python-venv), wartet auf die App und öffnet den Browser. Erneutes Ausführen aktualisiert und startet neu. Solange das Repo privat ist, funktioniert der curl-Weg nur mit GitHub-Zugriff — Alternative:

git clone https://github.com/Rawkeep/grounded-rag && ./grounded-rag/install.sh

Optionen per Umgebungsvariable: GRAG_PORT=9090, GRAG_USE=docker|python, GRAG_HOME=/pfad, GRAG_NO_BROWSER=1.

Mit Docker (manuell):

docker compose up -d
docker compose logs grounded-rag     # API-Key steht hier im Log

Dann http://localhost:8080 öffnen, den API-Key aus dem Log ins Key-Feld eintragen, Dokumente per Upload hinzufügen, fragen. Daten liegen im Volume grag-data; ein Ollama auf dem Host wird automatisch genutzt (host.docker.internal:11434), ohne Ollama läuft der extraktive Modus. Eigenen Key dauerhaft setzen: GRAG_API_KEY=… in eine .env neben der docker-compose.yml.

Ohne Docker (macOS/Linux, Python ≥ 3.9):

./start.sh

Legt beim ersten Lauf automatisch ein venv an, installiert alles und startet die Web-UI auf http://127.0.0.1:8080.

Schnellstart

pip install -e .              # Kern (nur pydantic)
python demo.py                # End-to-End-Demo, kein Ollama nötig

# Dokumente indexieren (txt, md, csv, docx, pdf*, html, json)
grounded-rag ingest ./handbuch ./tickets/export.csv --collection hr

# Ordner dauerhaft überwachen: neue/geänderte/gelöschte Dateien automatisch syncen
grounded-rag watch ./handbuch --collection hr --interval 30   # --once = ein Durchlauf

# SQLite-Datenbank indexieren (z. B. CRM, Ticketsystem)
grounded-rag ingest-db crm.db tickets --id-column id

# IMAP-Postfach indexieren (Passwort via GRAG_IMAP_PASSWORD oder Prompt)
grounded-rag ingest-mail mail.firma.de support@firma.de --folder INBOX --limit 200

# Fragen stellen (optional pro Collection)
grounded-rag query "Wie viele Urlaubstage stehen mir zu?" --collection hr
grounded-rag stats

# Web-UI + HTTP-API (Extra .[api])
grounded-rag serve            # UI: http://127.0.0.1:8080  ·  API-Docs: /docs

* PDF benötigt pip install -e ".[pdf]", API pip install -e ".[api]".

Mit lokalem LLM (empfohlen): Ollama starten, Modelle ziehen (ollama pull nomic-embed-text llama3.2:3b) — GroundedRAG nutzt sie automatisch. Ohne Ollama fällt das System still auf den deterministischen Hash-Embedder und extraktive Antworten zurück — es bleibt voll funktionsfähig.

Konfiguration über Umgebungsvariablen (Präfix GRAG_), siehe .env.example. Alle Schwellwerte zentral in grounded_rag/config.py — keine Magic Numbers im Code.

Architektur

Modul Aufgabe
models.py Pydantic-Vertrag (Single Source of Truth)
chunking.py Deterministisches, absatzbasiertes Chunking
ingest.py Dateien (txt/md/csv/docx/pdf/html/json), SQLite-Tabellen, IMAP-Postfächer → Index
folder_sync.py Ordner als dauerhafte Quelle: Sync + Watch (Polling, idempotent)
store.py SQLite: Dokumente, Chunks, FTS5-Volltext, Embeddings, Collections
embeddings.py Ollama-Embeddings, dep-freier Hash-Fallback
retrieval.py Hybrid: BM25 + Kosinus, RRF-Fusion, Phrasen-Re-Rank, Konfidenz
grounding.py Kern-IP: die deterministischen Grounding-Gates
llm.py Ollama-Chat mit JSON-Schema-erzwungener Ausgabe
answer.py Orchestrierung Retrieval → Gates → Antwort
api.py / cli.py FastAPI-Server + Web-UI / Kommandozeile
eval/ Eval-Suite als Regressions-Gate (python -m grounded_rag.eval.run)
static/index.html Web-UI — vanilla JS, kein CDN, dark/light

Mandantentrennung: Jedes Dokument gehört zu einer collection (z. B. hr, export, Kunde X); Abfragen können darauf eingeschränkt werden.

API-Absicherung: GRAG_API_KEY setzen ⇒ alle Endpunkte außer /health verlangen X-API-Key. Ohne Key startet serve ausschließlich auf localhost.

Qualitätssicherung

python -m pytest -q                 # 49 Tests
python -m grounded_rag.eval.run     # Eval-Suite, Exit ≠ 0 bei Regression

Die Testsuite deckt explizit die Halluzinations-Abwehr ab: erfundene Chunk-IDs, nicht belegbare Zitate, themenfremde Fragen, leerer Index, LLM-Ausfall — jeder Fall endet nachweislich in EXTRACTIVE oder REFUSED, nie in einer unbelegten Antwort. Die Eval-Suite ist das Regressions-Gate fürs Threshold-Tuning: Erwartungen dort bewusst mitziehen, nie lockern.

Roadmap

  • API-Key-Auth + Collections (Mandantentrennung) — v0.2
  • Web-UI (vanilla JS, kein CDN, dark/light) — v0.2
  • Konnektoren: DOCX (stdlib), IMAP-Postfächer — v0.2
  • Deterministisches Phrasen-Re-Ranking — v0.2
  • Eval-Suite als Regressions-Gate — v0.2
  • Docker-Image + Compose + start.sh + GHCR-Publishing — v0.3
  • WhatsApp-HR-Agent (Baileys-Gateway, Prototyp) — v0.4
  • Visuelle Quellen-Suche (grounded-rag visual, PixelRAG-PoC, PIXELRAG.md)
  • Cross-Encoder-Re-Ranking (lokal, optional)
  • SharePoint-/Confluence-Export-Konnektor
  • Deployment-Rezept Fly.io/Railway (Muster aus EIS/CK)
  • Antwort-Streaming in der UI

Dokumentation

Dokument Inhalt
docs/BENUTZERHANDBUCH.md Start, Ingest, UI/CLI/API, Konfiguration, Troubleshooting
docs/ARCHITEKTUR.md Datenfluss, Module, Design-Entscheidungen, Tuning
docs/SICHERHEIT-DSGVO.md Zugriffsschutz, Datenhaltung, Löschung, Grenzen
WHATSAPP-HR-AGENT.md WhatsApp-Gateway (Prototyp): Setup, Architektur, Rechtliches, Demo-Video
CHANGELOG.md Versionshistorie
CLAUDE.md Invarianten & Qualitäts-Gate für die Entwicklung

Einordnung ins Portfolio

Eigenständiges Produkt neben OrgMind (Enterprise-Wissensplattform): GroundedRAG ist die fokussierte, einbettbare RAG-Engine — klein genug, um sie in Kundenprojekte (RAQ/EIS, BrokerPilot, sap-agent) zu integrieren, mit der Grounding-Garantie als Alleinstellungsmerkmal.

About

RAG ohne Halluzination: jede Antwort quellenverifiziert oder verweigert. Lokal-first (SQLite + Ollama), läuft komplett offline.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages