Fallstudie · AI-Engineering

PflegeLotse

DSGVO-konformer KI-Assistent für das Pflege-Recht (SGB XI). RAG-System mit quellenbelegten Antworten, Anti-Halluzination und messbarer Qualität — EU- oder lokal gehostet.

Python · FastAPIpgvectormultilingual-E5 Mistral / OllamaJinja2 · HTMXDocker Limber Martinez · 2026

Management Summary

PflegeLotse beantwortet Fragen zum SGB XI ausschließlich aus dem amtlichen Gesetzestext, belegt jede Aussage mit dem Paragraphen und verweigert ehrlich die Antwort, wenn keine Quelle trägt. Das Projekt zeigt End-to-End-Kompetenz: Clean Architecture, eine eigene RAG-Pipeline, eine quantitative Evaluations-Pipeline (Recall@5 80 %, 0 Halluzinationen auf Out-of-Scope-Fragen), DSGVO-/EU-AI-Act-Konformität, Tests, CI/CD und ein reproduzierbares Docker-Deployment.

1Projektumfeld & Ausgangssituation

Pflegekräfte, Pflegeberatung und Angehörige müssen Leistungsansprüche nach dem Elften Sozialgesetzbuch (SGB XI) schnell und korrekt einschätzen. Die Recherche im Gesetzestext ist zeitaufwändig; generische Chatbots halluzinieren — bei Rechtsfragen inakzeptabel.

Problem. Es fehlt ein Assistent, der NUR aus dem Gesetz antwortet, die Quelle (§) nennt und bei Unsicherheit ehrlich abbricht — statt plausibel klingender, falscher Auskünfte.

2Projektziel & Anforderungen

Projektziel

Ein in Produktion deploytes RAG-System, das Fragen zu SGB XI mit quellenbelegten Antworten beantwortet, Halluzinationen durch striktes Grounding und Abstention verhindert und seine Qualität messbar macht.

Funktionale Anforderungen
  • Frage (DE) → Antwort mit §-Zitaten
  • Sichtbare Quellenangabe (Originaltext + Link)
  • „Ich weiß nicht" bei schwachem Retrieval
  • Umschaltung EU-Cloud (Mistral) / Lokal (Ollama)
Nicht-funktionale Anforderungen
  • DSGVO/EU-AI-Act-Konformität, RDG-Disclaimer
  • Antwortzeit p50 ~1 s
  • WCAG 2.1 AA, self-hosted Fonts
  • Reproduzierbar (Docker), getestet, CI-grün

Abgrenzung: keine Rechtsberatung (RDG), keine Speicherung personenbezogener Daten, Korpus auf SGB XI begrenzt.

3Projektplanung

Inkrementelles, nachvollziehbares Vorgehen in 6 Phasen — jede Phase lässt etwas Lauffähiges und Commitfähiges zurück (TDD, CI-grün vor dem Weitergehen).

PhaseInhaltErgebnis
0 SetupClean-Arch-Gerüst, Docker, CI, ADRsLauffähiges Skelett
1 IngestSGB-XI-XML → §-Chunks → E5 → pgvector235 §§ durchsuchbar
2 RAG-Core/ask: Retrieval + Grounding + LLM + CitationsAntworten mit Belegen
3 EvaluationGolden-Set, Metriken, TuningRecall@5 80 %, 0 Halluzinationen
4 FrontendChat (Jinja2/HTMX), Zustände, a11yBediente UI
5 DeployVPS, Caddy, Subdomain, DokuÖffentlich erreichbar

4Architektur & Entwurf

Clean Architecture

Abhängigkeiten zeigen nach innen; die Domäne kennt keine Frameworks. Ports (Protokolle) in der Domäne, konkrete Adapter in der Infrastruktur — LLM/Embedder/DB sind austauschbar.

