u/North_Expert9120

▲ 5 r/recht

KI-gestützte juristische Prüfassistenz vom Bund entwickelt - SPARK Workflow mit meiner Meinung nach erheblichen Mängeln für die Anwendbarkeit

Ich habe mir den SPARK-Workflow des BMDS angeschaut. Bezahlt mit Steuergeldern, und nicht billig. Die Idee finde ich grundsätzlich sinnvoll: KI soll Planfeststellungsverfahren unterstützen durch eine KI Assistenz bei der Subsumtion, Dokumente dafür zu strukturieren und Fundstellen schneller nutzbar machen.

Mein Hauptproblem nach Blick in den Code ist aber nicht der KI-Einsatz an sich, sondern ein gefährliches Muster. Den ganzen Bericht findet ihr hier

https://www.reddit.com/r/KI\_de/comments/1ugd5sg/ich\_hab\_mir\_diese\_woche\_sparkworkflow\_vom\_bmds

aber hier noch mal zusammengefasst:

Das System kann Ergebnisse erzeugen, die vollständig wirken, obwohl im Hintergrund relevante Dokumente, Normen oder Argumente fehlen.

Normen (Gesetzesparagraphen) können fehlen
Das System prüft offenbar nur manuell konfigurierte Einstiegsnormen. Es gibt laut Post keine automatische Normidentifizierung aus den hochgeladenen Dokumenten. Kontextnormen werden zudem begrenzt nachgeladen. Dadurch kann eine relevante Spezialnorm fehlen, ohne dass der Nutzer eine klare Warnung bekommt.

Unwichtige Kontextnormen können einbezogen werden, während wichtige fehlen
Kritisch ist nicht nur „zu wenig Kontext“, sondern der falsche Kontext: Wenn Normen eher numerisch nachgeladen werden, können weniger relevante Vorschriften im Kontext landen, während die eigentlich einschlägige Spezialnorm außerhalb des Limits liegt. Das Ergebnis kann dann juristisch vollständig aussehen, ist es aber nicht.

Der Gesetzeskorpus selbst kann unvollständig sein
Wenn Parser Normen, Absätze oder fehlerhafte Einträge still überspringen, arbeitet die spätere KI-Bewertung möglicherweise auf einem lückenhaften Rechtstext. Besonders gefährlich wäre das, wenn das System nicht sichtbar markiert, welche Normteile beim Einlesen verloren gingen.

Bewertungen arbeiten teilweise auf gekürzten oder gesampelten Daten
Laut Post werden Fundstellen bei großen Mengen gesampelt, Chunk-Texte gekürzt und Fallback-Micros erzeugt, ohne dass das Ergebnis zwingend sichtbar als gesampelt, gekürzt oder fallback-basiert markiert wird. Relevante Sätze können dadurch fehlen, obwohl sie im Dokument standen.

Juristische Recherche wird offenbar nicht konsequent in die Bewertung gegeben
Besonders kritisch wirkt der Punkt research_report=None: Recherche zu Gerichtsentscheidungen/Gesetzesbegründungen kann vorhanden sein, fließt aber laut Post nicht in die eigentliche Bewertungslogik ein. Dann sieht die Bewertung juristisch fundiert aus, obwohl zentrale juristische Substanz nicht genutzt wurde.

Auditability reicht für produktive Rechtswirkung nicht aus
Positiv sind Quellenbelege und Datenbank-Versionierung. Aber problematisch ist laut Post: Modellversion, Workflow-Run, Reviewer-Issues, Applicability-Begründungen und Fehlerzustände sind nicht durchgehend sichtbar/persistiert. Genau das bräuchte man aber, wenn später gefragt wird: Warum wurde etwas geprüft, übersprungen oder falsch bewertet?

Mein Fazit:
SPARK-Workflow wirkt als PoC interessant. Aber für produktive Verfahren mit Rechtswirkung wäre der zentrale Risikopunkt: Scheinsicherheit durch unsichtbare Unvollständigkeit.
Nicht „die KI macht Fehler“ ist das Hauptproblem, sondern:
- Dokumente können fehlen
- Normen können fehlen
- Normtexte können unvollständig sein
- unwichtige Kontextnormen können wichtige verdrängen
- relevante Fundstellen können durch Sampling/Kürzung/Fallbacks rausfallen
- Fehlerzustände werden nicht hart genug sichtbar gemacht

Ein solches System müsste sehr deutlich anzeigen:
Diese Prüfung ist nicht vollständig. Diese Dokumente wurden nicht verarbeitet. Diese Normen wurden nicht geprüft. Diese Fundstellen wurden gesampelt/gekürzt. Diese Bewertung basiert auf Fallbacks.
Ohne solche Warnungen sieht das Ergebnis belastbarer aus, als es technisch ist.

Was haltet ihr von dem System als Experten?

reddit.com
u/North_Expert9120 — 9 days ago
▲ 12 r/de_IT

BMDS-SPARK: Das kritische Problem ist nicht „KI“, sondern unsichtbare Unvollständigkeit

Ich habe mir den SPARK-Workflow des BMDS angeschaut. Bezahlt mit Steuergeldern, und nicht billig. Die Idee finde ich grundsätzlich sinnvoll: KI soll Planfeststellungsverfahren unterstützen, Dokumente strukturieren und Fundstellen schneller nutzbar machen.

Mein Hauptproblem nach Blick in den Code ist aber nicht der KI-Einsatz an sich, sondern ein gefährliches Muster. Den ganzen Bericht findet ihr hier

https://www.reddit.com/r/KI_de/comments/1ugd5sg/ich_hab_mir_diese_woche_sparkworkflow_vom_bmds

aber hier noch mal zusammengefasst:

Das System kann Ergebnisse erzeugen, die vollständig wirken, obwohl im Hintergrund relevante Dokumente, Normen oder Argumente fehlen.

Dokumente können wegfallen
Im Post werden Fälle beschrieben, in denen Dateien mit gleichem Namen als Duplikate verworfen werden oder Quelldokumente ohne passende _processed.json beim Ingest übersprungen werden. Wenn solche Fälle nicht sichtbar in UI/Ergebnis landen, kann eine Vollständigkeitsprüfung über einen unvollständigen Dokumentensatz laufen.

Normen (Gesetzesparagraphen) können fehlen
Das System prüft offenbar nur manuell konfigurierte Einstiegsnormen. Es gibt laut Post keine automatische Normidentifizierung aus den hochgeladenen Dokumenten. Kontextnormen werden zudem begrenzt nachgeladen. Dadurch kann eine relevante Spezialnorm fehlen, ohne dass der Nutzer eine klare Warnung bekommt.

Unwichtige Kontextnormen können einbezogen werden, während wichtige fehlen
Kritisch ist nicht nur „zu wenig Kontext“, sondern der falsche Kontext: Wenn Normen eher numerisch nachgeladen werden, können weniger relevante Vorschriften im Kontext landen, während die eigentlich einschlägige Spezialnorm außerhalb des Limits liegt. Das Ergebnis kann dann juristisch vollständig aussehen, ist es aber nicht.

