
r/SoftwareDACH

Self-Promotion Samstag - KW 27/26
Heute ist Samstag. Der einzige Zeitpunkt, an dem die Regel gegen Eigenwerbung aufgehoben wird.
Wenn du an etwas baust, ob SaaS, Open-Source-Tool, Side-Project oder Service, droppe es hier. Heute ist Eigenwerbung erlaubt!
Template-Vorschlag
* Name + Link: Dein Projekt
* Was es macht: Ein Satz
* Für wen: Was ist der Anwendungsfall und die Zielgruppe
* Stand: Idee, MVP, live etc.
* Success-Stories: Welchen Erfolg möchtest du teilen? (opt.)
* Feedback-Frage: Eine Feedback-Frage an die Community (opt.)
Regeln:
* Nur eigene Projekte. Affiliate-Links für fremde Produkte werden entfernt.
* Kommentare oder Links ohne Beschreibung werden entfernt.
* Wenn du ein Projekt vorstellst, gib gerne in anderen Kommentaren Feedback.
* Kein MLM und keine Affiliate-Programme.
DACH-Bezug ist erwünscht, aber kein Muss.
Also, was baust du gerade?
Microsoft plant nächsten großen KI-Serverstandort in NRW
heise.deAnthropic says Claude Fable 5 and Mythos 5 are coming back tomorrow
Polizei und Palantir: Wie Bayern die Kontrolle über Palantir verliert
golem.deTrump threatens 100% tariffs on countries putting 'Digital Services Tax on American Companies'
cnbc.comDer eigene Juristische Dienst des EU-Rates sagt: Anlasslose Chatkontrolle unvereinbar mit Grundrechten!
Trotzdem soll genau das mit Verfahrenstricks doch noch erzwungen werden: https://patrick-breyer.de/doppelte-gefahr-fuer-private-kommunikation-undemokratische-hinterzimmer-deals-zur-chatkontrolle-lassen-widerstand-wieder-aufflammen/
Ich hatte gerade ein Update für Open Office
Das hat mich ziemlich irritiert. Ich dachte Apache bleibt gleich
Diskussion der Woche: Build or Buy? - KW27/26
Build or Buy: baut ihr selbst oder kauft ihr ein?
Tools werden teurer, gleichzeitig wird es mit KI-Unterstützung leichter, kleine Lösungen selbst zu bauen. Gleichzeitig beginnen Branchen-Experten spezfizierte Lösungen anzubieten.
Die KI-Coding-Hypothese: Wenn Personen Nischenlösungen bauen, könnt ihr das inzwischen auch.
Ein paar Anstöße:
- Habt ihr im Unternehmen bereits ein gekauftes Tool durch eine Eigenentwicklung ersetzt? Was war der Auslöser?
- Wo lohnt sich selbst bauen aus eurer Sicht, und wo bleibt Kaufen klar die bessere Wahl?
- Gibt es interne Projekte, die ihr gerne selbst umsetzen würdet, aber nicht dürft oder nicht schafft?
- Wie rechnet ihr das durch: Lizenzkosten gegen Entwicklungs- und Wartungsaufwand?
Erzählt gern von einem konkreten Fall. Was habt ihr gebaut, was gekauft, und würdet ihr es wieder so machen?
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.
Self-Promotion Samstag - KW 26/26
Heute ist Samstag. Der einzige Zeitpunkt, an dem die Regel gegen Eigenwerbung aufgehoben wird.
Wenn du an etwas baust, ob SaaS, Open-Source-Tool, Side-Project oder Service, droppe es hier. Heute ist Eigenwerbung erlaubt!
Template-Vorschlag
- Name + Link: Dein Projekt
- Was es macht: Ein Satz
- Für wen: Was ist der Anwendungsfall und die Zielgruppe
- Stand: Idee, MVP, live etc.
- Success-Stories: Welchen Erfolg möchtest du teilen? (opt.)
- Feedback-Frage: Eine Feedback-Frage an die Community (opt.)
Regeln:
- Nur eigene Projekte. Affiliate-Links für fremde Produkte werden entfernt.
- Kommentare oder Links ohne Beschreibung werden entfernt.
- Wenn du ein Projekt vorstellst, gib gerne in anderen Kommentaren Feedback.
- Kein MLM und keine Affiliate-Programme.
DACH-Bezug ist erwünscht, aber kein Muss.
Also, was baust du gerade?
KI im Marketing wo tauscht ihr euch dazu aus? (DACH)
Hi zusammen,
ich beschäftige mich beruflich viel mit Marketing und merke, dass sich gerade im Bereich KI alles wahnsinnig schnell entwickelt. Jeden Tag gibt's irgendwas Neues und ich komm gar nicht mehr mit 😢
Deshalb meine Frage: Gibt es aktive deutschsprachige Communities (Reddit, Discord, WhatsApp etc.), in denen man sich speziell über KI im Marketing austauscht? Oder vllt sogar live Veranstaltungen?
Ich hab echt keine Lust mehr mich alleine damit rumzuschlagen und ich denke dann immer, dass nur mich alle überfordert, aber glaube/ hoffe, dass andere da auch ähnliche Probleme haben.
Freue mich über jeden Tipp! thank uuu
US-Exportkontrolle schaltet Anthropics KI-Modelle weltweit ab, auch über AWS und Google Cloud. Hat Washington uns in Europa digital am Haken?
Letzte Woche hat das US-Handelsministerium Anthropic per Exportkontroll-Direktive untersagt, seine neuesten KI-Modelle (Mythos 5 und Fable 5) an ausländische Staatsbürger verfügbar zu machen — auch an solche innerhalb der USA. Weil man nicht in Echtzeit nach Nationalität filtern kann, wurde für alle abgeschaltet. Das lief nicht nur über Anthropics eigene API, sondern gleichzeitig über AWS Bedrock, Google Cloud und Microsoft. AWS hat global gekappt und auf Fallback-Modelle umgeleitet, ohne Ausnahme für regulierte Branchen.
Seitdem lässt mich ein Gedanke nicht los: Wenn eine US-Behörde so einen Schalter bei einem KI-Anbieter über mehrere Clouds gleichzeitig umlegen kann — was hindert sie daran, das im Konfliktfall mit anderen Diensten zu tun? In der EU laufen Wirtschaft, Verwaltung und kritische Infrastruktur fast vollständig auf AWS, Azure und Google Cloud.
In der Branche reden sie schon von einem „AI kill-switch". Ich frage mich: Überschätze ich das, oder hat Washington uns in Europa im Ernstfall bei den Eiern? Stichworte CLOUD Act, FISA, digitale Souveränität, Gaia-X.
Wie schätzt ihr das ein?
Infranode: keyless, Open Source MCP Server for AI agents .
Hi all, I built InfraNode, an open-source (Apache-2.0) MCP server that gives AI assistants live open data for 84 German cities: weather, air quality, public transit departures, parking, bike counts, solar potential and more, all from official open-data sources.
Why it might interest this community:
- Keyless and hosted. Point your client at the remote server (mcp.infranode.dev, streamable-http) and the tools just work. No signup, no API key.
- Around 48 read-only tools, plus a get_city_overview discovery tool so an agent can see in one call which data a given city offers and which tool to use next.
- The same data is also a plain REST API, so it works outside MCP too.
Repo: https://github.com/street1983nk/infranode
Docs: https://infranode.dev
Full disclosure: I am the author. I would love feedback on the tool design and especially the discovery flow.