api — FastAPI · Jinja2 + HTMX · Templates/Static (Routen /, /ask, /info, Legal, /health)
application — Use-Cases: AnswerQuestion (Grounding + Abstention) · IngestCorpus
domain — Entitäten (Document/Chunk/Citation/Answer) + Ports (EmbedderPort/VectorRepoPort/LLMPort)
infrastructure — Adapter: PgVectorRepo · E5Embedder · MistralLLM/OllamaLLM · Chunker/Parser

RAG-Flow (Anfrage)

Frage + Verlauf Query-Rewriting Embed (Mistral/E5) pgvector Top-k (Cosine) Grounding-Prompt LLM (Mistral/Ollama) §-Citations (gestreamt)

Verzweigung: Score < 0.78 oder LLM ohne Beleg → „Keine Quelle gefunden — keine Antwort" (Abstention statt Halluzination). Konversationell: der Verlauf wird stateless mitgeschickt (kein Cookie); ein Follow-up wird per Query-Rewriting zu einer eigenständigen Suchanfrage aufgelöst. Der Abstention-Gate sitzt vor dem LLM und bleibt damit prompt-unabhängig.

Datenmodell

EntitätFelder (Auszug)
documentsid, source_url, gesetz, ingested_at
chunksid, document_id, paragraph („§ 36"), titel, text, source_url, token_count, embedding vector(1024) (hnsw, cosine)

Technologieentscheidungen (ADR-Auszug)

ThemaEntscheidungBegründung
Vector-StorePostgreSQL + pgvectorEin Motor (relational + vektoriell), einfacher Betrieb
EmbeddingsMistral-API (Deploy) · E5 lokal (Option)beide 1024-dim; mistral-embed = leicht (kein torch, kleiner VPS); E5 = 100% lokal (kein Datenabfluss). ADR-002.
LLMMistral (EU) · Ollama (lokal)DSGVO-Story; Provider hinter Port austauschbar
Chunkingnach §/Titelpräzise, verlinkbare Zitate statt blinder Token-Fenster
FrontendJinja2 + HTMXserver-rendered, ein Deploy, kein JS-Framework

5Implementierung

Ingest (offline, idempotent)

Die amtliche SGB-XI-XML wird je <norm> nach § zerlegt (Enbez/Titel/Text), pro § ein Chunk gebildet, mit E5 eingebettet und in pgvector upgesertet. Schlüsselentscheidung: ins Embedding fließt §-Nummer + Titel + Text — so findet die Query „Verhinderungspflege" den § 39 (dessen Titel „Verhinderung der Pflegeperson" den Begriff trägt).

Embeddings — zwei austauschbare Provider

Über EMBED_PROVIDER wählbar: Mistral-API (mistral-embed, Deploy-Default — leicht, kein torch, kleiner VPS) oder E5 lokal (für den 100%-lokalen Modus, kein Datenabfluss). Beide 1024-dim → dasselbe pgvector-Schema; Wechsel = Re-Ingest. Entscheidung & Begründung in docs/adr/ADR-002.

Grounding & Anti-Halluzination

Der System-Prompt erzwingt: „antworte ausschließlich aus dem Kontext, zitiere §, sonst abstiniere". Zusätzlich kappt eine Retrieval-Schwelle (Cosine < 0.78) zu schwache Treffer. Das Citation-Parsing belegt nur §§, die im Antworttext UND im Kontext vorkommen.

Frontend (server-rendered + Streaming)

Chat-Shell mit HTMX: POST /ask liefert ein HTML-Fragment (Antwort + Beleg-Chips) und aktualisiert per Out-of-Band-Swap das Quellen-Panel — ohne Full-Reload, ohne JS-Framework. Darüber liegt ein konversationeller Streaming-Pfad: POST /chat sendet die Antwort als Server-Sent-Events; chat.js (~150 Zeilen Vanilla-JS) hängt die Tokens live an und hält den Gesprächs-Verlauf (stateless). Ist JS deaktiviert, bleibt der HTMX-Fallback aktiv — Progressive Enhancement.

6Qualitätssicherung