Der Gesetzeskorpus selbst kann unvollständig sein
Wenn Parser Normen, Absätze oder fehlerhafte Einträge still überspringen, arbeitet die spätere KI-Bewertung möglicherweise auf einem lückenhaften Rechtstext. Besonders gefährlich wäre das, wenn das System nicht sichtbar markiert, welche Normteile beim Einlesen verloren gingen.

Bewertungen arbeiten teilweise auf gekürzten oder gesampelten Daten
Laut Post werden Fundstellen bei großen Mengen gesampelt, Chunk-Texte gekürzt und Fallback-Micros erzeugt, ohne dass das Ergebnis zwingend sichtbar als gesampelt, gekürzt oder fallback-basiert markiert wird. Relevante Sätze können dadurch fehlen, obwohl sie im Dokument standen.

Juristische Recherche wird offenbar nicht konsequent in die Bewertung gegeben
Besonders kritisch wirkt der Punkt research_report=None: Recherche zu Gerichtsentscheidungen/Gesetzesbegründungen kann vorhanden sein, fließt aber laut Post nicht in die eigentliche Bewertungslogik ein. Dann sieht die Bewertung juristisch fundiert aus, obwohl zentrale juristische Substanz nicht genutzt wurde.

Auditability reicht für produktive Rechtswirkung nicht aus
Positiv sind Quellenbelege und Datenbank-Versionierung. Aber problematisch ist laut Post: Modellversion, Workflow-Run, Reviewer-Issues, Applicability-Begründungen und Fehlerzustände sind nicht durchgehend sichtbar/persistiert. Genau das bräuchte man aber, wenn später gefragt wird: Warum wurde etwas geprüft, übersprungen oder falsch bewertet?

Mein Fazit:
SPARK-Workflow wirkt als PoC interessant. Aber für produktive Verfahren mit Rechtswirkung wäre der zentrale Risikopunkt: Scheinsicherheit durch unsichtbare Unvollständigkeit.
Nicht „die KI macht Fehler“ ist das Hauptproblem, sondern:
- Dokumente können fehlen
- Normen können fehlen
- Normtexte können unvollständig sein
- unwichtige Kontextnormen können wichtige verdrängen
- relevante Fundstellen können durch Sampling/Kürzung/Fallbacks rausfallen
- Fehlerzustände werden nicht hart genug sichtbar gemacht

Ein solches System müsste sehr deutlich anzeigen:
Diese Prüfung ist nicht vollständig. Diese Dokumente wurden nicht verarbeitet. Diese Normen wurden nicht geprüft. Diese Fundstellen wurden gesampelt/gekürzt. Diese Bewertung basiert auf Fallbacks.
Ohne solche Warnungen sieht das Ergebnis belastbarer aus, als es technisch ist.

reddit.com
u/North_Expert9120 — 10 days ago
▲ 22 r/SoftwareDACH+1 crossposts

Ich hab mir diese Woche SPARK-Workflow vom BMDS "KI-Agenten für Rechtsprüfung" angeschaut. War ehrlich gesagt nicht das, was ich erwartet hatte.

TL;DR: Ich habe mir SPARK Workflow, beauftragt vom "Deutschen Ministerum für Digitales und Staatsmodernisierung" (BMDS) technisch angeschaut. Mein Eindruck: Spannendes und vermutlich teures Open-Source-Projekt, zugeschnitten auf einen Anwendungsfall, maximal im PoC Status, aber eher eine strukturierte RAG-/Workflow-Pipeline als ein echtes KI-Agentensystem für Rechtsprüfung das wichtige Informationen "verliert" und damit definitiv noch nicht bereit ist für einen Einsatz. Besonders kritisch finde ich Lücken und Fehler bei Vollständigkeit, Fehlertransparenz, Nachvollziehbarkeit und Auditability.

Einleitung

Also ich muss vorausschicken: ich bin normalerweise nicht der Typ der sich über Produktnamen und große politische Ankündigungen aufregt. Namen sind Marketing, Politik und Versprechen ist, nunja, Politik und Versprechen... Technik ist Technik, und alles lebt irgendwie selten im selben Raum. Aber diese Woche, 35 Grad, draußen ist nichts, schlafen kann man sowieso nicht, hab ich die heißen Nächte damit verbracht, mir das groß angekündigte Open-Source-System für deutsche Planfeststellungsverfahren genauer anzuschauen (SPARK-workflow). Legal tech, KI-gestützte Normenprüfung, das ganze Programm. Irgendwie dachte ich mir, wenn ich schon nicht schlafen kann, kann ich wenigstens was sinnvolles tun. Und irgendwann saß ich da um 3 Uhr morgens und dachte: okay, ich muss das aufschreiben. Ich bin kein Jurist, ich mag zwar Suits und bin begeisterter Hobbyarbeitsrechtler, aber ich kenne meine Schranken, mein Wissen ist beschränkt, vor allem was Verwaltungsrecht betrifft. Aber, ein bisschen habe ich mich eingelesen weil es relevant ist um das System verstehen zu können. Denn immerhin sollen da ja einmal echte Verwaltungsverfahren drauf laufen. Und nicht nur kleine, sondern die ganz großen relevanten. Menschen verlassen sich darauf. Wir Bürger sind davon vermutlich alle früher oder später (un)mittelbar davon betroffen.

Und bei dem was ich jetzt hier mit meinem Laienwissen gefunden habe, fand ich doch die Lücke zwischen dem was kommuniziert wird und dem was technisch da ist, groß genug, sodass ich sie für relevant halte. Also lasst uns drüber sprechen. Für alle die was ich hier schreibe gerne einmal überprüfen möchten, hier der Link zum Repo.

Erst mal: Was ist das System überhaupt?

Die Grundidee ist gut. Planfeststellungsverfahren in Deutschland sind enorm dokumentenintensiv - Hunderte von Seiten Antragsdokumente, dutzende relevante Rechtsnormen, und am Ende muss eine Behörde einen Beschluss schreiben. Das kann auch mal Monate bis Jahre dauern und verzögert einfach unseren Wirtschaftsstandort Deutschland durch seine Asterix & Oberix mäßige Passierschein A38 Logik. Hier die Rettung, das SPARK-workflow System. Das System nimmt die Dokumente, nimmt die relevanten Normen, und fragt per LLM für jeden einzelnen Normsatz: ist das hier erfüllt, nicht erfüllt, oder nicht beurteilbar? Der Sachbearbeiter bekommt pro Satz eine strukturierte Analyse mit Quellenangaben.

Das ist sinnvoll. Das nimmt echte Arbeit ab. Soweit, so gut.

Aber lasst uns einmal die Details anschauen, denn da wird es doch etwas gruselig.

"Agenten" - schauen wir mal rein

Es gibt einen Service namens agent_orchestration_service. Klingt nach dem zentralen Gehirn. Ich schau mir die API-Routes an:

