Maria ist die Schicht zwischen SAJA und den großen Sprachmodellen, die im Hintergrund arbeiten. Sie sorgt dafür, dass keine echten Klientendaten an OpenAI oder Azure gehen, sondern nur Platzhalter. Das klingt einfach. In der Praxis war es ein Weg über zwei verworfene Verfahren, drei größere Architekturentscheidungen und eine Reihe von Bugs, an denen ich gelernt habe, was Pseudonymisierung in einem produktiven KI-Workflow wirklich heißt.
Das hier ist die ehrliche Version dieser Geschichte.
Shield v0.3: Listenabgleich als erste Linie
Die erste Version von Shield war eine Pseudonymisierungs-Maske mit klarer Aufgabe. Wenn eine Fachkraft in SAJA tippt „Max hatte heute Probleme in der Schule", soll OpenAI nicht „Max" sehen, sondern einen Platzhalter wie „Kind-1". Beim Rückweg wird der Platzhalter wieder durch den echten Namen ersetzt. So weit, so klassisch.
Was gut funktionierte: Bekannte Klienten, Kontakte und Mitarbeiter aus der Datenbank wurden zuverlässig erkannt und durch stabile Pseudonyme ersetzt. „Kind-1", „Kontakt-2", „Mitarbeiter-3". Das System lernte still mit. Wenn eine Fachkraft einen neuen Arzt erwähnte, legte SAJA ihn im Hintergrund als Kontakt an und vergab ein neues Pseudonym. Stabilität über Sessions hinweg, im Datenbank-Feld festgeschrieben.
Das große Problem waren die unbekannten Personen. Dritte. Eine Fachkraft schreibt: „Max hat sich heute mit Tobias gestritten." Tobias ist nicht in der Datenbank. Tobias ist vielleicht ein anderes Kind aus einer Nachbargruppe. Vielleicht ein Klassenkamerad. Vielleicht ein Verwandter. Egal was, Tobias ist ein realer Name, der nicht an OpenAI gehen sollte.
Meine Antwort darauf war eine Liste. Genauer: 10.160 deutsche Vornamen aus dem Standesamt Köln. Wenn ein Wort in der Liste vorkam und kapitalisiert war, wurde es maskiert. Das funktionierte für offensichtliche Fälle. Es war weniger Intelligenz als Abgleich, und genau da fingen die Probleme an.
Drei Bugs, die mir Pseudonymisierung beigebracht haben
Während des Bauens fielen mir drei Bugs auf, die jeden für sich harmlos klingen, aber zusammen ein größeres Bild zeichnen.
Der erste: Das Wort „Nur" steht in der Liste. Es ist als nordischer Vorname registriert. Eine Fachkraft schreibt „Nichts besonderes. Nur U4. Routine." Shield erkennt „Nur" als Vorname und maskiert es. Schlimmer noch, es vertreibt damit eine andere Maskierung aus dem vorherigen Turn, weil intern die Person-Counter durcheinandergeraten. Aus „Person-1 ist Dr. Neu" wird plötzlich „Person-1 ist nichts besonderes". Das System ist konsistent in sich, aber sachlich falsch.
Der zweite: „UM" wurde als Vorname gedeutet. Wahrscheinlich weil die Liste irgendwo einen Eintrag hatte, der so kurz wirkte. Das Ergebnis war, dass medizinische Begriffe oder Abkürzungen plötzlich als Personen behandelt wurden, mit kaskadierenden Folgen für den Kontext, den das LLM bekam.
Der dritte und vielleicht lehrreichste: Eine Fachkraft erwähnt einen neuen Arzt, „Dr. Neu". Shield erkennt „Dr." als Titel-Trigger, maskiert „Dr. Neu" zu „Person-1". SAJA bekommt also „Person-1" und denkt, das sei eine bereits bekannte Person aus der Datenbank, weil das Format so aussieht. Sie legt keinen neuen Kontakt an. Der echte Arzt ist im System nie angekommen, obwohl die Fachkraft ihn explizit genannt hat.
Was diese Bugs gemeinsam haben: Sie sind keine Programmierfehler im klassischen Sinn. Sie sind Folgen davon, dass eine Liste keinen Kontext versteht. Die Liste sieht nur Wörter, sie sieht nicht, was zwischen ihnen steht. Pseudonymisierung über Listenabgleich ist eine erste Linie, aber sie reicht nicht für eine Fachsoftware, in der der Kontext sich über mehrere Nachrichten und mehrere Akten zieht.
Das größere Problem: Rekonstruktion durch Datenmenge
Auch wenn alle einzelnen Bugs gefixt waren, blieb eine strukturelle Schwäche. Pseudonymisierung durch Platzhalter wie „Kind-1" verbirgt den Namen, aber sie verbirgt nicht den Kontext. Wenn ein LLM über mehrere Nachrichten hinweg von Kind-1 liest, das in Hannover lebt, in der vierten Klasse ist, eine Schwester namens Kontakt-2 hat, und letzte Woche einen Vorfall hatte, dann hat das LLM ein sehr präzises Bild von Kind-1, auch ohne den Namen.
Das ist nicht falsch im juristischen Sinne, weil keine direkte Identifikation möglich ist. Aber es ist auch nicht unbedingt das, was eine Datenschutzgrundverordnung sich unter Pseudonymisierung vorstellt. Je größer die Datenmenge wird, die ein LLM kumulativ über einen pseudonymisierten Klienten lernt, desto mehr Quasi-Identifier entstehen. Familienkonstellation, Wohnort, Schule, Diagnosen, Verhaltensmuster. Das alles bleibt erhalten, weil es genau die Sachen sind, die in fachlicher Doku zwingend stehen müssen.
Ich habe das Problem damals nicht so klar formuliert wie jetzt. Aber ich hatte das Gefühl, dass etwas an der Architektur nicht reichte. Also habe ich nach einer schärferen Antwort gesucht.
Shield v2: Plausible Substitution
Die Idee von Shield v2 war ehrgeizig. Statt Platzhalter wie „Kind-1" zu verwenden, sollten echte personenbezogene Daten durch realistische, aber komplett fiktive Daten ersetzt werden. Ein Märchen.
Aus „Lisa wohnt mit ihrer Mutter Frau Mayer in Misburg. Sie hat ADHS und nimmt Ritalin" sollte „Moritz wohnt mit seiner Oma in Hamburg. Er hat eine Angststörung und nimmt Venlafaxin" werden. Der Payload, den OpenAI bekommt, beschreibt eine Person, die nicht existiert. Beim Rückweg wird die fiktive Person wieder durch die echten Daten ersetzt.
Theoretisch war das stark. Wenn an OpenAI nur Texte gehen, die nachweislich keine reale Person beschreiben, ist die juristische Argumentation eine andere. Erwägungsgrund 26 DSGVO und das EuGH-Urteil C-413/23 P legen nahe, dass synthetische Daten, die keine real existierende Person betreffen, möglicherweise gar nicht mehr personenbezogen sind. Das wäre der härtere Schutz gewesen.
In der Praxis ist die Idee an mehreren Stellen gleichzeitig auseinandergeflogen.
Das erste Problem war Konsistenz. SAJA arbeitet nicht in einer einzelnen Anfrage, sondern führt Gespräche über mehrere Nachrichten hinweg. Wenn ich in Nachricht 1 „Lisa" zu „Moritz" ersetze, muss ich in Nachricht 4 immer noch „Moritz" verwenden, sonst wird die Geschichte inkonsistent. Das hieß, ich brauchte eine Mapping-Tabelle, die über die ganze Session stabil bleibt. Das funktionierte technisch, aber es schuf ein neues Korrelationsrisiko: Eine Mapping-Tabelle, die über lange Zeiträume stabil ist, ist selbst ein hochsensitives Datum.
Das zweite Problem war Präzision. Eine plausible Substitution musste nicht nur konsistent sein, sondern auch sinnvoll. Wenn ich „ADHS" zu „Aufmerksamkeitsstörung" generalisiere, weil mein Substitutions-Code die exakte medizinische Bezeichnung nicht kannte, dann ging die Information verloren. Die Doku, die SAJA am Ende erzeugte, war ungenauer als die Eingabe der Fachkraft. Das ist in der Sozialen Arbeit nicht nur unschön, sondern fachlich problematisch. Eine Verlaufsdoku, die „Aufmerksamkeitsstörung" sagt, wo die Fachkraft „ADHS" gemeint hat, ist eine andere Doku.
Das dritte und entscheidende Problem war OpenAI selbst. SAJA nutzt OpenAI-Funktionen wie Tool-Use, um aktiv mit der Datenbank zu sprechen. SAJA fragt zum Beispiel: „Ist Tobias schon als Kontakt angelegt?" Das ist ein Tool-Call, der echte Datenbank-Operationen auslöst. Wenn ich zwischen SAJA und OpenAI eine zweite KI als Übersetzungs-Schicht setze, die den Text in Märchen verwandelt, dann muss diese KI nicht nur den Text umschreiben, sondern auch die Tool-Calls verstehen, weiterleiten und übersetzt zurückführen. Das hat funktioniert, bis ich Tool-Use eingeführt habe. Danach hat es nicht mehr funktioniert. Die Übersetzungs-KI sperrte den Tool-Use, weil sie ihn nicht durchreichen konnte. SAJA wurde stumm.
In dem Moment habe ich gemerkt: Plausible Substitution kann technisch sauber sein, aber sie kämpft gegen die Mechanik des Werkzeugs, das wir nutzen. OpenAI ist nicht eine Black Box, in die man Text reinwirft. OpenAI ist ein Werkzeug mit Tools, mit Funktionen, mit einer eigenen Architektur. Wer eine Schicht dazwischen baut, die alles übersetzt, blockiert die Mechanik.
Ich habe Shield v2 verworfen.
Maria: ehrlicher als ein Märchen
Maria ist die Konsequenz dieser Lernschritte. Sie sieht anders aus als beide Vorgänger.
Das Verfahren in Maria heißt D-POM. Datenflusskontrolle mit kontextlokalen Refs. Aus „Lisa wohnt in Hannover" wird nicht „Moritz wohnt in Hamburg", sondern „[KLIENT_A] wohnt in [WOHNORT_1]". Das LLM weiß durch das Format sofort, dass es einen Platzhalter sieht, keine reale Person. Es kann sich auf den Platzhalter beziehen, aber es kann nicht halluzinieren, dass „Moritz" ein Junge wäre, oder eine biografische Annahme treffen, die im weiteren Verlauf falsche Schlüsse produziert.
Die Refs sind kontextlokal. Sie gelten innerhalb einer Aufgabe, nicht über alle Sessions hinweg. „[KLIENT_A]" in der morgendlichen Verlaufsdoku ist nicht dieselbe Person wie „[KLIENT_A]" in der nachmittäglichen Hilfeplanung. Das verhindert, dass eine globale Mapping-Tabelle entsteht, die selbst zum Sicherheitsproblem wird. Was Maria stabil hält, ist die Konsistenz innerhalb einer Aufgabe, nicht darüber hinaus.
Maria ist auch keine Übersetzungs-KI mehr. Sie ist eine Trust Boundary in der EDN-Plattform, mit klar definierten Tool-Grenzen. Wenn SAJA mit OpenAI spricht und einen Tool-Call braucht, läuft der Tool-Call durch die EDN-Plattform, nicht durch eine zwischengeschaltete KI. Maria sorgt dafür, dass der Inhalt des Calls keine Klardaten enthält, aber sie versperrt den Call nicht. Das ist die strukturelle Lehre aus Shield v2.
Was Maria daraus macht, ist eine Architektur, die sich anders anfühlt. Kühler im LLM-Output, weil keine Geschichten mehr erzählt werden. Sauberer im Datenfluss, weil keine Mapping-Tabelle über die ganze Session stabil bleibt. Ehrlicher in der DSGVO-Argumentation, weil Maria nicht behauptet, das LLM sehe eine andere Person, sondern explizit sagt: Das LLM sieht keinen Personenbezug, sondern einen Platzhalter.
Maria läuft heute auf shield.edn-system.de in Produktion. 155 Tests sind grün. Vier API-Endpoints, mit klar dokumentierten Verträgen. Sie ist noch nicht juristisch validiert, das ist der nächste Schritt: ein Rechtsgutachten zur Frage, ob das Verfahren unter § 65 SGB VIII und § 203 StGB trägt, nicht nur unter DSGVO. Das ist Arbeit, die ansteht.
Was ich daraus mitnehme
Drei Sachen, die mir geblieben sind.
Erstens: Listenabgleich ist eine erste Linie, keine vollständige Antwort. Wer Pseudonymisierung über Listen baut, baut einen Filter mit blinden Flecken. Das war Shield v0.3, und es hat seinen Zweck erfüllt für eine erste Version. Aber es war nicht das Verfahren, mit dem ich vor einen DSB einer Diakonie treten würde.
Zweitens: Plausible Substitution klingt wie die ehrliche Antwort, ist aber in einem Tool-Use-Workflow nicht praktikabel. Märchen erzählen funktioniert für isolierte Texte. Es funktioniert nicht für Software, die mit ihrer Umgebung sprechen muss. Wer KI in eine Fachanwendung baut, muss die Mechanik der KI respektieren, nicht versuchen, sie zu kapseln.
Drittens, und das ist das wichtigste: Die ehrlichste Architektur ist die, die nichts behauptet, was sie nicht ist. Maria sagt nicht „das LLM sieht eine andere Person", sondern „das LLM sieht keine Person, sondern einen Platzhalter". Das ist sachlich präziser und juristisch sauberer. Die ehrliche Architektur ist auch die nüchternste, und das ist, denke ich, kein Zufall.
Maria ist genau wie SAJA ein Prototyp. Sie wird weiter entwickelt, getestet und stabilisiert.