Statische Analyse (ruff, mypy --strict), Unit-Tests (pytest) und CI (GitHub Actions) bei jedem Push. Kern ist die Evaluations-Pipeline über ein Golden-Set (26 Fälle: 20 echt + 6 Trap).

85 %Recall@5 (17/20)
100 %sichere Abstention auf Traps (0 Halluzinationen)
~1,8 sLatenz p50
8/8Tests · ruff + mypy clean

Ehrliche Analyse: Die Abstention-Fehler sind durchweg konservative False-Abstentions (System sagt „weiß nicht", obwohl der § gefunden wurde) — nie Halluzinationen. Ein stärkeres LLM bzw. ein weicherer Grounding-Prompt würde die Hilfsbereitschaft erhöhen (Helpfulness ↔ Safety-Trade-off). Iteration: Recall@5 stieg messbar durch das §+Titel-Embedding (s. o.) — „messen, Ursache finden, gezielt fixen, neu messen".

7Datenschutz & Compliance

8Betrieb & Deployment

Docker-Compose-Stack: Caddy (Auto-HTTPS) → FastAPI (uvicorn) → Postgres/pgvector. Zielumgebung: Linux-VPS unter pflegelotse.limbermartinez.com. CI/CD über GitHub Actions. Secrets (MISTRAL_API_KEY) nur als Umgebungsvariable, nie im Repo.

Reproduzierbar: docker compose up startet die App; docker compose run --rm ingest lädt SGB XI; … python eval/run_eval.py erzeugt den Eval-Report.

9Anwenderdokumentation (Kundendokumentation)

Zielgruppe: Pflegekräfte, Pflegeberatung und Angehörige. Die Bedienung ist bewusst einfach (ein Eingabefeld, sofort belegte Antworten).

Erste Schritte

  1. Seite öffnen — der Startbildschirm zeigt Beispielfragen.
  2. Frage eintippen oder eine Beispielfrage anklicken.
  3. Antwort lesen — jede Aussage trägt einen §-Beleg; rechts erscheinen die Quellen mit Originaltext und Link.
  4. Bei „Keine Quelle gefunden" die Frage konkreter stellen (z. B. mit Pflegegrad/Leistungsart).
  5. Über EU-Cloud / Lokal den Datenschutz-Modus wählen.
Startbildschirm mit Beispielfragen
Startbildschirm — Beispielfragen & „informativ, keine Rechtsberatung"
Antwort mit §-Belegen und Quellen-Panel
Antwort mit §-Zitaten, Beleg-Chips und Quellen-Panel (Originaltext + Link)
Mobile Ansicht
Mobil — einspaltig, kompakter Header
Cookie-Banner
Einwilligung (TDDDG-konform, gleichwertige Buttons)
Wichtiger Hinweis für Anwender: PflegeLotse liefert informative Auskünfte auf Basis des Gesetzestextes — keine Rechtsberatung. Maßgeblich ist der amtliche Gesetzestext; im Zweifel wenden Sie sich an Ihre Pflegekasse.

10Fazit & Ausblick

Soll-Ist: Alle Kernziele erreicht — quellenbelegte, halluzinationssichere Antworten, messbare Qualität, DSGVO-konformer, getesteter und reproduzierbarer Aufbau.

Ausblick: Golden-Set erweitern (stabilere Zahlen), Absatz-genaues Chunking und hybride Suche (pgvector + Volltext) für höhere Recall, stärkeres LLM gegen False-Abstentions, Konversations-Verlauf, Eval-Dashboard.

Anhang

Glossar

BegriffBedeutung
RAGRetrieval-Augmented Generation — Antworten aus abgerufenen Quellen statt aus dem Modellgedächtnis
EmbeddingVektor-Darstellung von Text für semantische Ähnlichkeit
GroundingBindung der Antwort an den bereitgestellten Kontext
Abstentionbewusstes „weiß nicht", wenn keine Quelle trägt
Recall@kAnteil der Fragen, bei denen der richtige § in den Top-k liegt

Quellen & Repository