# agent_orchestration_service/src/api/routes/workflows_api.py
@router.post("/bewertung")
async def start_bewertung(request: BewertungsRequest):
    handle = await start_workflow(
        client, BewertungsWorkflow.run, input_data, workflow_id
    )
    return WorkflowResponse(parent_job_id=handle.id)

Hubz? Das ist ein HTTP-Gateway, keine wie auch immer geartete agentische Orchestrierung? Er nimmt einen Request, startet einen Temporal-Workflow, gibt die ID zurück. Keine Entscheidungslogik. Kein Routing zwischen verschiedenen Strategien. Kein Planning. Ich scroll durch alle Endpoints: start_bewertung, start_batch_mvp, start_risikohinweise, überall dasselbe Muster. Anfrage rein, Workflow starten, ID raus.

Und die "Agenten" selbst? Ich nehme den LegalDefinitionenExtrahiererAgent als Beispiel, der Name klingt ja nach einem eigenständigen Akteur:

# modul-rechtsmethodik/src/workflows/legal_definitionen/erkennung/lde.py
@workflow.defn
class LegalDefinitionenExtrahiererAgent:
    @workflow.run
    async def run(self, input: LDEInput) -> LDEOutput:
        result = await workflow.execute_activity(
            llm_invoke,
            LLMInvokeInput(prompt=build_prompt(input)),
            ...
        )
        return parse_output(result)

Ein Temporal-Workflow. Ein LLM-Aufruf. Kein Tool-Use, keine Werkzeugauswahl, keine Iteration, keine Reaktion auf unerwartete Ergebnisse. Wenn der LLM-Aufruf zurückkommt, ist der "Agent" fertig. Das ist eine Funktion mit einem API-Call. In modernen Frameworks würde man das eine "chain" mit LLM-Call nennen, keinen Agenten.

Was das System tatsächlich ist: eine durchaus durchdachte, deterministisch strukturierte Pipeline mit LLM-Schritten an fixen Stellen, orchestriert über Temporal. Das ist ehrenwert, aber kein Multi-Agenten-System.

Warum der Unterschied relevant ist:

Ein echter KI-Agent würde auf unerwartete Situationen reagieren - wenn ein Normsatz auf eine Verwaltungsvorschrift verweist die er nicht kennt, würde er das signalisieren oder nachrecherchieren. Wenn ein Dokument unvollständig ist, würde er das erkennen und seine Strategie anpassen. Wenn sich zwei Normen widersprechen, würde er das als Problem eskalieren.

Diese Pipeline tut das nicht. Sie läuft durch, egal was kommt. Wenn Eingaben fehlen, fehlen sie still. Wenn Normen nicht konfiguriert sind, werden sie nicht geprüft, ohne Hinweis. Für einen Juristen oder Sachbearbeiter der glaubt, ein autonomes System würde aktiv auf Vollständigkeit achten und Lücken melden, ist das ein gefährliches Missverständnis. Das System hilft bei dem was konfiguriert ist. Was nicht konfiguriert ist, existiert für das System nicht.

Die "Rechts-Graphdatenbank"

Ich such nach einer Datenbankverbindung und finde hier etwas mit dem Namen "Graph". Mein Interesse ist geweckt. Unser Gesetz ist ja durchaus ein wildes Netz an Verknüpfungen und Verweisen von einer Norm auf eine andere, mit Definitionen an allen möglichen Stellen, teilweise auch nicht in einer Norm selbst, sondern über Urteile. Völlig logisch das auch als Graphen zu modellieren, lasst uns also da mal reinschauen. pls_topic_graph.py - klingt vielversprechend. TopicGraphScope, fetch_topic_trees, graph_nodes. Ich such nach einem Graph-DB-Driver, nach Neo4j, nach einer Cypher-Query, nach irgendetwas das nach Graphtraversierung aussieht.

Was ich finde ist die NodeModelBase aus der shared library node-crud:

# node-crud/src/node_crud/base.py
class NodeModelBase(Base):
    id: Mapped[str] = mapped_column(String, primary_key=True)
    frontend_parent_ids: Mapped[list[str]] = mapped_column(ARRAY(String))
    project_version: Mapped[int] = mapped_column(Integer)

PostgreSQL. Eltern-Kind-Beziehungen als ARRAY(String) von UUIDs. Die Traversierung sieht dann so aus:

# agent_orchestration_service/src/workflows/pls_topic_graph.py
async def fetch_topic_trees(project_id, ...):
    all_nodes = await list_nodes(project_id)           # alle Nodes laden
    node_map = {n["id"]: n for n in all_nodes}         # in Dict packen
    for node in all_nodes:                              # Python-Loop
        for parent_id in node["frontend_parent_ids"]:  # Eltern iterieren
            ...

Das ist eine relationale Datenbank mit einer Adjazenzliste und clientseitiger Traversierung in Python (und kleiner Spoiler, das wird später auch noch weggeworfen). Funktioniert für flache Strukturen, aber Graph-Queries, Pfadsuche, Beziehungslogik zwischen Normen, das gibt es hier nicht. Sprich der eigentlich Grund weshalb man eine Graphenstruktur überhaupt wählt.

Die einzige echte Graphdatenbank im gesamten Stack ist SpiceDB, läuft als Docker-Container, Google-Zanzibar-Derivat, robustes System. Wird ausschließlich für Zugriffsberechtigungen genutzt. Für fachliche Normbeziehungen: kein Graph.

Warum das ein Problem ist, ein konkretes Beispiel:

Rechtsnormen sind keine isolierten Sätze. Sie verweisen aufeinander, bedingen einander, bauen aufeinander auf. Nehmen wir § 44 Abs. 1 BNatSchG, das ist der artenschutzrechtliche Kerntatbestand: Tötungsverbot, Störungsverbot, Zerstörungsverbot für geschützte Tierarten. Dieser Paragraph kann im Planfeststellungsverfahren nicht sinnvoll bewertet werden ohne § 15 BNatSchG (Eingriffsregelung, wurde überhaupt ein Eingriff festgestellt?), ohne § 45 Abs. 7 BNatSchG (Ausnahmetatbestand, greift hier eine Ausnahme?), und ohne die einschlägige AVV Artenschutz.

In einem echten Graphen würde man diese Abhängigkeiten abbilden: Knoten für jede Norm, Kanten für Verweise, Konditionalkanten für "wenn § X erfüllt dann prüfe zwingend § Y". Das System könnte dann sagen: du hast § 44 konfiguriert, aber § 45 fehlt, das ist eine notwendige Folgenorm, willst du sie hinzufügen?

Stattdessen: wenn § 45 nicht manuell in der TopicNorm-Tabelle steht, wird er nicht geprüft. Das System prüft § 44, kommt zum Ergebnis "möglicherweise Verstoß gegen Tötungsverbot", und schweigt dann darüber ob eine Ausnahme nach § 45 Abs. 7 in Betracht käme. Das ist kein Randproblem, der Ausnahmetatbestand ist in vielen Planfeststellungsverfahren der entscheidende Prüfpunkt. Er fällt durchs Raster wenn er nicht manuell konfiguriert wurde. Und das System sagt nicht, dass er fehlt.

