RAG-Architekturen für deutsche Rechtsprechung & lokale Mandatsdaten-Anonymisierung (§ 203 StGB)
RAG-Architekturen für deutsche Rechtsprechung & lokale Mandatsdaten-Anonymisierung: Schutz vor KI-Halluzinationen und Berufsrechtsverstößen (§ 203 StGB, § 43e BRAO) Der Einsatz großer Sprachmodelle (Large Language Mode
RAG-Architekturen für deutsche Rechtsprechung & lokale Mandatsdaten-Anonymisierung: Schutz vor KI-Halluzinationen und Berufsrechtsverstößen (§ 203 StGB, § 43e BRAO)
Der Einsatz großer Sprachmodelle (Large Language Models, LLMs) in Anwaltskanzleien und Rechtsabteilungen scheitert in der Praxis meist an zwei strukturellen Hürden:
- KI-Halluzinationen und erfundene Rechtsprechungsfundstellen: Sprachmodelle generieren plausibel klingende, aber frei erfundene Aktenzeichen des Bundesgerichtshofs (BGH) oder Oberlandesgerichts (OLG). Wie die aktuelle Rechtsprechungsübersicht zu KI-Halluzinationen und erfundenen Fundstellen vor Gericht auf LegalTech.top dokumentiert – etwa in den Verfahren vor dem BayVerfGH (Vf. 9-VI-25) und dem Bundesarbeitsgericht oder dem OLG München (7 U 1044/26) –, drohen bei ungeprüfter Übernahme nicht nur Prozessverlust und Haftungsfälle, sondern auch empfindliche berufsrechtliche Konsequenzen.
- Anwaltliche Verschwiegenheitspflicht (§ 203 StGB, § 43a Abs. 2, § 43e BRAO): Mandatsbezogene Sachverhalte dürfen niemals ungeschützt an externe US-Cloud-APIs übertragen werden, bei denen ein menschliches Abuse Monitoring oder Modelltraining stattfindet (vgl. die Analyse zu Abuse Monitoring bei KI-Anbietern und dem Anwaltsgeheimnis sowie zu Verschwiegenheit und KI unter der KI-Verordnung).
Dieser Beitrag zeigt, wie Legal-Tech-Entwickler und Kanzlei-Ingenieure beide Probleme architektonisch lösen: durch eine lokale, deterministische Pseudonymisierungs-Pipeline vor jedem API-Call und eine strikte Retrieval-Augmented-Generation-Architektur (RAG) mit nachgeschaltetem Aktenzeichen-Verifier.
1. Lokale Anonymisierung & reversible Pseudonymisierung in Python
Bevor ein Schriftsatzentwurf oder ein Vernehmungsprotokoll an ein LLM übergeben wird, müssen personenbezogene Daten (Mandantennamen, Zeugen, Anschriften, IBANs, Telefonnummern und behördliche Aktenzeichen) lokal erkannt und durch konsistente Platzhalter ([MANDANT_1], [ZEUGE_2], [IBAN_1]) ersetzt werden.
Entscheidend für die juristische Subsumtion ist die referenzielle Konsistenz: Wenn „Max Mustermann“ auf Seite 3 als Geschäftsführer und auf Seite 18 als Kontoinhaber auftaucht, muss er an beiden Stellen auf denselben Token [PERSON_1] abgebildet werden, damit das Sprachmodell Kausalzusammenhänge weiterhin versteht. Weiterführende Grundlagen zur Anonymisierung und Pseudonymisierung in der Aktenbewältigung sowie zum KI-Datenschutz in der Kanzlei finden sich im Praxisbereich von LegalTech.top.
import re
from dataclasses import dataclass, field
from typing import Dict, Tuple
@dataclass
class ReversibleVaultPseudonymizer:
"""
Deterministische, lokal ausgeführte Pseudonymisierung für juristische
Dokumente mit reversibler In-Memory-Mapping-Tabelle (Vault).
"""
entity_To_token: Dict[str, str] = field(default_factory=dict)
token_to_entity: Dict[str, str] = field(default_factory=dict)
counters: Dict[str, int] = field(default_factory=lambda: {
"IBAN": 0, "EMAIL": 0, "TEL": 0, "AZ": 0, "PERSON": 0
})
def _register(self, raw_value: str, category: str) -> str:
norm = raw_value.strip()
if norm in self.entity_To_token:
return self.entity_To_token[norm]
self.counters[category] += 1
token = f"[{category}_{self.counters[category]}]"
self.entity_To_token[norm] = token
self.token_to_entity[token] = norm
return token
def pseudonymize(self, text: str, known_names: list[str]) -> str:
# 1. Bekannte Namen (sortiert nach Länge absteigend)
for name in sorted(known_names, key=len, reverse=True):
if name in text:
token = self._register(name, "PERSON")
text = text.replace(name, token)
# 2. Deutsche IBANs
text = re.sub(
r'\bDE\d{2}\s?(?:\d{4}\s?){4}\d{2}\b',
lambda m: self._register(m.group(0), "IBAN"),
text
)
# 3. E-Mail-Adressen
text = re.sub(
r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b',
lambda m: self._register(m.group(0), "EMAIL"),
text
)
# 4. Staatsanwaltschaftliche Js-Aktenzeichen (z. B. 123 Js 456/26)
text = re.sub(
r'\b\d{1,4}\s+Js\s+\d{1,6}/\d{2,4}\b',
lambda m: self._register(m.group(0), "AZ"),
text
)
return text
def depseudonymize(self, llm_output: str) -> str:
result = llm_output
for token, original in self.token_to_entity.items():
result = result.replace(token, original)
return result
Die Zuordnungstabelle (token_to_entity) verbleibt ausschließlich im lokalen Arbeitsspeicher des Kanzleirechners oder einer lokalen KI-Infrastruktur in der Kanzlei.
2. Juristisches Chunking & Retrieval-Augmented Generation (RAG)
Standard-Textsplitter aus allgemeinen Frameworks schneiden nach festen Token-Längen (z. B. alle 500 Tokens). Bei deutschen Gesetzen und Gerichtsurteilen reißt dieses Vorgehen Tatbestandsvoraussetzungen, Ausnahmetatbestände („Dies gilt nicht, wenn…“) und Randnummern auseinander.
Für eine verlässliche RAG-KI in der Rechtspraxis müssen Texte struktur- und normsensitiv entlang von Paragrafen, Absätzen und Urteils-Randnummern (Rn.) segmentiert werden:
import re
from typing import List, Dict
def split_german_judgment_by_randnummer(
full_text: str,
court: str,
file_number: str,
decision_date: str
) -> List[Dict[str, str]]:
"""
Zerlegt ein deutsches Gerichtsurteil exakt entlang der Randnummern (Rn.)
und reichert jeden Chunk mit unveränderlichen Zitations-Metadaten an.
"""
pattern = re.compile(r'(?m)^(?:Rn\.?\s*|\[)(\d+)(?:\]|\s+)')
matches = list(pattern.finditer(full_text))
chunks = []
for idx, match in enumerate(matches):
rn = match.group(1)
start = match.start()
end = matches[idx + 1].start() if idx + 1 < len(matches) else len(full_text)
paragraph_text = full_text[start:end].strip()
chunks.append({
"chunk_id": f"{court}_{file_number}_Rn_{rn}",
"citation": f"{court}, Beschl. v. {decision_date} – {file_number}, Rn. {rn}",
"court": court,
"file_number": file_number,
"randnummer": rn,
"content": paragraph_text
})
return chunks
3. Deterministischer Zitations-Gatekeeper gegen Halluzinationen
Um auszuschließen, dass das Modell trotz RAG-Kontext externe Fundstellen aus seinen Trainingsgewichten hinzuerfindet (vgl. auch die Diskussion zu Prüfpflichten und Verschwiegenheit beim KI-Einsatz in der Strafverteidigung), wird jeder generierte Absatz vor der Ausgabe durch einen deterministischen Citation Gatekeeper geprüft:
import re
from typing import Set, List
BGH_CITATION_REGEX = re.compile(
r'\b(?:\d+\s+StR\s+\d+/\d{2,4}|[I|V|X]+\s+ZR\s+\d+/\d{2,4}|\d+\s+BvR\s+\d+/\d{2,4}|BGHSt\s+\d+,\s*\d+)\b'
)
def verify_citations_against_context(
generated_text: str,
allowed_context_citations: Set[str]
) -> Tuple[bool, List[str]]:
"""
Prüft jedes im generierten Schriftsatz genannte Aktenzeichen gegen die
tatsächlich im RAG-Retrieval abgerufenen Primärquellen.
"""
found_citations = {m.group(0).strip() for m in BGH_CITATION_REGEX.finditer(generated_text)}
unverified = [c for c in found_citations if c not in allowed_context_citations]
return (len(unverified) == 0, unverified)
Wird ein Aktenzeichen entdeckt, das nicht in allowed_context_citations (dem abgerufenen Quellkorpus der aktuellen Sitzung) enthalten ist, blockiert die Pipeline die Ausgabe automatisch und markiert die Stelle zur anwaltlichen Nachprüfung.
4. Fazit für Legal Engineers
Eine produktionsreife Kanzlei-KI verlässt sich niemals auf bloßes Prompting (Prompting für Juristen), sondern kombiniert drei technische Schutzschichten:
- Lokales Pre-Processing: Reversible Pseudonymisierung sensibler Mandantendaten vor jedem externen API-Aufruf.
- Norm- und Randnummern-basiertes Hybrid-RAG: Kombination aus exakt gewichteter BM25-Suche (für Paragrafenketten und Aktenzeichen) und dichter Vektorsuche.
- Deterministischer Post-Processing-Gatekeeper: Programmatische Verifikation jedes einzelnen Urteilszitats gegen die verifizierte Primärdatenbank.
Weiterführende Analysen zu KI-Verordnung & Kanzlei-Richtlinien, Elektronischem Rechtsverkehr & beA sowie aktuellen Entwicklungen rund um Legal Tech & Kanzleiautomatisierung erscheinen fortlaufend auf https://legaltech.top/.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.