Wie das System an seine Informationen kommt, und wo es still aufgibt

Weil mir persönlich die Idee fehlte, wie man unser Recht ohne eine Graphdatenbank sinnvoll nutzen könnte in Kombination mit KI, stieg der Spannungsbogen bei mir enorm. Ich dachte, es ist an der Zeit etwas zu lernen, wie es schneller, eleganter oder eben auch anders geht. Also gehen wir hier etwas tiefer.

Die Pipeline im Überblick

Für jeden einzelnen Normsatz läuft folgendes ab:

Schritt 1 : Retrieval: Vier parallele Suchstrategien über ein Qdrant-Vektorstore (1024-dimensionale Embeddings, Cosine-Similarity, Threshold 0.4): Direktsuche über TBM-Text (TBM=Tatbestandsmerkmal), über Prüffragen, über Satztext, und semantisch über Norm-Zusammenfassungen. Dazu parallel läuft TBMDBResearchWorkflow, der sucht in einer separaten Datenbank nach Gesetzesbegründungen (DKE), Gerichtsentscheidungen, und Rechtsbegriffen zum betreffenden Tatbestandsmerkmal.

Schritt 2 : PageIndex SVM: Ein zweistufiges Ranking-Verfahren. Erst werden Dokumentabschnitte per LLM auf Relevanz geprüft (Stage 1), dann werden innerhalb der relevanten Abschnitte einzelne Sätze selektiert (Stage 2). Das Ergebnis sind konkrete Originaltexte als Fundstellen.

Schritt 3 : MicroBuilder: Die gefundenen Fundstellen werden in Batches von 20 zu "Kernaussagen" komprimiert. Aus langen Originaltexten werden prägnante Extrakte.

Schritt 4 : Bewertung: MicroBuilder-Output → Applicability-Check (soll überhaupt bewertet werden?) → Planner (Kapitelstruktur) → Writer (pro Kapitel) → Ergebnis-Writer → Quality Reviewer.

Das klingt nach einer durchdachten Pipeline. Und dann kommt das:

# agent_orchestration_service/src/workflows/bewertung/input_builder.py:50
inputs.append(BewertungsWorkflowInput(
    satz_id=satz.id,
    satz_text=satz.text,
    tatbestandsmerkmale=tbms,
    fundstellen=fundstellen,
    research_report=None,  # <- BOING! Alles wegwerfen!
))

research_report=None. Der TBMDBResearchWorkflow läuft, erzeugt eine Synthese aus Gerichtsentscheidungen und Gesetzesbegründungen - und diese Synthese kommt nicht beim Bewertungs-LLM an. Das LLM sieht nur die komprimierten Fundstellen aus den Projektdokumenten und sein eigenes Trainingswissen.

Ich hab noch mal nachgeschaut ob ich das falsch lese. Nein, das geht so weiter!

# satz_orchestrator_workflow.py:169
workflow.execute_child_workflow(
    MatchSingleTBMWorkflow.run,
    MatchSingleTBMWorkflowInput(
        ...
        research_report=None,  # auch hier: nicht weitergegeben
    ),

Der research_report fließt zwar in den PageIndex SVM (für die Relevanz-Einschätzung welche Dokumentabschnitte wichtig sind), aber nicht in die eigentliche Bewertungslogik. Kein Fehler, kein Log, keine Warnung. Die Pipeline läuft durch.

Was das bedeutet, konkret:

Nehmen wir § 34 BNatSchG (FFH-Verträglichkeitsprüfung). Das BVerwG hat dazu in den letzten Jahren eine sehr ausdifferenzierte Rechtsprechung entwickelt, z.B. BVerwG 9 A 7/21 zu den Anforderungen an Summationswirkungen, BVerwG 4 A 4/19 zu Kohärenzmaßnahmen. Diese Entscheidungen prägen, was eine FFH-Prüfung heute leisten muss. Sie stehen, nach allem was ich sehen kann, in der Rechtsdatenbank des Systems.

Das System holt sie raus. Es synthetisiert sie. Und dann gibt es sie dem LLM nicht, warum auch immer. Das LLM bewertet § 34 BNatSchG mit dem was es aus seinem Training kennt, und Trainingsdaten für spezialisierte Verwaltungsrechtsprechung sind dünn, haben ein Cutoff-Datum, und bilden die jüngste BVerwG-Linie möglicherweise gar nicht oder falsch ab.

Das Ergebnis: eine Bewertung die aussieht als wäre sie rechtlich fundiert, aber de facto auf dem zusammengesetzten Halbwissen des Basismodells basiert, während die echte juristische Substanz ungenutzt im Hintergrund liegt. Das ist kein technisches Versehen, das ist eine aktive Architekturentscheidung die jemand getroffen hat. Ich hoffe es gibt einen guten Grund den ich nicht sehe.

Normen die fehlen, ohne dass es auffällt

Aber, es wird noch lückenhafter. Denn nicht nur Urteile fehlen, sondern auch Normen. Denn, das System prüft nur was manuell konfiguriert wurde. Die TopicNorm-Tabelle enthält die Einstiegsnormen, ein Sachbearbeiter oder Projektmanager trägt ein: BNatSchG § 44, WHG § 8, und so weiter. Das ist der vollständige Ausgangspunkt. Es gibt keine automatische Normidentifizierung aus den hochgeladenen Dokumenten.

Für jede Einstiegsnorm werden dann Kontextnormen geladen:

# examination_service/src/services/sa.py
further_norms = await norm_client.fetch_norms(
    jurabk=entry_norm.jurabk,
    paragraph_nr=entry_norm.paragraph_nr,
)
further_norms = further_norms[:10]

Zehn Normen. Sortiert nach paragraph_nr aufsteigend in der Datenbank, also im Wesentlichen die zehn nächsten Paragraphen in numerischer Reihenfolge. Keine Relevanzbewertung, keine semantische Ähnlichkeit, kein Zusammenhang mit dem konkreten Antrag. Und warum nur 10? Wieso nicht 11 oder 9 oder die magische Zahl 42 mit dem Sinn die wirklich alles erklärt?

Warum das gefährlich ist, ein konkretes Beispiel:

Stellen wir uns vor, das Verfahren dreht sich um eine Fernstraße mit erheblichen Lärmauswirkungen. Die Einstiegsnorm ist § 5 Abs. 1 Nr. 1 BImSchG, der allgemeine Schutz vor schädlichen Umwelteinwirkungen. Das System lädt also § 5 und dann die nächsten 10 Paragraphen: § 6, § 7, § 8, § 9, § 10, § 11, § 12, § 13, § 14, § 15 BImSchG. Das sind Genehmigungsverfahrensvorschriften, größtenteils.

Was fehlt: § 41 BImSchG (Lärmschutz an Straßen und Schienenwegen), das ist die Kernnorm für aktiven Schallschutz bei Verkehrsinfrastruktur. § 42 BImSchG (Entschädigung bei Lärmschutz). § 43 BImSchG (Rechtsverordnung über Lärmschutz). § 48 BImSchG (die Ermächtigungsgrundlage für die TA Lärm). Diese Normen stehen bei BImSchG alle ab § 40 aufwärts, sie werden nie als Kontextnormen geladen, weil das System nach Paragraphennummer aufsteigend abbricht.

Konkret bedeutet das: die Bewertung von Lärmschutzanforderungen könnte vollständig auf § 5 BImSchG basieren, während § 41 BImSchG, der eigentlich einschlägige Spezialtatbestand, gar nicht im Bild ist. Der Beschluss sieht vollständig geprüft aus. Er ist es nicht.

Und das Schlimmste daran: es gibt keine Warnung. Kein "die folgenden potenziell relevanten Normen wurden aus Kapazitätsgründen nicht berücksichtigt". Das System schweigt, und das Ergebnis sieht genauso aus wie wenn alle Normen berücksichtigt worden wären.

Dazu gibt es den NormDeconstruction-Cache. Das System zerlegt Normparagraphen in atomare Tatbestandsmerkmale und cached das Ergebnis:

# examination_service/src/services/norm_processing.py
cached = await cache.get(jurabk=jurabk, paragraph=paragraph_nr)
if cached:
    return cached  # cache hit

Der Cache hat kein law_version-Feld. Kein Ablaufdatum. Kein Content-Hash der Gesetzesversion, obwohl die Gesetze-Normen-DB selbst einen content_hash für Änderungserkennung hat. Wenn das BNatSchG nach einer Novellierung in der Datenbank aktualisiert wird, bleibt die alte Dekonstruktion im Cache erhalten bis jemand manuell löscht. Das System bemerkt die Inkonsistenz nicht.

Was das bedeutet: Angenommen, das BNatSchG wurde zuletzt 2022 substanziell geändert. Wenn die Normen-DB aktualisiert wurde, der Cache aber noch die alte Atomisierung enthält, bewertet das System Tatbestandsmerkmale die so im aktuellen Gesetz gar nicht mehr stehen, oder verfehlt neue die hinzugekommen sind. Niemand sieht das. Die Bewertung sieht aktuell aus. Sie basiert auf vergangenem Recht.

Was ein Sachbearbeiter sieht, und was nicht

Ich hab mir das Frontend und die Datenbankstruktur genauer angeschaut weil ich wissen wollte: wenn jemand diese Bewertungen nutzt, was kann er eigentlich nachvollziehen?

Was funktioniert gut

Der Quellenbeleg-Mechanismus ist tatsächlich ordentlich gemacht. Jede \[xxxx]-Inline-Referenz im Bewertungstext verweist auf eine BewertungQuelle-Zeile in der Datenbank:

# examination\_service/src/models/db/prufung\_models.py:788
class BewertungQuelle(Base):
    bewertung\_kapitel\_id: Mapped\[str]
    dokument\_id: Mapped\[str]
    cited\_svm\_id: Mapped\[str]       # welche Fundstelle
    chunk\_ids: Mapped\[list\[str]]    # welche Chunks
    page\_numbers: Mapped\[list\[int]] # welche Seiten

Man kann also für jede Quellenangabe im Text nachvollziehen: aus welchem Dokument, welche Seiten, welche Textabschnitte. Das ist echte Traceability auf Dokumentebene und ich will das ausdrücklich positiv hervorheben weil es Arbeit gemacht hat das so zu bauen.

Dazu gibt es VersionedMixin auf allen kritischen Tabellen, PostgreSQL Temporal Tables mit sys\_period TSTZRANGE. Vollständige Zeitreise: jede Datenbankzeile jedes Zustands ist rekonstruierbar. Und es gibt einen Protocol Service der alle Nutzeränderungen mit Before/After-Diffs loggt.

Das ist solide.

Was fehlt

Jetzt der andere Teil. Ich schau in die bewertung-Tabelle:

# examination\_service/src/models/db/prufung\_models.py:737
class Bewertung(VersionedMixin, Base):
    id: Mapped\[str]
    satz\_id: Mapped\[str]
    result: Mapped\[str]           # erfuellt | nicht\_erfuellt | nicht\_beurteilbar
    kurzform: Mapped\[str]
    norm: Mapped\[str]
    markdown\_text\_id: Mapped\[str]
    # kein llm\_model, kein llm\_version, kein workflow\_run\_id

Welches LLM-Modell hat diese Bewertung erzeugt? Nicht gespeichert. Welche Modellversion? Nicht gespeichert. Wenn in einem Jahr jemand fragt "mit welchem Modell wurde diese Bewertung aus 2025 erzeugt", gibt es keine Antwort.

Was das bedeutet: Stellt jemand den Beschluss vor Gericht in Frage und argumentiert, die KI-Analyse sei zum Zeitpunkt X mit einem Modell erstellt worden das bekannte Schwächen in Verwaltungsrechtsfragen hatte, die Behörde kann das nicht widerlegen. Sie kann nicht mal bestätigen welches Modell es war. Das ist für eine nachvollziehbare Verwaltungsentscheidung ein ernstes Problem, denn die Behörde hat eine Begründungspflicht. "Das KI-System hat das so bewertet" ist keine Begründung wenn man nicht sagen kann welches KI-System das war.

Dann die BewertungKapitel-Tabelle:

# examination\_service/src/models/db/prufung\_models.py:765
class BewertungKapitel(VersionedMixin, Base):
    id: Mapped\[str]
    bewertung\_id: Mapped\[str]
    titel: Mapped\[str]
    markdown: Mapped\[str]
    kurzform: Mapped\[str]
    order: Mapped\[int]
    # quality\_issues: existiert nicht

Warum gibt es kein quality\_issues-Feld? Weil der Quality Reviewer zwar läuft, seine Befunde aber nirgendwo persistent gemacht werden. Der Reviewer hat 12 Fehlerkategorien:

# modul-bewertung/src/models/types.py:119
class QualityIssue(BaseModel):
    category: str    # Fehler | Inkonsistenz | Halluzination | Quellenabweichung | ...
    description: str
    severity: str
    affected\_text: str
    correction: str

Er findet Probleme. Er korrigiert. Und dann:

# modul-bewertung/src/workflows/main\_workflow.py
chapter\_result = ChapterResult(
    draft=review\_result.revised\_chapter,  # das Korrigierte kommt durch
    # quality\_issues wird hier einfach nicht übergeben
)

In der Datenbank steht das korrigierte Ergebnis. Was korrigiert wurde, warum, ob es sich um eine Halluzination handelte oder eine Inkonsistenz, das ist weg. Ein Sachbearbeiter sieht eine Bewertung. Er sieht nicht ob das LLM ursprünglich etwas Falsches produziert hatte.

Was das bedeutet: Der Sachbearbeiter kann nicht einschätzen ob eine Bewertung "sauber" war oder mehrfach korrigiert werden musste. Zwei Bewertungen sehen in der Datenbank identisch aus, eine die beim ersten Durchlauf korrekt war, und eine die dreimal halluziniert hat bevor der Quality Reviewer sie in Form gebracht hat. Das ist ein Unterschied der für die Zuverlässigkeitseinschätzung enorm relevant wäre. Er ist unsichtbar.

Das gleiche gilt für den Applicability-Check. Für jeden Normsatz entscheidet eine LLM-Stage ob er überhaupt bewertet wird (bewerten), übersprungen wird (ueberspringen) oder nicht beurteilbar ist (nicht\_beurteilbar). Die Begründung wird intern erzeugt:

class ApplicabilityResult(BaseModel):
    decision: ApplicabilityDecision
    begruendung\_markdown: str  # warum diese Entscheidung

Aber begruendung\_markdown wird nicht in die Datenbank geschrieben. Wenn ein Normsatz als "nicht anwendbar" markiert ist, steht da kein Eintrag. Warum dieser Satz keine Bewertung hat, lässt sich aus der Datenbank nicht ableiten.

Was das bedeutet: Im fertigen Beschluss gibt es zu § X keine Prüfung. Jemand fragt: warum wurde § X nicht geprüft? Das System kann keine Antwort geben. War es eine bewusste Entscheidung? Ein Fehler in der Konfiguration? Hat die KI den Satz als "nicht anwendbar" eingestuft, obwohl er es war? Niemand weiß es. Bei einer Anfechtung vor dem Verwaltungsgericht ist genau das eine der ersten Fragen, und die Antwort ist schlicht nicht rekonstruierbar.

Der "Confidence" Score, oder: 1.0 für alles

Wir wissen, unterwegs verlieren wir das Eine oder Andere. Vielleicht. Aber wichtig wäre ja selbst für das was ich sehe, wie sicher und gut ist denn wenigstens der Teil der angezeigt wird? Ich such also nach einem quantitativen Qualitätssignal. Irgendetwas das einem Sachbearbeiter sagt: dieser Bewertung kannst du eher vertrauen, jener weniger. Auch die KI hat ja (noch) ihre Grenzen.

Es gibt zwei interne 1-10-Skalen. Eine im Planner, eine im Quality Reviewer. Beide sind im Prompt als Chain-of-Thought beschrieben, das LLM soll sich erst eine Zahl geben, dann weiterdenken. Diese Zahlen landen aber nicht im strukturierten Output-Schema, werden also auch nicht zurückgegeben. Sie sind Reasoning-Hilfsmittel, keine Kennzahlen.

Dann gibt es confidence-Felder in der Datenbank. Ich find sie:

# examination\_service/src/models/db/prufung\_models.py
class TechnischeNorm(Base):
    ...
    confidence: Mapped\[float] = mapped\_column(Float, default=1.0)

Und im Mapper:

# agent\_orchestration\_service/src/workflows/bewertung/mapper.py:150
db\_objects.append(TechnischeNorm(
    ...
    "confidence": 1.0,  # hardcoded
))

Jede TechnischeNorm bekommt confidence 1.0. Immer. Unabhängig von irgendetwas. Das ist kein Score, das ist ein Platzhalter. Und dann auch noch einer der möglicherweise Anwender in völlig falscher Sicherheit wiegt?

Es gibt noch eine Normvorschlag-Tabelle mit einem confidence-Feld, die tatsächlich eine echte Zahl aufnehmen könnte. Der Kommentar im Code: # NOTUSED. Die Tabelle wird nicht beschrieben.

Das einzige echte Qualitätssignal das Sachbearbeiter hinterlassen können ist Daumen hoch/runter-Feedback auf einzelne Bewertungen und Quellen, binär, manuell. Ob das systematisch ausgewertet wird, hab ich nicht gefunden.

Was das bedeutet: Ein Sachbearbeiter hat vor ihm 50 Bewertungen, jede mit confidence 1.0. Er hat keine maschinelle Grundlage um zu entscheiden welche er besonders kritisch gegenlesen sollte und welche er vertrauensvoll übernehmen kann. Er muss entweder alles gleichwertig prüfen, dann ist der Effizienzgewinn des Systems deutlich kleiner als versprochen, oder er vertraut dem System pauschal, und dann trägt er das Risiko der Fehler die er nicht sieht.

Das eigentliche Problem: niemand weiß wann es schief geht

Was mich wirklich beschäftigt ist nicht das einzelne technische Detail und teilweise Fehler. Es ist das Muster was ich überall gefunden habe.

Ich hab im Laufe der Woche noch einmal tiefer geschaut und ein systematisches Audit über die gesamte Codebasis gemacht, alle Backend-Services, alle Modulcluster, das Frontend, die geteilten Bibliotheken. Das Ergebnis war ernüchternd. Nicht weil irgendwo ein spektakulärer Bug steckt, sondern weil sich durch alle Schichten dasselbe Designprinzip zieht: bei Lücke oder Fehler still degradieren, und das Ergebnis als vollständig weiterreichen.

Das ist kein Einzelfall. Das ist Systemarchitektur.

Dokumente die spurlos verschwinden

# document\_management\_service/src/services/workflows/activities/compute\_diff.py:141-142
# Dateien mit gleichem Dateinamen werden als Duplikat verworfen

# persist\_zip\_diff.py:34-65
# \_to\_schema übernimmt den duplicate-Bucket gar nicht in die FileDiffResponse

Zwei hochgeladene Dateien mit demselben Namen, einer wird verworfen. Nicht in der UI angezeigt, nicht im Review-Prozess, kein Hinweis. Die FileDiffResponse die ans Frontend geht enthält den duplicate-Bucket schlicht nicht. Upload erfolgreich. Datei weg.

Ähnliches passiert weiter unten in der Pipeline: Quelldokumente ohne passende \_processed.json-Datei werden beim Ingest still übersprungen, nie extrahiert, nie geprüft:

# modul-plausibilitaet-pruefung/src/dms/dms\_client.py:96-109
# modul-formale-pruefung/src/services/dms\_client.py:120-134
# → kein passendes \_processed.json → continue, kein Log

Die formale Vollständigkeitsprüfung läuft über einen möglicherweise unvollständigen Dokumentensatz. Das Ergebnis sieht vollständig aus.

Was das bedeutet: Die formale Vollständigkeitsprüfung ist eigentlich der Gatekeeper, sie soll sicherstellen, dass alle Pflichtunterlagen vorliegen bevor das Verfahren weitergeht. Wenn ein Dokument durch einen Dateinamen-Konflikt oder eine fehlende Prozessierungsdatei aus der Prüfung fällt, kann das System "vollständig" melden obwohl ein Pflichtgutachten faktisch nicht geprüft wurde. Das Verfahren läuft weiter. Das fehlende Dokument fällt erst auf wenn jemand manuell nachzählt, oder wenn eine Klagebegründung drauf hinweist.

Der Gesetzeskorpus wird beim Einlesen still beschnitten

Die Gesetze-Normen-Datenbank ist das Herzstück, hier liegen die Texte die alles andere speisen. Was ich in den Parser-Schleifen gefunden habe:

# db-services/gesetze-normen-db-service/db\_pipelines/parsers/xml\_2/parser.py:622-646
# Normen ohne erkannten Typ oder mit Duplikat-Key → continue, kein Log

# json\_1/parser.py:156-168
# Absätze ohne Nummer → continue

# pw\_1/processor.py:653-696
# gleiches Muster, vier verschiedene Parser

Ein Gesetz wird als vollständig persistiert. Ein paar Paragraphen fehlen. Niemand weiß welche.

Was das bedeutet: Das LLM analysiert einen Normparagraphen auf Basis eines Textes der möglicherweise unvollständig ist, Absätze fehlen, Sätze fehlen. Es füllt die Lücken mit Trainingswissen. Das Ergebnis sieht vollständig begründet aus, basiert aber auf einem lückenhaften Rechtstext. Und weil niemand weiß welche Absätze beim Ingest verworfen wurden, weiß auch niemand bei welchen Normen dieses Risiko besteht.

Und dann das hier, ein echter Bug, kein Design-Entscheid:

# xml\_2/parser.py:594
if para\_titel == "Schlussformel": continue
# para\_titel ist ein XML-Element-Objekt, nicht ein String
# → Vergleich mit str ist immer False
# → der intendierte Skip feuert nie

Der Entwickler wollte Schlussformel-Abschnitte überspringen. Der Code tut das nicht, weil ein Element-Objekt nie gleich einem String ist. Stiller Logikbug. Läuft seit wann?

Dazu: Gerichtsurteile werden nur auf gruende und entscheidungsgruende indexiert, tatbestand, tenor, leitsatz werden zwar gespeichert, aber nie durchsuchbar gemacht. Der RAG-Retriever sieht sie nie.

Die Bewertung arbeitet auf einer gesampelten Teilmenge

# modul-bewertung/src/workflows/planner.py:63-67
# bei > MAX\_PLANNER\_MICROS (=600) Micros:
step = total / MAX\_PLANNER\_MICROS
sampled = \[micros\[int(i \* step)] for i in range(MAX\_PLANNER\_MICROS)]
# → Stride-Sampling, kein Log, kein Truncation-Flag im Output

Wenn für einen Normsatz mehr als 600 komprimierte Fundstellen existieren, baut der Planner sein Argumentationsgerüst aus einem gleichmäßig verteilten Sample. Die Applicability-Entscheidung, ob ein Satz überhaupt bewertet wird, trifft dasselbe Sample. Beweise für Anwendbarkeit können in den gedroppten Micros liegen. Das Ergebnis trägt kein sampled: true-Flag.

Dazu kürzt der MicroBuilder jeden Chunk-Text auf 2000 Zeichen vor der Micro-Bildung. Was dahinter steht, wird nie bewertet. Schlägt das Micro-Parsing fehl, kommt ein Fallback-Micro aus den rohen ersten 200 Zeichen, behandelt downstream als valides Micro, Warning im Log, nichts im Output.

Was das bedeutet: Ein Antragsdokument enthält auf Seite 87 einen entscheidenden Satz: "Die Lärmschutzwand wird auf 4 Meter erhöht um die Anforderungen nach § 41 BImSchG zu erfüllen." Wenn dieser Satz im 2001. Zeichen eines Chunks steht, oder wenn er in einem Micro landet das beim Parsing versagt, wird er nie in die Bewertung einbezogen. Das System kommt möglicherweise zum Ergebnis "Lärmschutzanforderung unklar", obwohl die Antwort explizit im Dokument steht. Der Sachbearbeiter sieht "nicht beurteilbar". Er weiß nicht warum, und er weiß nicht dass der relevante Satz einfach nicht gelesen wurde.

Einwendungen die im Nichts verschwinden

Das Einwendungsmanagement-Modul verarbeitet Bürgereinwendungen zu Planfeststellungsverfahren. Das ist politisch sensibel, jede Einwendung hat gesetzliche Relevanz.

# argument\_classification\_batch\_workflow.py:300-308
# LLM-Antwort hat falsche Länge (≠ Batchlänge)
# → gesamter Batch wird durch idx=-1, confidence=0.0 ersetzt
# → alle Argumente des Batches: "kein Match"
# → kein Error-Flag im ClassifiedArgument

Eine einzige fehlerhafte LLM-Antwort entwertet alle Argumente im Batch. Sie erscheinen als unklassifiziert, nicht als fehlgeschlagen. Wer die Klassifikationsergebnisse sieht, sieht keine Fehlermeldung. Er sieht unklassifizierte Argumente.

# argument\_extraction\_batch\_workflow.py:131-136
# Grounding (Fuzzy-Span-Match) schlägt fehl
# → Sentinel TextSpan(-1,-1)
# → Workflow continue → extrahiertes Argument fällt aus dem Output

Extrahierte Argumente die nicht sauber auf den Originaltext zurückgemappt werden können, verschwinden still. Die Einwendung ist im System. Das Argument ist es nicht.

Was das bedeutet: Nach § 73 VwVfG hat die Planfeststellungsbehörde eine Pflicht, alle fristgerecht erhobenen Einwendungen in die Abwägung einzubeziehen. Wenn ein Argument technisch aus der Pipeline fällt, erscheint es in der Abwägung nicht. Der Bürger hat seine Einwendung fristgerecht eingereicht. Die Behörde hat sie formal registriert. Aber das konkrete Argument wurde nie abgewogen, weil ein Fuzzy-Match fehlschlug. Das ist ein klassischer Abwägungsfehler, der zur Aufhebung des Beschlusses führen kann. Und niemand merkt es, bis der Betroffene klagt.

Ein Anwendungsfall, tief verdrahtet

Das System ist erkennbar für einen sehr spezifischen Kontext gebaut worden und trägt das auch überall durch. Der UUID-Anker des gesamten Seed-Systems:

# project\_logic\_service/src/services/projects/default\_topic\_seed\_data.py:7
DEFAULT\_PROJECT\_TYPE\_NAME = "Fernstraße"

Von diesem Eintrag hängen Dutzende von Seed-Skripten ab, Dokumenttypen, Prüfkataloge, Normgruppen. Der Formal-Completeness-Check hat einen eigenen Pflichtunterlagen-Katalog mit ~30 Dokumenttypen spezifisch für Fernstraßen-Planfeststellungsverfahren. Die TopicEnum mit 55 Werten ist vollständig planfeststellungsspezifisch. Die Risikohinweiser-Prompts haben die dreiteilige Beschlussstruktur (ENTSCHEIDUNG → BEGRÜNDUNG → RECHTSBEHELFSBELEHRUNG mit spezifischen Unterkapiteln wie "Wasserrechtliche Erlaubnis") hardcodiert.

Was mich dabei zusätzlich stört: TopicEnum ist in zwei verschiedenen Dateien dupliziert topic\_enums.py und default\_topic\_seed\_data.py. Zwei Wahrheitsquellen für dasselbe Vokabular, keine automatische Synchronisierung. Das ist ein Wartungsproblem das irgendwann zuschlägt.

Eine Portierung dieses Systems auf ein anderes Rechtsgebiet, BImSchG-Genehmigungsverfahren, Bergrecht, irgendetwas das nicht Fernstraßen-Planfeststellung ist, ist keine Konfigurationsaufgabe. Es ist eine Neu-Implementierung in mehreren Schichten gleichzeitig. Das hat mich auf jeden Fall enorm überrascht, denn so etwas skaliert ja nicht auf die hunderten möglichen Anwendungsfälle innerhalb Deutschlands, vielleicht sogar Europa.

Das systemische Muster

Ich hab aufgehört zu zählen bei Stelle 50. Das Audit hat am Ende über 7 strukturelle Root-Cause-Muster identifiziert die sich durch alle Schichten ziehen:

  • „Auflösen per Membership, Unauflösbares droppen" - if id in map, kein Log, ~15 Backend-Stellen: Topic-Namen, Bundesländer, Satz-auf-Absatz-Mapping, Markdown-Fragmente, Filenames, Claims
  • Malformte LLM-Antwort → Platzhalter statt Fehler - ~9 Modul-Stellen, falsche Länge entwertet ganze Batches, Downstream behandelt Degradiertes als vollständig
  • \[:N] / Stride-Sampling / Char-Caps ohne sichtbaren Marker - ~20 Stellen, inkonsistent - manche Stellen markieren ...gekürzt..., die kritischen nicht
  • Intern getrackt, an der Systemgrenze verworfen - error\_pages, skipped, .skipped - Status erfasst, nicht im Rückgabeobjekt oder in der UI ausgegeben
  • except …: pass / return None|\[] ohne Log - Korpus-Parser, Chunk-Enrichment, HTTP-404-Lookups - verschluckte Fehler die eine leere Antwort von einer fehlenden Antwort ununterscheidbar machen

All das passiert hinter einer Oberfläche die vollständig und korrekt aussieht. Das System wirft keine Fehler. Es produziert ein schönes Ergebnis. Und wenn man Glück hat, merkt man irgendwann dass dieses Ergebnis falsch ist.

Bitte nicht zu früh produktiv einsetzen

Nach den technischen Befunden habe ich mir auch angeschaut, wie das Projekt öffentlich kommuniziert wird. Groß angekündigt, politisch gewollt, Digitalisierung der Verwaltung — und ich verstehe den Druck. Planfeststellungsverfahren dauern in Deutschland viel zu lange.

Aber genau deshalb wäre ein produktiver Einsatz in echten Verfahren mit Rechtswirkung aus meiner Sicht aktuell hochriskant. Nicht weil die Idee schlecht ist, sondern weil das System Ergebnisse erzeugen kann, die vollständig wirken, obwohl relevante Informationen fehlen.

Auffallen würde das vermutlich in zwei Szenarien:

Erstens: Ein Beschluss wird angefochten, weil eine relevante Norm nicht geprüft wurde. Sie stand nicht in der manuellen TopicNorm-Konfiguration, das System hat sie nicht erkannt, das Ergebnis sah trotzdem vollständig aus.

Zweitens: Jemand prüft die juristischen Quellen nach. Wenn die Recherche zu Gerichtsentscheidungen und Gesetzesbegründungen zwar läuft, aber mit research_report=None nicht an das Bewertungs-LLM übergeben wird, bewertet das Modell faktisch ohne diese Quellen — also mit Trainingswissen, Cutoff-Datum und allen bekannten Halluzinationsrisiken.

Dass LLMs in juristischen Kontexten nicht existierende Urteile oder Aktenzeichen erfinden können, ist inzwischen dokumentiert. Genau deshalb ist belastbares Grounding hier entscheidend.

Der kritische Punkt ist also nicht: „KI darf nie helfen.“ Der Punkt ist: Ein System darf nicht so aussehen, als würde es auf vollständiger juristischer Substanz basieren, wenn zentrale Quellen, Normen oder Fehlerzustände für Nutzer unsichtbar bleiben.

Fairerweise: Warum das trotzdem relevant ist

Ich will das nicht als reinen Verriss stehen lassen. Einige Teile sind wirklich ordentlich gebaut: Quellenbelege mit cited_svm_id, Seitenzahlen und Chunk-IDs, robuste Temporal-Workflows und Temporal Tables für nachvollziehbare Datenbankzustände. Das ist nicht trivial und war sichtbar Arbeit.

Als Proof of Concept und Forschungsprojekt ist SPARK Workflow interessant. Die Grundidee ist gut. Aber es gibt technische Schnitzer, die dringend behoben werden müssten.

Denn die Kommunikation ist entscheidend: Wer „Multi-Agenten-System mit Graphdatenbank für automatisierte Rechtsprüfung“ hört, erwartet Autonomie, Vollständigkeit und Nachvollziehbarkeit. Tatsächlich wirkt es eher wie eine RAG-Pipeline mit festen LLM-Schritten und manuell konfiguriertem Normkatalog.

Im Legal-Kontext ist das kein Detail. Wenn Sachbearbeiter glauben, das System finde selbstständig alle relevanten Normen, obwohl es nur konfiguriertes Material verarbeitet, passt das Vertrauen nicht zur technischen Realität.

Je nach Einsatz kann das sehr nahe an High-Risk-Konstellationen des AI Acts heranreichen. Modellversionen, übersprungene Sätze, Reviewer-Korrekturen, Logging und Human Oversight sind hier keine Nice-to-haves, sondern Audit-Anforderungen.

Was ich mir wünschen würde

Nicht dass das System nicht existiert. Sondern dass es ehrlich kommuniziert wird.

Sagt dass es eine RAG-Pipeline ist, kein Multi-Agenten-System. Sagt dass die Normabdeckung manuell konfiguriert ist und keine Vollständigkeitsgarantie gibt. Sagt dass die Gerichtsentscheidungen aus der Datenbank aktuell nicht in die Bewertung einfließen. Sagt dass kein Confidence Score existiert. Sagt dass der Quality Reviewer Korrekturen vornimmt die niemand sehen kann.

Dann kann ein Sachbearbeiter das System korrekt einschätzen, entsprechend einsetzen, und die richtigen Stellen manuell nachprüfen. Das wäre ein nützliches Werkzeug.

Wer es stattdessen als vollautomatische Rechtsprüfungsmaschine positioniert, schafft ein Vertrauensniveau das die Technik schlicht nicht rechtfertigt. Und das Risiko trägt am Ende nicht der Hersteller.

Ich hab diese Woche wahrscheinlich mehr schlaflose Nächte damit verbracht als gesund ist. Aber wenn man sowieso nicht schläft, kann man wenigstens was aufschreiben das vielleicht nützlich ist.

Hat das schon jemand anderes genauer angeschaut? Interessiert mich ob ich was übersehen oder falsch eingeordnet habe.

u/North_Expert9120 — 10 days ago