[{"data":1,"prerenderedAt":5560},["ShallowReactive",2],{"blog-lokale-ki":3,"related-lokale-ki":759},{"id":4,"title":5,"body":6,"created":745,"description":746,"extension":747,"icon":748,"keyword":749,"lastUpdated":745,"meta":750,"navigation":751,"order":752,"path":753,"readingTime":754,"seo":755,"stem":756,"topic":757,"__hash__":758},"blog\u002Fblog\u002Flokale-ki.md","Lokale KI: Wo kleine Modelle die großen ablösen und wo nicht",{"type":7,"value":8,"toc":727},"minimark",[9,27,30,38,43,147,156,177,182,203,206,210,219,228,231,239,243,251,260,263,267,276,283,287,295,304,308,311,330,354,378,389,393,494,498,517,520,524,527,531,559,563],[10,11,12,13,20,21,26],"p",{},"6,6 Gigabyte. So groß ist der Download von Qwen3.5-9B in der ",[14,15,19],"a",{"href":16,"rel":17},"https:\u002F\u002Follama.com\u002Flibrary\u002Fqwen3.5",[18],"nofollow","Ollama-Bibliothek",". Das ist weniger als mancher Mitschnitt eines Quartalsmeetings und passt in den Arbeitsspeicher eines gewöhnlichen Business-Notebooks. Laut ",[14,22,25],{"href":23,"rel":24},"https:\u002F\u002Fhuggingface.co\u002FQwen\u002FQwen3.5-9B",[18],"Model Card"," erreicht dieses Modell auf GPQA Diamond 81,7 Punkte und liegt damit vor gpt-oss-120B mit 80,1, einem Modell mit mehr als der zehnfachen Parameterzahl. Das sind Herstellerangaben, und Benchmarks sind keine Produktionslast. Die Richtung stimmt trotzdem.",[10,28,29],{},"Ich höre in Architektur-Reviews noch oft den Satz \"Dafür nehmen wir das große Modell, sicher ist sicher\". Gemeint ist dann eine Aufgabe wie: eingehende E-Mails einer von zwölf Kategorien zuordnen. Dafür ein Frontier-Modell zu bezahlen, ist ungefähr so, als würde man für den Weg zum Bäcker einen Sattelzug mieten. Er kommt an, keine Frage.",[10,31,32,33,37],{},"Meine These für diesen Artikel: Bei eng umrissenen Aufgaben werden lokale Modelle die großen Foundation-Modelle Schritt für Schritt verdrängen. Bei offenen, mehrstufigen Aufgaben werden sie das auf absehbare Zeit nicht tun. Und wer lokal betreibt, übernimmt Sicherheitsarbeit, die vorher der Cloud-Anbieter gemacht hat. Die ",[14,34,36],{"href":35},"\u002Fblog\u002Fdeployment","Kosten- und Hardwarerechnung für Cloud, On-Prem und Hybrid"," habe ich an anderer Stelle aufgeschrieben, hier geht es um die Frage, welche Aufgaben wohin gehören.",[39,40,42],"h2",{"id":41},"was-2026-auf-ein-notebook-passt","Was 2026 auf ein Notebook passt",[44,45,46,65],"table",{},[47,48,49],"thead",{},[50,51,52,56,59,62],"tr",{},[53,54,55],"th",{},"Modell",[53,57,58],{},"Größen",[53,60,61],{},"Lizenz",[53,63,64],{},"Bemerkung",[66,67,68,89,113,130],"tbody",{},[50,69,70,77,80,83],{},[71,72,73],"td",{},[14,74,76],{"href":16,"rel":75},[18],"Qwen3.5 (kleine Serie)",[71,78,79],{},"0,8B, 2B, 4B, 9B",[71,81,82],{},"9B unter Apache 2.0",[71,84,85,86],{},"262.144 Token Kontext, Text, Bild und Video laut ",[14,87,25],{"href":23,"rel":88},[18],[50,90,91,98,101,104],{},[71,92,93],{},[14,94,97],{"href":95,"rel":96},"https:\u002F\u002Fai.google.dev\u002Fgemma\u002Fdocs\u002Fcore\u002Fmodel_card_4",[18],"Gemma 4",[71,99,100],{},"E2B, E4B, 12B, 26B A4B, 31B",[71,102,103],{},"Apache 2.0",[71,105,106,107,112],{},"Im ",[14,108,111],{"href":109,"rel":110},"https:\u002F\u002Fopensource.googleblog.com\u002F2026\u002F03\u002Fgemma-4-expanding-the-gemmaverse-with-apache-20.html",[18],"April 2026"," unter Apache 2.0 veröffentlicht, laut Google für lokale Ausführung ohne Cloud gedacht",[50,114,115,122,125,127],{},[71,116,117],{},[14,118,121],{"href":119,"rel":120},"https:\u002F\u002Fmistral.ai\u002Fnews\u002Fmistral-3",[18],"Ministral 3",[71,123,124],{},"3B, 8B, 14B",[71,126,103],{},[71,128,129],{},"Europäischer Anbieter, vom Hersteller für \"edge and local use cases\" positioniert",[50,131,132,139,142,144],{},[71,133,134],{},[14,135,138],{"href":136,"rel":137},"https:\u002F\u002Fhuggingface.co\u002Fopenai\u002Fgpt-oss-20b",[18],"gpt-oss-20b",[71,140,141],{},"21 Mrd. Parameter, davon 3,6 Mrd. aktiv",[71,143,103],{},[71,145,146],{},"Läuft laut OpenAI in 16 GB Speicher, Function Calling eingebaut",[10,148,149,150,155],{},"Dass diese Modelle so wenig Speicher brauchen, liegt an der Quantisierung. Die Gewichte werden mit weniger Bit gespeichert als im Training, typischerweise 4 bis 8 statt 16. Bei 4 Bit belegt eine Milliarde Parameter rechnerisch ein halbes Gigabyte. Was das an Qualität kostet, vergleicht eine ",[14,151,154],{"href":152,"rel":153},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2601.14277",[18],"Auswertung der llama.cpp-Formate vom Januar 2026"," systematisch für 3 bis 8 Bit. Mein Rat: Messen Sie die quantisierte Variante an Ihrer eigenen Aufgabe.",[10,157,158,159,164,165,170,171,176],{},"Auf der Hardwareseite hat sich die Frage \"Können wir das überhaupt betreiben?\" weitgehend erledigt. Microsoft definiert Copilot+ PCs über eine ",[14,160,163],{"href":161,"rel":162},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows\u002Fai\u002Fnpu-devices\u002F",[18],"NPU mit mehr als 40 TOPS",", in der Geräteliste stehen Business-Modelle wie das Dell Latitude 7455 und das Lenovo ThinkPad T14s. Apple nennt für den ",[14,166,169],{"href":167,"rel":168},"https:\u002F\u002Fwww.apple.com\u002Fnewsroom\u002F2025\u002F10\u002Fapple-unleashes-m5-the-next-big-leap-in-ai-performance-for-apple-silicon\u002F",[18],"M5"," eine Speicherbandbreite von 153 GB\u002Fs und wirbt ausdrücklich damit, größere Modelle vollständig auf dem Gerät auszuführen. Eine Klasse darüber steht NVIDIAs ",[14,172,175],{"href":173,"rel":174},"https:\u002F\u002Fwww.nvidia.com\u002Fen-us\u002Fproducts\u002Fworkstations\u002Fdgx-spark\u002F",[18],"DGX Spark"," mit 128 GB gemeinsamem Speicher, laut Hersteller für Inferenz mit Modellen bis 200 Milliarden Parameter. Als Laufzeitumgebung reichen auf dem Einzelplatz Ollama oder llama.cpp, für einen Teamserver mit vielen parallelen Anfragen ist vLLM die übliche Wahl.",[178,179,181],"h3",{"id":180},"die-betriebssysteme-machen-es-vor","Die Betriebssysteme machen es vor",[10,183,184,185,190,191,196,197,202],{},"Aufschlussreich finde ich, was die Plattformhersteller selbst tun. Apple liefert ein ",[14,186,189],{"href":187,"rel":188},"https:\u002F\u002Fmachinelearning.apple.com\u002Fresearch\u002Fapple-foundation-models-2025-updates",[18],"On-Device-Modell mit rund 3 Milliarden Parametern"," aus, quantisiert auf 2 Bit pro Gewicht, und beschreibt es so: stark bei Zusammenfassung, Entity-Extraktion, Textverständnis und kurzen Dialogen, aber \"not designed to be a chatbot for general world knowledge\". Google betreibt ",[14,192,195],{"href":193,"rel":194},"https:\u002F\u002Fdeveloper.android.com\u002Fai\u002Fgemini-nano",[18],"Gemini Nano"," im Android-Systemdienst AICore für Zusammenfassen, Korrekturlesen und Umformulieren, ohne Netzverbindung. Microsoft bietet mit ",[14,198,201],{"href":199,"rel":200},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows\u002Fai\u002Fapis\u002Fphi-silica",[18],"Phi Silica"," ein lokales Modell für Copilot+ PCs an.",[10,204,205],{},"Drei Konzerne mit eigenen Frontier-Modellen geben die kleinen Aufgaben also an kleine Modelle. Ein Detail aus der Microsoft-Dokumentation sollte Sie allerdings hellhörig machen: Phi Silica wird laut derselben Seite ab November 2026 auf Endgeräten durch ein neues Modell namens Aion Instruct ersetzt, Entwickler sollen ihre LoRA-Adapter neu trainieren. Ein Modell, das mit dem Betriebssystem kommt, wechselt nach dem Zeitplan des Herstellers. Wer darauf eine Fachanwendung baut, braucht Regressionstests.",[39,207,209],{"id":208},"wofür-kleine-modelle-reichen","Wofür kleine Modelle reichen",[10,211,212,213,218],{},"Die pointierteste Quelle dazu stammt von NVIDIA Research. Im Positionspapier ",[14,214,217],{"href":215,"rel":216},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2506.02153",[18],"Small Language Models are the Future of Agentic AI"," (Juni 2025, überarbeitet September 2025) argumentieren Belcak und Kollegen, kleine Modelle seien für die sich wiederholenden, eng geschnittenen Teilaufgaben in Agentensystemen \"sufficiently powerful, inherently more suitable, and necessarily more economical\". Ein kleines Modell ist dort eines, das auf ein übliches Endgerät passt, Stand 2025 also unter etwa 10 Milliarden Parameter. Den Betrieb eines 7-Milliarden-Modells beziffern die Autoren als 10 bis 30 Mal günstiger bei Latenz, Energie und Rechenaufwand als den eines Modells mit 70 bis 175 Milliarden Parametern. In drei Fallstudien schätzen sie, dass sich rund 60 Prozent der LLM-Aufrufe in MetaGPT, 40 Prozent in Open Operator und 70 Prozent in Cradle durch spezialisierte kleine Modelle ersetzen ließen. Es sind Schätzungen in einem Positionspapier, keine Messungen im Feld.",[10,220,221,222,227],{},"Belastbarer ist die Lage bei angepassten Modellen. In der Studie ",[14,223,226],{"href":224,"rel":225},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2405.00732",[18],"LoRA Land"," wurden 310 Modelle auf 31 Aufgaben feinjustiert. Die 4-Bit-Varianten lagen im Schnitt 34 Punkte über ihren Basismodellen und 10 Punkte über GPT-4. 25 dieser Adapter auf Basis von Mistral-7B liefen gemeinsam auf einer einzigen A100-GPU. Die Studie ist von 2024, der Vergleichsgegner GPT-4 ist längst abgelöst. Die kleinen Basismodelle von damals sind es aber auch.",[10,229,230],{},"Daraus ergibt sich für mich eine recht klare Liste von Aufgaben, bei denen ich 2026 zuerst ein lokales Modell prüfen würde: Klassifikation und Routing von Tickets und E-Mails, Extraktion von Feldern aus Rechnungen und Verträgen, Zusammenfassung einzelner Dokumente, Erkennen und Schwärzen personenbezogener Daten vor einem Cloud-Aufruf, Antworten aus einem eng begrenzten RAG-Bestand, einzelne Function Calls mit festem Schema. Gemeinsam ist ihnen, dass die Eingabe kurz ist, das Ausgabeformat feststeht und Sie die Qualität an ein paar hundert Beispielen messen können.",[10,232,233,234,238],{},"Die Gründe für lokal sind dann selten nur die Tokenkosten. Die Juristin im Einkauf kann einen Vertragsentwurf zusammenfassen lassen, ohne dass vorher ein Drittlandtransfer geprüft werden muss (die übrigen Pflichten bleiben, siehe ",[14,235,237],{"href":236},"\u002Fblog\u002Fdsgvo-llm","DSGVO und LLM Compliance","). Die Klassifikation läuft auch, wenn der Anbieter eine Störung hat oder das Werk in Tschechien gerade kein Netz. Und niemand kündigt Ihnen das Modell ab, auf das Sie Ihre Prompts monatelang abgestimmt haben.",[39,240,242],{"id":241},"wo-die-großen-modelle-bleiben","Wo die großen Modelle bleiben",[10,244,245,246,250],{},"Googles eigene Zahlen zeigen die Grenze ziemlich genau. In der ",[14,247,249],{"href":95,"rel":248},[18],"Gemma-4-Model-Card"," erreicht das kleine E4B auf MMLU Pro 69,4 Prozent, das 31B-Modell 85,2. Beim agentischen Benchmark Tau2 sind es 42,2 gegenüber 76,9 Prozent, das kleinste Modell E2B kommt auf 24,5. Wissen skaliert also halbwegs gnädig nach unten, mehrstufiges Handeln mit Werkzeugen nicht.",[10,252,253,254,259],{},"Eine Arbeit zu ",[14,255,258],{"href":256,"rel":257},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2511.22138",[18],"kleinen Modellen auf Edge-Geräten"," kommt zum gleichen Bild: Die besten Modelle im Bereich von 1 bis 3 Milliarden Parametern erreichten im Berkeley Function Calling Leaderboard nach aufwendiger Optimierung 65,74 Prozent insgesamt und 55,62 Prozent bei mehrstufigen Dialogen. Für einen einzelnen Aufruf mit Plausibilitätsprüfung kann das genügen. In einem Agentenlauf multiplizieren sich die Fehler. Ein Rechenbeispiel: Bei 95 Prozent Trefferquote pro Schritt kommen nach 20 abhängigen Schritten noch etwa 36 Prozent der Läufe fehlerfrei durch.",[10,261,262],{},"Komplexe Analyse über lange Dokumente, Codeänderungen über mehrere Dateien, offene Recherche, lange Agentenläufe mit vielen Werkzeugen: Hier würde ich kein Modell unter 30 Milliarden Parametern ohne menschliche Kontrolle einsetzen, und in vielen Fällen auch kein lokales. Die NVIDIA-Autoren räumen selbst ein, dass große Modelle beim allgemeinen Sprachverständnis vorn bleiben.",[39,264,266],{"id":265},"klein-zuerst-groß-als-eskalation","Klein zuerst, groß als Eskalation",[10,268,269,270,275],{},"Das Architekturmuster, das daraus folgt, funktioniert wie der First-Level-Support: Die meisten Anfragen löst die erste Stufe, der Rest wird weitergereicht. Die Arbeit ",[14,271,274],{"href":272,"rel":273},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2406.18665",[18],"RouteLLM"," hat gezeigt, dass ein gelernter Router zwischen einem schwächeren und einem stärkeren Modell die Kosten in manchen Fällen mehr als halbiert, ohne dass die Antwortqualität leidet.",[10,277,278,279,282],{},"In der Praxis braucht der Router drei Dinge. Erstens ein Eskalationskriterium, das sich prüfen lässt: Schema verletzt, Konfidenz unter Schwellwert, Eingabe länger als das Kontextbudget, Aufgabe nicht auf der Liste bekannter Typen. Zweitens eine Regel, was eskalieren darf. Im ",[14,280,281],{"href":35},"Deployment-Artikel"," routet der Proxy nach Datenklasse, hier kommt die Schwierigkeit als zweite Achse hinzu, und die Datenklasse gewinnt. Ein vertrauliches Dokument, an dem das kleine Modell scheitert, geht an ein größeres lokales Modell oder an einen Menschen, aber nie automatisch in die Cloud. Drittens eine Messung der Eskalationsquote. Steigt sie, hat sich die Eingabe verändert oder das Modell wurde getauscht.",[39,284,286],{"id":285},"souveränität-ist-der-rückenwind","Souveränität ist der Rückenwind",[10,288,106,289,294],{},[14,290,293],{"href":291,"rel":292},"https:\u002F\u002Fwww.bitkom.org\u002FPresse\u002FPresseinformation\u002FDeutsche-Cloud-4-von-10-Unternehmen-wuerden-Abstriche-in-Kauf-nehmen",[18],"Bitkom Cloud Report vom 17. Juni 2026"," halten 85 Prozent der 603 befragten Unternehmen Deutschland für zu abhängig von US-Cloud-Anbietern. 42 Prozent beziehen KI-Dienste aus der Cloud, 69 Prozent planen das binnen fünf Jahren. Bitkom-Präsident Wintergerst sagt dazu: \"Künstliche Intelligenz ist die Zukunftstechnologie schlechthin und braucht Rechenleistung, die häufig nur Cloud-Dienste anbieten.\"",[10,296,297,298,303],{},"Für Training und Frontier-Inferenz stimmt das. Für die Aufgaben aus der Liste oben stimmt es 2026 nicht mehr, und genau dort liegt ein großer Teil des Alltagsvolumens. Die EU-Kommission hat am 3. Juni 2026 den Vorschlag für einen ",[14,299,302],{"href":300,"rel":301},"https:\u002F\u002Fdigital-strategy.ec.europa.eu\u002Fen\u002Fpolicies\u002Fcloud-and-ai-development-act",[18],"Cloud and AI Development Act"," vorgelegt, der die Rechenzentrumskapazität in der EU binnen fünf bis sieben Jahren mindestens verdreifachen soll und Souveränitätsstufen für die öffentliche Beschaffung vorsieht. Das ist ein Vorschlag, Parlament und Rat verhandeln noch. Ich würde keine Architekturentscheidung darauf stützen. Ein Klassifikator auf dem eigenen Server ist heute verfügbar.",[39,305,307],{"id":306},"lokale-modelle-sind-software-lieferkette","Lokale Modelle sind Software-Lieferkette",[10,309,310],{},"Jetzt zu dem Teil, der in den Begeisterungsvorträgen fehlt. \"Lokal\" heißt, dass Sie einen Inferenzserver betreiben, Binärdateien aus dem Internet laden und beides aktuell halten müssen.",[10,312,313,317,318,323,324,329],{},[314,315,316],"strong",{},"Offene Instanzen."," SentinelLABS und Censys haben über 293 Tage ",[14,319,322],{"href":320,"rel":321},"https:\u002F\u002Fwww.sentinelone.com\u002Flabs\u002Fsilent-brothers-ollama-hosts-form-anonymous-ai-network-beyond-platform-guardrails\u002F",[18],"175.108 öffentlich erreichbare Ollama-Hosts in 130 Ländern"," gezählt, 48 Prozent davon mit aktivierten Tool-Calling-Fähigkeiten. Ollama bindet laut ",[14,325,328],{"href":326,"rel":327},"https:\u002F\u002Fdocs.ollama.com\u002Ffaq",[18],"eigener FAQ"," standardmäßig an 127.0.0.1, eine Authentifizierung erwähnt die FAQ nicht. Es genügt also eine einzige Umgebungsvariable, gesetzt vom Entwickler, der das Modell \"nur kurz\" vom zweiten Rechner aus erreichen wollte.",[10,331,332,335,336,341,342,347,348,353],{},[314,333,334],{},"Lücken in der Laufzeitumgebung."," Cyera hat im Mai 2026 mit ",[14,337,340],{"href":338,"rel":339},"https:\u002F\u002Fwww.cyera.com\u002Fresearch\u002Fbleeding-llama-critical-unauthenticated-memory-leak-in-ollama",[18],"Bleeding Llama"," (CVE-2026-7482, CVSS 9,1) eine Lücke in Ollama veröffentlicht, über die sich ohne Anmeldung Prozessspeicher auslesen ließ, darunter Prompts, Systemprompts und Umgebungsvariablen. Cyera spricht von rund 300.000 erreichbaren Servern. vLLM hatte im Februar 2026 mit ",[14,343,346],{"href":344,"rel":345},"https:\u002F\u002Fgithub.com\u002Fadvisories\u002FGHSA-4r2x-xpjr-7cvv",[18],"CVE-2026-22778"," eine Remote Code Execution mit CVSS 9,8, behoben in Version 0.14.1. Für llama.cpp wurde am 7. August 2026 ",[14,349,352],{"href":350,"rel":351},"https:\u002F\u002Fgithub.com\u002Fadvisories\u002FGHSA-6hc7-9rph-cm99",[18],"CVE-2026-43631"," mit CVSS 9,2 veröffentlicht. Inferenzserver gehören ins Patch-Management wie jeder Webserver. In vielen Umgebungen, die ich sehe, laufen sie dagegen als Experiment eines Teams, das niemand inventarisiert hat.",[10,355,356,359,360,365,366,371,372,377],{},[314,357,358],{},"Herkunft der Gewichte."," Das klassische PyTorch-Format basiert auf Pickle, und Hugging Face ",[14,361,364],{"href":362,"rel":363},"https:\u002F\u002Fhuggingface.co\u002Fdocs\u002Fhub\u002Fsecurity-pickle",[18],"warnt selbst",", dass beim Laden beliebiger Code ausgeführt werden kann. ReversingLabs fand im Februar 2025 ",[14,367,370],{"href":368,"rel":369},"https:\u002F\u002Fwww.reversinglabs.com\u002Fblog\u002Frl-identifies-malware-ml-model-hosted-on-hugging-face",[18],"zwei Modelle auf Hugging Face",", die den Scanner der Plattform umgingen und beim Laden eine Reverse Shell öffneten. Laden Sie Gewichte als safetensors oder GGUF, ausschließlich aus den Konten der Hersteller, und halten Sie Version und Hash fest. Die ",[14,373,376],{"href":374,"rel":375},"https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm032025-supply-chain\u002F",[18],"OWASP Top 10 für LLMs"," stellen nüchtern fest: \"Currently there are no strong provenance assurances in published models.\" Die Lizenz gehört in dieselbe Prüfung. Apache 2.0 ist unkompliziert, andere Modell-Lizenzen enthalten Nutzungsbeschränkungen, die Ihre Rechtsabteilung lesen sollte.",[10,379,380,383,384,388],{},[314,381,382],{},"Prompt Injection."," Sie verschwindet durch lokalen Betrieb nicht. Ein kleines Modell, das eine präparierte E-Mail zusammenfasst und danach ein Werkzeug aufruft, ist genauso angreifbar wie ein großes, eher mehr. Alles aus dem Artikel zu ",[14,385,387],{"href":386},"\u002Fblog\u002Fprompt-injection","Prompt Injection"," gilt unverändert, vor allem die Begrenzung dessen, was das Modell auslösen darf.",[39,390,392],{"id":391},"entscheidungshilfe-nach-anwendungsfall","Entscheidungshilfe nach Anwendungsfall",[44,394,395,408],{},[47,396,397],{},[50,398,399,402,405],{},[53,400,401],{},"Anwendungsfall",[53,403,404],{},"Empfehlung",[53,406,407],{},"Begründung",[66,409,410,421,431,441,451,462,472,483],{},[50,411,412,415,418],{},[71,413,414],{},"E-Mail- und Ticket-Klassifikation",[71,416,417],{},"Lokal",[71,419,420],{},"Festes Schema, hohes Volumen, gut messbar",[50,422,423,426,428],{},[71,424,425],{},"Feldextraktion aus Rechnungen, Verträgen",[71,427,417],{},[71,429,430],{},"Oft personenbezogen, Ausgabe validierbar",[50,432,433,436,438],{},[71,434,435],{},"PII-Erkennung vor Cloud-Aufrufen",[71,437,417],{},[71,439,440],{},"Der Filter darf die Daten nicht selbst verschicken",[50,442,443,446,448],{},[71,444,445],{},"Zusammenfassung einzelner Dokumente",[71,447,417],{},[71,449,450],{},"Auch im Betriebssystem schon so gelöst",[50,452,453,456,459],{},[71,454,455],{},"Interner Wissensassistent (RAG)",[71,457,458],{},"Hybrid",[71,460,461],{},"Klein zuerst, Eskalation nach Datenklasse",[50,463,464,467,469],{},[71,465,466],{},"Code-Assistenz",[71,468,458],{},[71,470,471],{},"Vervollständigung lokal, größere Umbauten groß",[50,473,474,477,480],{},[71,475,476],{},"Mehrstufige Agenten mit vielen Werkzeugen",[71,478,479],{},"Cloud oder großes Modell im eigenen Rechenzentrum",[71,481,482],{},"Fehler multiplizieren sich über die Schritte",[50,484,485,488,491],{},[71,486,487],{},"Offene Recherche, komplexe Analyse",[71,489,490],{},"Cloud",[71,492,493],{},"Hier zählt die Qualitätsspitze",[39,495,497],{"id":496},"was-geschäftsführung-und-cto-entscheiden-müssen","Was Geschäftsführung und CTO entscheiden müssen",[499,500,501,505,508,511,514],"ol",{},[502,503,504],"li",{},"Eine Person benennen, die für lokal betriebene Modelle und Inferenzserver verantwortlich ist, samt Inventar. Aufwand: eine Entscheidung und wenige Tage für die Bestandsaufnahme.",[502,506,507],{},"Eine Freigabeliste für Modelle festlegen: Herkunft, Lizenz, Format, Hash. Drei bis fünf Modelle genügen den meisten Häusern. Aufwand: ein bis zwei Wochen mit Security und Recht.",[502,509,510],{},"Die Regel \"kleines Modell zuerst\" für neue Anwendungsfälle beschließen. Wer ein großes Cloud-Modell will, begründet es mit einer Messung. Das kostet nichts außer Disziplin.",[502,512,513],{},"Inferenzserver in Patch-Management, Netzwerksegmentierung und Schwachstellenscan aufnehmen, mit Authentifizierung davor. Aufwand: je nach Reife Tage bis wenige Wochen.",[502,515,516],{},"Budget für Evaluation einplanen. Ohne eigenen Testdatensatz pro Anwendungsfall bleibt jede Modellwahl eine Geschmacksfrage.",[10,518,519],{},"Eine Grundsatzentscheidung \"alles lokal\" empfehle ich nicht. Sie verlieren damit die Aufgaben, bei denen große Modelle den Unterschied machen.",[39,521,523],{"id":522},"ihr-schritt-für-diese-woche","Ihr Schritt für diese Woche",[10,525,526],{},"Nehmen Sie den Cloud-LLM-Anwendungsfall mit dem höchsten Aufrufvolumen, der im Kern eine Klassifikation oder Extraktion ist. Lassen Sie 200 echte, bereits geprüfte Beispiele durch ein lokales 9B-Modell auf einem Entwickler-Notebook laufen, ohne Netzfreigabe des Ports, und legen Sie die Ergebnisse neben die des bisherigen Modells. Das ist ein Nachmittag Arbeit. Danach wissen Sie für diesen einen Fall, ob die These bei Ihnen trägt, und haben nebenbei Ihren ersten Testdatensatz.",[39,528,530],{"id":529},"weiterführend","Weiterführend",[532,533,534,540,547,554],"ul",{},[502,535,536,539],{},[14,537,538],{"href":35},"AI Deployment: Cloud vs. On-Prem vs. Hybrid",", Kostenrechnung, Hardware und Tool-Stack",[502,541,542,546],{},[14,543,545],{"href":544},"\u002Fblog\u002Fdata-privacy","Data Privacy Architecture für KI-Systeme",", PII-Minimierung und Data Residency",[502,548,549,553],{},[14,550,552],{"href":551},"\u002Fblog\u002Fllm-integration","LLM-Integration: 5 Patterns für Enterprise",", Gateway, RAG und Agenten",[502,555,556,558],{},[14,557,387],{"href":386},", warum das Problem mit dem Modellstandort nichts zu tun hat",[39,560,562],{"id":561},"quellen","Quellen",[532,564,565,571,577,583,589,595,601,607,613,619,625,631,637,643,649,655,661,667,673,679,685,691,697,703,709,715,721],{},[502,566,567,568],{},"Ollama, Modellbibliothek \"qwen3.5\", abgerufen September 2026, ",[14,569,16],{"href":16,"rel":570},[18],[502,572,573,574],{},"Qwen Team (Alibaba), Model Card Qwen3.5-9B, 2026, ",[14,575,23],{"href":23,"rel":576},[18],[502,578,579,580],{},"Google, Gemma 4 Model Card, 2026, ",[14,581,95],{"href":95,"rel":582},[18],[502,584,585,586],{},"Google Open Source Blog, \"Gemma 4: Expanding the Gemmaverse with Apache 2.0\", 02.04.2026, ",[14,587,109],{"href":109,"rel":588},[18],[502,590,591,592],{},"Mistral AI, \"Introducing Mistral 3\", 02.12.2025, ",[14,593,119],{"href":119,"rel":594},[18],[502,596,597,598],{},"OpenAI, Model Card gpt-oss-20b, 2025, ",[14,599,136],{"href":136,"rel":600},[18],[502,602,603,604],{},"Kurt, \"Which Quantization Should I Use? A Unified Evaluation of llama.cpp Quantization on Llama-3.1-8B-Instruct\", 11.01.2026, ",[14,605,152],{"href":152,"rel":606},[18],[502,608,609,610],{},"Microsoft Learn, \"Copilot+ PCs developer guide\", Stand 19.08.2026, ",[14,611,161],{"href":161,"rel":612},[18],[502,614,615,616],{},"Microsoft Learn, \"Get started with Phi Silica\", Stand 24.07.2026, ",[14,617,199],{"href":199,"rel":618},[18],[502,620,621,622],{},"Apple, \"Apple unleashes M5\", 15.10.2025, ",[14,623,167],{"href":167,"rel":624},[18],[502,626,627,628],{},"Apple Machine Learning Research, \"Updates to Apple's On-Device and Server Foundation Language Models\", 09.06.2025, ",[14,629,187],{"href":187,"rel":630},[18],[502,632,633,634],{},"Google, Android Developers, \"Gemini Nano\", Stand 08.09.2026, ",[14,635,193],{"href":193,"rel":636},[18],[502,638,639,640],{},"NVIDIA, Produktseite DGX Spark, abgerufen September 2026, ",[14,641,173],{"href":173,"rel":642},[18],[502,644,645,646],{},"Belcak et al. (NVIDIA Research), \"Small Language Models are the Future of Agentic AI\", 02.06.2025, überarbeitet 15.09.2025, ",[14,647,215],{"href":215,"rel":648},[18],[502,650,651,652],{},"Zhao et al., \"LoRA Land: 310 Fine-tuned LLMs that Rival GPT-4\", 29.04.2024, ",[14,653,224],{"href":224,"rel":654},[18],[502,656,657,658],{},"Haque et al., \"TinyLLM: Evaluation and Optimization of Small Language Models for Agentic Tasks on Edge Devices\", 27.11.2025, ",[14,659,256],{"href":256,"rel":660},[18],[502,662,663,664],{},"Ong et al., \"RouteLLM: Learning to Route LLMs with Preference Data\", 26.06.2024, ",[14,665,272],{"href":272,"rel":666},[18],[502,668,669,670],{},"Bitkom, \"Deutsche Cloud: 4 von 10 Unternehmen würden Abstriche in Kauf nehmen\", 17.06.2026, ",[14,671,291],{"href":291,"rel":672},[18],[502,674,675,676],{},"Europäische Kommission, \"Cloud and AI Development Act\", Stand 03.06.2026, ",[14,677,300],{"href":300,"rel":678},[18],[502,680,681,682],{},"SentinelLABS und Censys, \"Silent Brothers: Ollama Hosts Form Anonymous AI Network Beyond Platform Guardrails\", 29.01.2026, ",[14,683,320],{"href":320,"rel":684},[18],[502,686,687,688],{},"Ollama, FAQ, abgerufen September 2026, ",[14,689,326],{"href":326,"rel":690},[18],[502,692,693,694],{},"Cyera Research, \"Bleeding Llama: Critical Unauthenticated Memory Leak in Ollama\", Mai 2026, ",[14,695,338],{"href":338,"rel":696},[18],[502,698,699,700],{},"GitHub Advisory Database, GHSA-4r2x-xpjr-7cvv (CVE-2026-22778, vLLM), 02.02.2026, ",[14,701,344],{"href":344,"rel":702},[18],[502,704,705,706],{},"GitHub Advisory Database, GHSA-6hc7-9rph-cm99 (CVE-2026-43631, llama.cpp), 07.08.2026, ",[14,707,350],{"href":350,"rel":708},[18],[502,710,711,712],{},"Hugging Face, \"Pickle Scanning\", Hub-Dokumentation, ",[14,713,362],{"href":362,"rel":714},[18],[502,716,717,718],{},"ReversingLabs, \"Malicious ML models discovered on Hugging Face platform\", 06.02.2025, ",[14,719,368],{"href":368,"rel":720},[18],[502,722,723,724],{},"OWASP GenAI Security Project, \"LLM03:2025 Supply Chain\", ",[14,725,374],{"href":374,"rel":726},[18],{"title":728,"searchDepth":729,"depth":729,"links":730},"",2,[731,735,736,737,738,739,740,741,742,743,744],{"id":41,"depth":729,"text":42,"children":732},[733],{"id":180,"depth":734,"text":181},3,{"id":208,"depth":729,"text":209},{"id":241,"depth":729,"text":242},{"id":265,"depth":729,"text":266},{"id":285,"depth":729,"text":286},{"id":306,"depth":729,"text":307},{"id":391,"depth":729,"text":392},{"id":496,"depth":729,"text":497},{"id":522,"depth":729,"text":523},{"id":529,"depth":729,"text":530},{"id":561,"depth":729,"text":562},"2026-09-17","Ein 9-Milliarden-Modell läuft auf dem Notebook und reicht für Klassifikation, Extraktion und Routing. Wo lokale KI trägt, wo nicht, und wie Sie sie absichern.","md","cpu-chip","lokale-ki",{},true,35,"\u002Fblog\u002Flokale-ki",11,{"title":5,"description":746},"blog\u002Flokale-ki","enterprise-architektur","ZjcgGOjJmjB2GN649x1_z8uF3AFZeETaspTxSSHu1r0",[760,1861,3194],{"id":761,"title":545,"body":762,"created":1852,"description":1853,"extension":747,"icon":1854,"keyword":1855,"lastUpdated":1852,"meta":1856,"navigation":751,"order":1857,"path":544,"readingTime":1113,"seo":1858,"stem":1859,"topic":757,"__hash__":1860},"blog\u002Fblog\u002Fdata-privacy.md",{"type":7,"value":763,"toc":1823},[764,767,770,774,777,780,784,866,872,876,879,883,889,973,978,992,1006,1010,1015,1018,1023,1037,1042,1116,1126,1130,1135,1196,1206,1210,1215,1253,1258,1303,1313,1317,1322,1327,1332,1337,1342,1421,1430,1434,1440,1445,1453,1459,1469,1473,1478,1481,1486,1497,1507,1511,1514,1518,1524,1530,1535,1546,1550,1553,1612,1616,1619,1623,1634,1638,1641,1645,1726,1730,1734,1745,1749,1760,1764,1775,1779,1787,1791,1794,1797,1799,1819],[10,765,766],{},"Die Frage \"Ist unser KI-System DSGVO-konform?\" lässt sich nicht mit einer Checkbox beantworten. Sie lässt sich mit einer Architektur beantworten.",[10,768,769],{},"Privacy nachträglich in ein KI-System einzubauen funktioniert selten. Die Data Flows sind bereits definiert, die Speicherorte gewählt, die Provider-Verträge unterschrieben. Wer Privacy nicht von Anfang an mitdenkt, baut technische Schulden auf, die später teuer werden.",[39,771,773],{"id":772},"data-flow-mapping-wo-fließen-ihre-daten","Data Flow Mapping: Wo fließen Ihre Daten?",[10,775,776],{},"Bevor Sie über Maßnahmen nachdenken, brauchen Sie Sichtbarkeit. Für jeden KI-Touchpoint in Ihrem System:",[778,779],"ai-data-flow-diagram",{},[178,781,783],{"id":782},"die-kritischen-fragen-pro-touchpoint","Die kritischen Fragen pro Touchpoint",[44,785,786,799],{},[47,787,788],{},[50,789,790,793,796],{},[53,791,792],{},"Touchpoint",[53,794,795],{},"Fragen",[53,797,798],{},"Typische Risiken",[66,800,801,814,827,840,853],{},[50,802,803,808,811],{},[71,804,805],{},[314,806,807],{},"User Input",[71,809,810],{},"Enthält es PII? Wird es geloggt?",[71,812,813],{},"Unkontrolliertes Logging von Kundendaten",[50,815,816,821,824],{},[71,817,818],{},[314,819,820],{},"Preprocessing",[71,822,823],{},"Wird PII erkannt und redaktiert?",[71,825,826],{},"PII fließt unbemerkt zum LLM",[50,828,829,834,837],{},[71,830,831],{},[314,832,833],{},"LLM\u002FModel",[71,835,836],{},"Wo wird verarbeitet? Was speichert der Provider?",[71,838,839],{},"Drittland-Transfer, Provider-Training",[50,841,842,847,850],{},[71,843,844],{},[314,845,846],{},"Storage",[71,848,849],{},"Prompts? Responses? Embeddings? Wie lange?",[71,851,852],{},"Unbegrenzte Retention, fehlende Löschkonzepte",[50,854,855,860,863],{},[71,856,857],{},[314,858,859],{},"RAG\u002FRetrieval",[71,861,862],{},"Enthält die Knowledge Base PII? Access Control?",[71,864,865],{},"Unberechtigter Zugriff auf sensitive Dokumente",[10,867,868,871],{},[314,869,870],{},"Das Ziel:"," Eine dokumentierte Übersicht, die Sie bei der nächsten Audit-Anfrage vorlegen können.",[39,873,875],{"id":874},"die-7-privacy-patterns","Die 7 Privacy-Patterns",[10,877,878],{},"Nicht jedes System braucht alle Patterns. Die Auswahl hängt von Ihrer Datenklassifizierung und Risikobereitschaft ab.",[178,880,882],{"id":881},"pattern-1-pii-minimierung","Pattern 1: PII-Minimierung",[10,884,885,888],{},[314,886,887],{},"Prinzip:"," Nur die Daten verarbeiten, die das LLM wirklich braucht.",[890,891,895],"pre",{"className":892,"code":893,"language":894,"meta":728,"style":728},"language-python shiki shiki-themes github-dark github-dark github-dark","# Vorher: Alle verfügbaren Informationen\nprompt = f\"\"\"\nDer Kunde Max Müller (max.mueller@firma.de, Tel: 0171-1234567)\nhat am 15.03.2024 Produkt XYZ bestellt (Bestellung #12345).\nEr wohnt in der Musterstraße 42, 80331 München.\nWas ist der Status seiner Bestellung?\n\"\"\"\n\n# Nachher: Nur das Nötige\nprompt = f\"\"\"\nEin Kunde hat am 15.03.2024 Produkt XYZ bestellt (Bestellung #12345).\nWas ist der Status dieser Bestellung?\n\"\"\"\n","python",[896,897,898,906,911,916,922,928,934,940,946,952,957,962,968],"code",{"__ignoreMap":728},[899,900,903],"span",{"class":901,"line":902},"line",1,[899,904,905],{},"# Vorher: Alle verfügbaren Informationen\n",[899,907,908],{"class":901,"line":729},[899,909,910],{},"prompt = f\"\"\"\n",[899,912,913],{"class":901,"line":734},[899,914,915],{},"Der Kunde Max Müller (max.mueller@firma.de, Tel: 0171-1234567)\n",[899,917,919],{"class":901,"line":918},4,[899,920,921],{},"hat am 15.03.2024 Produkt XYZ bestellt (Bestellung #12345).\n",[899,923,925],{"class":901,"line":924},5,[899,926,927],{},"Er wohnt in der Musterstraße 42, 80331 München.\n",[899,929,931],{"class":901,"line":930},6,[899,932,933],{},"Was ist der Status seiner Bestellung?\n",[899,935,937],{"class":901,"line":936},7,[899,938,939],{},"\"\"\"\n",[899,941,943],{"class":901,"line":942},8,[899,944,945],{"emptyLinePlaceholder":751},"\n",[899,947,949],{"class":901,"line":948},9,[899,950,951],{},"# Nachher: Nur das Nötige\n",[899,953,955],{"class":901,"line":954},10,[899,956,910],{},[899,958,959],{"class":901,"line":754},[899,960,961],{},"Ein Kunde hat am 15.03.2024 Produkt XYZ bestellt (Bestellung #12345).\n",[899,963,965],{"class":901,"line":964},12,[899,966,967],{},"Was ist der Status dieser Bestellung?\n",[899,969,971],{"class":901,"line":970},13,[899,972,939],{},[10,974,975],{},[314,976,977],{},"Quick Check:",[532,979,980,983,986,989],{},[502,981,982],{},"Braucht das LLM Namen? → Meist nein",[502,984,985],{},"Braucht es Kontaktdaten? → Fast nie",[502,987,988],{},"Braucht es Adressen? → Selten",[502,990,991],{},"Was ist das absolute Minimum für die Aufgabe?",[10,993,994,997,998,1001,1002,1005],{},[314,995,996],{},"Aufwand:"," Gering | ",[314,999,1000],{},"Impact:"," Hoch | ",[314,1003,1004],{},"Empfehlung:"," Immer implementieren",[178,1007,1009],{"id":1008},"pattern-2-pseudonymisierung","Pattern 2: Pseudonymisierung",[10,1011,1012,1014],{},[314,1013,887],{}," PII durch Platzhalter ersetzen, Original-Mapping lokal behalten.",[1016,1017],"pseudonymization-flow",{},[10,1019,1020],{},[314,1021,1022],{},"Implementierungs-Approach:",[499,1024,1025,1028,1031,1034],{},[502,1026,1027],{},"PII-Detection (Presidio, spaCy NER, oder Custom-Regex)",[502,1029,1030],{},"Deterministisches Mapping (gleicher Input → gleicher Platzhalter)",[502,1032,1033],{},"Mapping in separater, verschlüsselter Datenbank",[502,1035,1036],{},"Restore nach LLM-Response",[10,1038,1039],{},[314,1040,1041],{},"Code-Skeleton:",[890,1043,1045],{"className":892,"code":1044,"language":894,"meta":728,"style":728},"class Pseudonymizer:\n    def pseudonymize(self, text: str, pii_entities: list) -> str:\n        \"\"\"Ersetzt PII durch Platzhalter, speichert Mapping lokal.\"\"\"\n        for entity in pii_entities:\n            pseudonym = f\"[{entity.type}_{hash(entity.text)[:8]}]\"\n            text = text.replace(entity.text, pseudonym)\n            self.store_mapping(pseudonym, entity.text)\n        return text\n\n    def restore(self, text: str) -> str:\n        \"\"\"Stellt Original-PII aus lokalem Mapping wieder her.\"\"\"\n        for pseudonym, original in self.get_mappings():\n            text = text.replace(pseudonym, original)\n        return text\n",[896,1046,1047,1052,1057,1062,1067,1072,1077,1082,1087,1091,1096,1101,1106,1111],{"__ignoreMap":728},[899,1048,1049],{"class":901,"line":902},[899,1050,1051],{},"class Pseudonymizer:\n",[899,1053,1054],{"class":901,"line":729},[899,1055,1056],{},"    def pseudonymize(self, text: str, pii_entities: list) -> str:\n",[899,1058,1059],{"class":901,"line":734},[899,1060,1061],{},"        \"\"\"Ersetzt PII durch Platzhalter, speichert Mapping lokal.\"\"\"\n",[899,1063,1064],{"class":901,"line":918},[899,1065,1066],{},"        for entity in pii_entities:\n",[899,1068,1069],{"class":901,"line":924},[899,1070,1071],{},"            pseudonym = f\"[{entity.type}_{hash(entity.text)[:8]}]\"\n",[899,1073,1074],{"class":901,"line":930},[899,1075,1076],{},"            text = text.replace(entity.text, pseudonym)\n",[899,1078,1079],{"class":901,"line":936},[899,1080,1081],{},"            self.store_mapping(pseudonym, entity.text)\n",[899,1083,1084],{"class":901,"line":942},[899,1085,1086],{},"        return text\n",[899,1088,1089],{"class":901,"line":948},[899,1090,945],{"emptyLinePlaceholder":751},[899,1092,1093],{"class":901,"line":954},[899,1094,1095],{},"    def restore(self, text: str) -> str:\n",[899,1097,1098],{"class":901,"line":754},[899,1099,1100],{},"        \"\"\"Stellt Original-PII aus lokalem Mapping wieder her.\"\"\"\n",[899,1102,1103],{"class":901,"line":964},[899,1104,1105],{},"        for pseudonym, original in self.get_mappings():\n",[899,1107,1108],{"class":901,"line":970},[899,1109,1110],{},"            text = text.replace(pseudonym, original)\n",[899,1112,1114],{"class":901,"line":1113},14,[899,1115,1086],{},[10,1117,1118,1120,1121,1001,1123,1125],{},[314,1119,996],{}," Mittel | ",[314,1122,1000],{},[314,1124,1004],{}," Bei sensiblen Daten",[178,1127,1129],{"id":1128},"pattern-3-encryption-at-rest-in-transit","Pattern 3: Encryption (At Rest & In Transit)",[10,1131,1132],{},[314,1133,1134],{},"Minimum-Standard für alle KI-bezogenen Daten:",[44,1136,1137,1150],{},[47,1138,1139],{},[50,1140,1141,1144,1147],{},[53,1142,1143],{},"Komponente",[53,1145,1146],{},"Encryption",[53,1148,1149],{},"Key Management",[66,1151,1152,1163,1174,1185],{},[50,1153,1154,1157,1160],{},[71,1155,1156],{},"Vector DB",[71,1158,1159],{},"AES-256",[71,1161,1162],{},"HashiCorp Vault \u002F AWS KMS",[50,1164,1165,1168,1171],{},[71,1166,1167],{},"Logs",[71,1169,1170],{},"AES-256, 90d Key Rotation",[71,1172,1173],{},"Managed",[50,1175,1176,1179,1182],{},[71,1177,1178],{},"Model Weights",[71,1180,1181],{},"Disk-level (LUKS)",[71,1183,1184],{},"—",[50,1186,1187,1190,1193],{},[71,1188,1189],{},"API Calls",[71,1191,1192],{},"TLS 1.3, mTLS für Service-to-Service",[71,1194,1195],{},"Certificate Manager",[10,1197,1198,1200,1201,1120,1203,1205],{},[314,1199,996],{}," Gering (meist Infrastruktur-Config) | ",[314,1202,1000],{},[314,1204,1004],{}," Immer",[178,1207,1209],{"id":1208},"pattern-4-data-residency","Pattern 4: Data Residency",[10,1211,1212,1214],{},[314,1213,887],{}," Daten bleiben in der gewünschten Region. Wichtig für DSGVO und Branchenregulierung.",[44,1216,1217,1227],{},[47,1218,1219],{},[50,1220,1221,1224],{},[53,1222,1223],{},"Requirement",[53,1225,1226],{},"Optionen",[66,1228,1229,1237,1245],{},[50,1230,1231,1234],{},[71,1232,1233],{},"EU-only",[71,1235,1236],{},"Azure OpenAI (EU West), AWS Bedrock (Frankfurt), Anthropic (EU)",[50,1238,1239,1242],{},[71,1240,1241],{},"Deutschland-only",[71,1243,1244],{},"On-Prem, Deutsche Cloud-Provider (IONOS, Hetzner)",[50,1246,1247,1250],{},[71,1248,1249],{},"On-Prem only",[71,1251,1252],{},"Llama 3, Mistral, Qwen (Self-hosted)",[10,1254,1255],{},[314,1256,1257],{},"Routing-Logik:",[890,1259,1261],{"className":892,"code":1260,"language":894,"meta":728,"style":728},"class RegionAwareRouter:\n    async def route(self, request, data_classification: str):\n        if data_classification == \"CONFIDENTIAL\":\n            return await self.onprem_client.chat(...)  # Bleibt intern\n        elif data_classification == \"INTERNAL\":\n            return await self.eu_client.chat(...)      # EU-Cloud OK\n        else:\n            return await self.cloud_client.chat(...)   # Überall OK\n",[896,1262,1263,1268,1273,1278,1283,1288,1293,1298],{"__ignoreMap":728},[899,1264,1265],{"class":901,"line":902},[899,1266,1267],{},"class RegionAwareRouter:\n",[899,1269,1270],{"class":901,"line":729},[899,1271,1272],{},"    async def route(self, request, data_classification: str):\n",[899,1274,1275],{"class":901,"line":734},[899,1276,1277],{},"        if data_classification == \"CONFIDENTIAL\":\n",[899,1279,1280],{"class":901,"line":918},[899,1281,1282],{},"            return await self.onprem_client.chat(...)  # Bleibt intern\n",[899,1284,1285],{"class":901,"line":924},[899,1286,1287],{},"        elif data_classification == \"INTERNAL\":\n",[899,1289,1290],{"class":901,"line":930},[899,1291,1292],{},"            return await self.eu_client.chat(...)      # EU-Cloud OK\n",[899,1294,1295],{"class":901,"line":936},[899,1296,1297],{},"        else:\n",[899,1299,1300],{"class":901,"line":942},[899,1301,1302],{},"            return await self.cloud_client.chat(...)   # Überall OK\n",[10,1304,1305,1120,1307,1309,1310,1312],{},[314,1306,996],{},[314,1308,1000],{}," Hoch für Compliance | ",[314,1311,1004],{}," Bei personenbezogenen\u002Fvertraulichen Daten",[178,1314,1316],{"id":1315},"pattern-5-ephemeral-prompts","Pattern 5: Ephemeral Prompts",[10,1318,1319,1321],{},[314,1320,887],{}," Prompts nicht persistent speichern, nur Metadaten für Debugging.",[10,1323,1324],{},[314,1325,1326],{},"Was loggen:",[532,1328,1329],{},[502,1330,1331],{},"Timestamp, User-ID, Model, Latency, Token-Count, Error-Codes",[10,1333,1334],{},[314,1335,1336],{},"Was NICHT loggen:",[532,1338,1339],{},[502,1340,1341],{},"Prompt-Inhalt, Response-Inhalt, PII in jeder Form",[890,1343,1345],{"className":892,"code":1344,"language":894,"meta":728,"style":728},"async def process(self, prompt: str) -> str:\n    response = await llm.complete(prompt)\n\n    # Nur Metadaten loggen\n    await log({\n        \"timestamp\": now(),\n        \"prompt_hash\": sha256(prompt),  # Für Debugging, nicht Rekonstruktion\n        \"prompt_length\": len(prompt),\n        \"user_id\": user.id,\n        \"model\": \"gpt-4\",\n        \"latency_ms\": elapsed\n    })\n\n    return response\n    # Prompt und Response werden nicht gespeichert\n",[896,1346,1347,1352,1357,1361,1366,1371,1376,1381,1386,1391,1396,1401,1406,1410,1415],{"__ignoreMap":728},[899,1348,1349],{"class":901,"line":902},[899,1350,1351],{},"async def process(self, prompt: str) -> str:\n",[899,1353,1354],{"class":901,"line":729},[899,1355,1356],{},"    response = await llm.complete(prompt)\n",[899,1358,1359],{"class":901,"line":734},[899,1360,945],{"emptyLinePlaceholder":751},[899,1362,1363],{"class":901,"line":918},[899,1364,1365],{},"    # Nur Metadaten loggen\n",[899,1367,1368],{"class":901,"line":924},[899,1369,1370],{},"    await log({\n",[899,1372,1373],{"class":901,"line":930},[899,1374,1375],{},"        \"timestamp\": now(),\n",[899,1377,1378],{"class":901,"line":936},[899,1379,1380],{},"        \"prompt_hash\": sha256(prompt),  # Für Debugging, nicht Rekonstruktion\n",[899,1382,1383],{"class":901,"line":942},[899,1384,1385],{},"        \"prompt_length\": len(prompt),\n",[899,1387,1388],{"class":901,"line":948},[899,1389,1390],{},"        \"user_id\": user.id,\n",[899,1392,1393],{"class":901,"line":954},[899,1394,1395],{},"        \"model\": \"gpt-4\",\n",[899,1397,1398],{"class":901,"line":754},[899,1399,1400],{},"        \"latency_ms\": elapsed\n",[899,1402,1403],{"class":901,"line":964},[899,1404,1405],{},"    })\n",[899,1407,1408],{"class":901,"line":970},[899,1409,945],{"emptyLinePlaceholder":751},[899,1411,1412],{"class":901,"line":1113},[899,1413,1414],{},"    return response\n",[899,1416,1418],{"class":901,"line":1417},15,[899,1419,1420],{},"    # Prompt und Response werden nicht gespeichert\n",[10,1422,1423,997,1425,1120,1427,1429],{},[314,1424,996],{},[314,1426,1000],{},[314,1428,1004],{}," Default für Production",[178,1431,1433],{"id":1432},"pattern-6-differential-privacy-für-training","Pattern 6: Differential Privacy (für Training)",[10,1435,1436,1439],{},[314,1437,1438],{},"Wann relevant:"," Fine-Tuning auf Kundendaten, Custom-Embeddings mit sensiblen Dokumenten.",[10,1441,1442,1444],{},[314,1443,887],{}," Noise so hinzufügen, dass aggregierte Patterns gelernt werden, aber einzelne Datenpunkte nicht extrahierbar sind.",[890,1446,1451],{"className":1447,"code":1449,"language":1450},[1448],"language-text","Klassisches Training:\nModel lernt: \"Max Müller kaufte am 15.3. Produkt X\"\n→ Risiko: Model könnte \"Max Müller\" reproduzieren\n\nDifferential Privacy:\nNoise hinzufügen, sodass:\n→ \"Kunden kaufen Produkt X häufig im März\" gelernt wird\n→ Einzelne Personen nicht identifizierbar\n","text",[896,1452,1449],{"__ignoreMap":728},[10,1454,1455,1458],{},[314,1456,1457],{},"Tools:"," TensorFlow Privacy, Opacus (PyTorch), PySyft",[10,1460,1461,1001,1463,1465,1466,1468],{},[314,1462,996],{},[314,1464,1000],{}," Hoch für Training-Szenarien | ",[314,1467,1004],{}," Bei Fine-Tuning auf PII",[178,1470,1472],{"id":1471},"pattern-7-federated-learning","Pattern 7: Federated Learning",[10,1474,1475,1477],{},[314,1476,887],{}," Daten bleiben lokal, nur Model-Updates werden geteilt.",[1479,1480],"federated-learning-diagram",{},[10,1482,1483],{},[314,1484,1485],{},"Wann sinnvoll:",[532,1487,1488,1491,1494],{},[502,1489,1490],{},"Multi-Standort-Unternehmen mit lokalen Datenschutzanforderungen",[502,1492,1493],{},"Sensible Daten, die nicht zentralisiert werden dürfen",[502,1495,1496],{},"Branchenspezifische Regulierung (Gesundheit, Finanzen)",[10,1498,1499,1501,1502,1001,1504,1506],{},[314,1500,996],{}," Sehr hoch | ",[314,1503,1000],{},[314,1505,1004],{}," Nur bei spezifischen Anforderungen",[39,1508,1510],{"id":1509},"rag-systeme-die-unterschätzten-risiken","RAG-Systeme: Die unterschätzten Risiken",[10,1512,1513],{},"RAG (Retrieval-Augmented Generation) hat spezielle Privacy-Herausforderungen, die oft übersehen werden.",[178,1515,1517],{"id":1516},"problem-1-embeddings-sind-nicht-anonymisiert","Problem 1: Embeddings sind NICHT anonymisiert",[890,1519,1522],{"className":1520,"code":1521,"language":1450},[1448],"Original: \"Max Müller arbeitet in der IT-Abteilung\"\n     ↓\nEmbedding: [0.23, -0.45, 0.12, ...]\n     ↓\nSemantisch ähnlich zu: \"Müller ist IT-Mitarbeiter\"\n",[896,1523,1521],{"__ignoreMap":728},[10,1525,1526,1529],{},[314,1527,1528],{},"Implikation:"," Embeddings enthalten die semantische Information des Originals. Wer Zugriff auf die Vector DB hat, kann Inhalte rekonstruieren.",[10,1531,1532],{},[314,1533,1534],{},"Mitigation:",[532,1536,1537,1540,1543],{},[502,1538,1539],{},"Embeddings wie Original-Daten behandeln (Encryption, Access Control)",[502,1541,1542],{},"PII vor dem Embedding entfernen",[502,1544,1545],{},"Chunking so gestalten, dass PII nicht in Chunks landet",[178,1547,1549],{"id":1548},"problem-2-fehlende-access-control","Problem 2: Fehlende Access Control",[10,1551,1552],{},"Ein häufiger Fehler: Alle Dokumente werden in eine Vector DB geladen, alle User können alles abfragen.",[890,1554,1556],{"className":892,"code":1555,"language":894,"meta":728,"style":728},"# Falsch: Keine Filterung\nresults = vector_db.query(embedding)\n\n# Richtig: Row-Level Security\nresults = vector_db.query(\n    embedding,\n    filter={\n        \"department\": {\"$in\": user.departments},\n        \"classification\": {\"$lte\": user.clearance_level}\n    }\n)\n",[896,1557,1558,1563,1568,1572,1577,1582,1587,1592,1597,1602,1607],{"__ignoreMap":728},[899,1559,1560],{"class":901,"line":902},[899,1561,1562],{},"# Falsch: Keine Filterung\n",[899,1564,1565],{"class":901,"line":729},[899,1566,1567],{},"results = vector_db.query(embedding)\n",[899,1569,1570],{"class":901,"line":734},[899,1571,945],{"emptyLinePlaceholder":751},[899,1573,1574],{"class":901,"line":918},[899,1575,1576],{},"# Richtig: Row-Level Security\n",[899,1578,1579],{"class":901,"line":924},[899,1580,1581],{},"results = vector_db.query(\n",[899,1583,1584],{"class":901,"line":930},[899,1585,1586],{},"    embedding,\n",[899,1588,1589],{"class":901,"line":936},[899,1590,1591],{},"    filter={\n",[899,1593,1594],{"class":901,"line":942},[899,1595,1596],{},"        \"department\": {\"$in\": user.departments},\n",[899,1598,1599],{"class":901,"line":948},[899,1600,1601],{},"        \"classification\": {\"$lte\": user.clearance_level}\n",[899,1603,1604],{"class":901,"line":954},[899,1605,1606],{},"    }\n",[899,1608,1609],{"class":901,"line":754},[899,1610,1611],{},")\n",[178,1613,1615],{"id":1614},"problem-3-unerwartetes-retrieval","Problem 3: Unerwartetes Retrieval",[10,1617,1618],{},"Ein Query über Produkte kann Kundendaten retrieven, wenn die Knowledge Base beides enthält.",[10,1620,1621],{},[314,1622,1534],{},[532,1624,1625,1628,1631],{},[502,1626,1627],{},"Strikte Trennung von Datentypen in der Vector DB",[502,1629,1630],{},"Metadaten-basiertes Filtering",[502,1632,1633],{},"Output-Screening als letzte Verteidigungslinie",[39,1635,1637],{"id":1636},"referenz-architektur","Referenz-Architektur",[1639,1640],"privacy-rag-architecture",{},[39,1642,1644],{"id":1643},"pattern-auswahl-nach-datenklassifizierung","Pattern-Auswahl nach Datenklassifizierung",[44,1646,1647,1663],{},[47,1648,1649],{},[50,1650,1651,1654,1657,1660],{},[53,1652,1653],{},"Datenklasse",[53,1655,1656],{},"Minimum",[53,1658,1659],{},"Empfohlen",[53,1661,1662],{},"Optional",[66,1664,1665,1679,1695,1711],{},[50,1666,1667,1672,1675,1677],{},[71,1668,1669],{},[314,1670,1671],{},"Öffentlich",[71,1673,1674],{},"Encryption, Ephemeral Prompts",[71,1676,1184],{},[71,1678,1184],{},[50,1680,1681,1686,1689,1692],{},[71,1682,1683],{},[314,1684,1685],{},"Intern",[71,1687,1688],{},"+ PII-Minimierung",[71,1690,1691],{},"Data Residency (EU)",[71,1693,1694],{},"Pseudonymisierung",[50,1696,1697,1702,1705,1708],{},[71,1698,1699],{},[314,1700,1701],{},"Vertraulich",[71,1703,1704],{},"+ Pseudonymisierung, Data Residency",[71,1706,1707],{},"On-Prem Routing",[71,1709,1710],{},"Federated Learning",[50,1712,1713,1718,1721,1724],{},[71,1714,1715],{},[314,1716,1717],{},"Streng vertraulich",[71,1719,1720],{},"Kein LLM oder On-Prem only",[71,1722,1723],{},"Differential Privacy",[71,1725,1184],{},[39,1727,1729],{"id":1728},"implementation-roadmap","Implementation Roadmap",[178,1731,1733],{"id":1732},"phase-1-sichtbarkeit-woche-1-2","Phase 1: Sichtbarkeit (Woche 1-2)",[532,1735,1736,1739,1742],{},[502,1737,1738],{},"Data Flow Mapping für alle KI-Systeme",[502,1740,1741],{},"Identifikation von PII-Touchpoints",[502,1743,1744],{},"Dokumentation des Ist-Zustands",[178,1746,1748],{"id":1747},"phase-2-quick-wins-woche-3-4","Phase 2: Quick Wins (Woche 3-4)",[532,1750,1751,1754,1757],{},[502,1752,1753],{},"PII-Minimierung in Prompts",[502,1755,1756],{},"Encryption At Rest und In Transit (falls nicht vorhanden)",[502,1758,1759],{},"Ephemeral Prompts statt Full Logging",[178,1761,1763],{"id":1762},"phase-3-strukturelle-maßnahmen-monat-2-3","Phase 3: Strukturelle Maßnahmen (Monat 2-3)",[532,1765,1766,1769,1772],{},[502,1767,1768],{},"Pseudonymisierung-Pipeline implementieren",[502,1770,1771],{},"Data Residency Routing (EU-Cloud oder On-Prem)",[502,1773,1774],{},"Access Control für RAG-Systeme",[178,1776,1778],{"id":1777},"phase-4-advanced-bei-bedarf","Phase 4: Advanced (bei Bedarf)",[532,1780,1781,1784],{},[502,1782,1783],{},"Differential Privacy für Fine-Tuning",[502,1785,1786],{},"Federated Learning für Multi-Standort-Szenarien",[39,1788,1790],{"id":1789},"der-häufigste-fehler","Der häufigste Fehler",[10,1792,1793],{},"RAG-Systeme ohne Access Control auf Dokumenten-Level.",[10,1795,1796],{},"Ein einziger Vektor-Query kann sensible Informationen zurückliefern, für die der User keine Berechtigung hat. Implementieren Sie Row-Level-Security von Anfang an. Nachträglich ist es deutlich aufwändiger.",[39,1798,530],{"id":529},[532,1800,1801,1807,1813],{},[502,1802,1803,1806],{},[14,1804,1805],{"href":236},"DSGVO & LLM Compliance",": Rechtliche Anforderungen im Detail",[502,1808,1809,1812],{},[14,1810,1811],{"href":35},"AI Deployment-Strategien",": EU-Hosting und On-Prem-Optionen",[502,1814,1815,1818],{},[14,1816,1817],{"href":551},"Sichere LLM-Integration",": Integration-Patterns für Enterprise",[1820,1821,1822],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":728,"searchDepth":729,"depth":729,"links":1824},[1825,1828,1837,1842,1843,1844,1850,1851],{"id":772,"depth":729,"text":773,"children":1826},[1827],{"id":782,"depth":734,"text":783},{"id":874,"depth":729,"text":875,"children":1829},[1830,1831,1832,1833,1834,1835,1836],{"id":881,"depth":734,"text":882},{"id":1008,"depth":734,"text":1009},{"id":1128,"depth":734,"text":1129},{"id":1208,"depth":734,"text":1209},{"id":1315,"depth":734,"text":1316},{"id":1432,"depth":734,"text":1433},{"id":1471,"depth":734,"text":1472},{"id":1509,"depth":729,"text":1510,"children":1838},[1839,1840,1841],{"id":1516,"depth":734,"text":1517},{"id":1548,"depth":734,"text":1549},{"id":1614,"depth":734,"text":1615},{"id":1636,"depth":729,"text":1637},{"id":1643,"depth":729,"text":1644},{"id":1728,"depth":729,"text":1729,"children":1845},[1846,1847,1848,1849],{"id":1732,"depth":734,"text":1733},{"id":1747,"depth":734,"text":1748},{"id":1762,"depth":734,"text":1763},{"id":1777,"depth":734,"text":1778},{"id":1789,"depth":729,"text":1790},{"id":529,"depth":729,"text":530},"2025-12-07","Privacy by Design für LLM-Anwendungen: PII-Minimierung, Pseudonymisierung, Data Residency. Architektur-Patterns für DSGVO-konforme RAG-Systeme.","lock-closed","data-privacy",{},34,{"title":545,"description":1853},"blog\u002Fdata-privacy","ObD8UAeWftMTAr0SnPoIRlnQRz8xwZ-2NcnfkRIsTC0",{"id":1862,"title":538,"body":1863,"created":3185,"description":3186,"extension":747,"icon":3187,"keyword":3188,"lastUpdated":3189,"meta":3190,"navigation":751,"order":2739,"path":35,"readingTime":1113,"seo":3191,"stem":3192,"topic":757,"__hash__":3193},"blog\u002Fblog\u002Fdeployment.md",{"type":7,"value":1864,"toc":3151},[1865,1871,1874,1877,1880,1884,1887,1891,1894,1899,1931,1936,1953,1957,1960,1965,1991,1996,2013,2017,2020,2025,2039,2041,2045,2048,2051,2055,2061,2067,2073,2077,2080,2129,2134,2142,2144,2148,2151,2154,2158,2163,2169,2174,2180,2185,2191,2193,2197,2201,2284,2288,2414,2418,2522,2527,2547,2549,2553,2556,2559,2563,2566,2805,2807,2811,2815,2887,2891,2897,2901,2921,2923,2927,2930,2934,2977,2981,3026,3030,3067,3069,3073,3078,3114,3117,3119,3121,3148],[10,1866,1867,1868],{},"Sie haben einen AI Use Case identifiziert. Jetzt die Frage: ",[314,1869,1870],{},"Wo läuft das Modell?",[10,1872,1873],{},"Die Antwort ist 2025 weniger eindeutig als noch vor einem Jahr. Qwen3-8B läuft auf einem Laptop und übertrifft Modelle, die 2024 noch Serverfarmen brauchten. Llama 3.3 70B liefert nahezu GPT-4-Qualität auf einer einzelnen GPU. Gleichzeitig bleiben Cloud-APIs für viele Use Cases die bessere Wahl.",[10,1875,1876],{},"Dieser Artikel gibt Ihnen eine klare Entscheidungsgrundlage: Wann Cloud, wann Self-Hosting, wann Hybrid? Mit aktuellen Benchmarks, Hardware-Empfehlungen und realistischen Kostenrechnungen.",[1878,1879],"hr",{},[39,1881,1883],{"id":1882},"die-drei-deployment-optionen-im-überblick","Die drei Deployment-Optionen im Überblick",[1885,1886],"deployment-comparison-diagram",{},[178,1888,1890],{"id":1889},"option-1-cloud-api","Option 1: Cloud API",[10,1892,1893],{},"Sie nutzen die APIs von OpenAI, Anthropic, Google oder Azure. Das Modell läuft auf deren Infrastruktur.",[10,1895,1896],{},[314,1897,1898],{},"Aktuelle Frontier-Modelle (Dezember 2025):",[532,1900,1901,1907,1913,1919,1925],{},[502,1902,1903,1906],{},[314,1904,1905],{},"OpenAI:"," GPT-5.1 (State of the Art), GPT-5 mini (günstig)",[502,1908,1909,1912],{},[314,1910,1911],{},"Anthropic:"," Claude Opus 4.5 (beste Coding-Performance), Sonnet 4.5, Haiku 4.5",[502,1914,1915,1918],{},[314,1916,1917],{},"Google:"," Gemini 3 Pro (1M Context, multimodal)",[502,1920,1921,1924],{},[314,1922,1923],{},"Azure OpenAI:"," GPT-5.1 mit Enterprise-Features (EU-Region)",[502,1926,1927,1930],{},[314,1928,1929],{},"AWS Bedrock:"," Multi-Model-Zugang (Claude, Llama, Mistral)",[10,1932,1933],{},[314,1934,1935],{},"Wann Cloud?",[532,1937,1938,1941,1944,1947,1950],{},[502,1939,1940],{},"Schneller Start ist wichtiger als Kosten",[502,1942,1943],{},"Sie brauchen Frontier-Qualität (GPT-5.1\u002FClaude Opus 4.5-Level)",[502,1945,1946],{},"Keine hochsensiblen Daten",[502,1948,1949],{},"Volumen unter 15-20M Tokens\u002FMonat",[502,1951,1952],{},"Kein Infra-Team vorhanden",[178,1954,1956],{"id":1955},"option-2-self-hosted-on-premises","Option 2: Self-Hosted (On-Premises)",[10,1958,1959],{},"Sie betreiben LLMs auf eigener Hardware oder dedizierten Cloud-GPUs. Das Modell und die Daten bleiben unter Ihrer Kontrolle.",[10,1961,1962],{},[314,1963,1964],{},"Die besten Open-Source-Modelle (Dezember 2025):",[532,1966,1967,1973,1979,1985],{},[502,1968,1969,1972],{},[314,1970,1971],{},"Qwen3-8B:"," Best-in-class für kleine Modelle, übertrifft Qwen2.5-14B",[502,1974,1975,1978],{},[314,1976,1977],{},"Llama 3.3 70B:"," Frontier-Performance, 128K Context, nahe GPT-4o",[502,1980,1981,1984],{},[314,1982,1983],{},"Mistral Nemo 12B:"," EU-Anbieter, Apache 2.0 Lizenz",[502,1986,1987,1990],{},[314,1988,1989],{},"DeepSeek-R1 8B:"," Exzellent für Reasoning\u002FMath",[10,1992,1993],{},[314,1994,1995],{},"Wann Self-Hosted?",[532,1997,1998,2001,2004,2007,2010],{},[502,1999,2000],{},"Vertrauliche oder personenbezogene Daten",[502,2002,2003],{},"Strenge Compliance (Gesundheit, Finanzen, DSGVO)",[502,2005,2006],{},"Volumen über 20M Tokens\u002FMonat",[502,2008,2009],{},"Latenz kritisch (\u003C50ms)",[502,2011,2012],{},"Infra-Expertise vorhanden",[178,2014,2016],{"id":2015},"option-3-hybrid","Option 3: Hybrid",[10,2018,2019],{},"Die meisten Enterprises landen hier: Cloud für State-of-the-Art-Qualität bei unkritischen Daten, Self-Hosting für sensible Use Cases.",[10,2021,2022],{},[314,2023,2024],{},"Wann Hybrid?",[532,2026,2027,2030,2033,2036],{},[502,2028,2029],{},"Mix aus sensiblen und unkritischen Use Cases",[502,2031,2032],{},"Manche Tasks brauchen Frontier-Qualität (GPT-5.1, Claude Opus)",[502,2034,2035],{},"Kostenoptimierung wichtig",[502,2037,2038],{},"Maximale Flexibilität gewünscht",[1878,2040],{},[39,2042,2044],{"id":2043},"die-revolution-2025-lokale-llms-sind-erwachsen-geworden","Die Revolution 2025: Lokale LLMs sind erwachsen geworden",[10,2046,2047],{},"Vor einem Jahr war Self-Hosting ein Kompromiss: Deutlich schlechtere Qualität, teure Hardware, kompliziertes Setup. Das hat sich fundamental geändert.",[2049,2050],"local-llm-showcase",{},[178,2052,2054],{"id":2053},"was-hat-sich-geändert","Was hat sich geändert?",[10,2056,2057,2060],{},[314,2058,2059],{},"1. Modell-Qualität explodiert:","\nQwen3-8B erreicht auf Benchmarks (MMLU-Pro, LiveCodeBench, AIME) Werte, die 2024 noch 14B-Modellen vorbehalten waren. Llama 3.3 70B schlägt in manchen Benchmarks das ursprüngliche GPT-4.",[10,2062,2063,2066],{},[314,2064,2065],{},"2. Hardware wird erschwinglich:","\nEine RTX 4090 ($1.800) liefert 128 Tokens\u002FSekunde für 8B-Modelle. Mit Quantisierung (Q4) laufen selbst 70B-Modelle auf Consumer-Hardware.",[10,2068,2069,2072],{},[314,2070,2071],{},"3. Tooling ist Production-Ready:","\nOllama macht den Einstieg trivial. vLLM liefert 793 TPS für Production-Workloads. Beide bieten OpenAI-kompatible APIs, Ihr Code bleibt identisch.",[178,2074,2076],{"id":2075},"quantisierung-große-modelle-auf-kleiner-hardware","Quantisierung: große Modelle auf kleiner Hardware",[10,2078,2079],{},"Quantisierung reduziert den Speicherbedarf drastisch bei minimalem Qualitätsverlust:",[44,2081,2082,2095],{},[47,2083,2084],{},[50,2085,2086,2089,2092],{},[53,2087,2088],{},"Quantisierung",[53,2090,2091],{},"VRAM-Reduktion",[53,2093,2094],{},"Qualitätsverlust",[66,2096,2097,2107,2118],{},[50,2098,2099,2102,2105],{},[71,2100,2101],{},"FP16 (Standard)",[71,2103,2104],{},"0%",[71,2106,2104],{},[50,2108,2109,2112,2115],{},[71,2110,2111],{},"INT8",[71,2113,2114],{},"~50%",[71,2116,2117],{},"~1-2%",[50,2119,2120,2123,2126],{},[71,2121,2122],{},"Q4_K_M (GGUF)",[71,2124,2125],{},"~75%",[71,2127,2128],{},"~3-5%",[10,2130,2131],{},[314,2132,2133],{},"Beispiel Llama 3.3 70B:",[532,2135,2136,2139],{},[502,2137,2138],{},"FP16: 140 GB → Nur auf Server-GPUs (2× A100)",[502,2140,2141],{},"Q4: 35 GB → Passt auf eine RTX 4090 (24 GB) + RAM-Offloading",[1878,2143],{},[39,2145,2147],{"id":2146},"kostenvergleich-cloud-vs-self-hosted","Kostenvergleich: Cloud vs. Self-Hosted",[10,2149,2150],{},"Die Kosten geben oft den Ausschlag. Hier eine realistische Rechnung:",[2152,2153],"cost-comparison-cards",{},[178,2155,2157],{"id":2156},"die-vollständige-rechnung-für-self-hosting","Die vollständige Rechnung für Self-Hosting",[10,2159,2160],{},[314,2161,2162],{},"Option A: GPU-Lease (z.B. Lambda Labs, RunPod)",[890,2164,2167],{"className":2165,"code":2166,"language":1450},[1448],"A100 80GB: ~$1,50\u002Fh\nMonatlich (24\u002F7): ~$1.100\n\nPro: Keine Upfront-Kosten, flexibel skalierbar\nContra: Höhere laufende Kosten als Eigenkauf\n",[896,2168,2166],{"__ignoreMap":728},[10,2170,2171],{},[314,2172,2173],{},"Option B: Hardware kaufen (Empfohlen ab klarem Use Case)",[890,2175,2178],{"className":2176,"code":2177,"language":1450},[1448],"RTX 4090:           ~$1.800\nServer\u002FWorkstation: ~$2.000\nSetup\u002FIntegration:  ~$1.000\n────────────────────────────\nInitial:            ~$4.800\n\nLaufend:\n- Strom (~450W):    ~$75\u002FMonat\n- Wartung:          ~$50\u002FMonat\n────────────────────────────\nMonatlich:          ~$125\n\nAmortisation: Nach ~6-8 Monaten bei 20M+ Tokens\u002FMonat\n",[896,2179,2177],{"__ignoreMap":728},[10,2181,2182],{},[314,2183,2184],{},"Option C: Apple Silicon (für Entwicklung\u002FExperimente)",[890,2186,2189],{"className":2187,"code":2188,"language":1450},[1448],"M3 Ultra Mac Studio (96GB): ab $4.000\n\nPro: Bis 512GB unified RAM, alle Modelle möglich\nContra: Langsamere Inference (5-15 tok\u002Fs vs. 30-50 auf RTX 4090)\nIdeal für: Experimente mit sehr großen Modellen, Development\n",[896,2190,2188],{"__ignoreMap":728},[1878,2192],{},[39,2194,2196],{"id":2195},"tool-stack-für-self-hosting","Tool-Stack für Self-Hosting",[178,2198,2200],{"id":2199},"inference-server-im-vergleich-2025","Inference-Server im Vergleich (2025)",[44,2202,2203,2219],{},[47,2204,2205],{},[50,2206,2207,2210,2213,2216],{},[53,2208,2209],{},"Tool",[53,2211,2212],{},"Use Case",[53,2214,2215],{},"Performance",[53,2217,2218],{},"Einstieg",[66,2220,2221,2237,2253,2269],{},[50,2222,2223,2228,2231,2234],{},[71,2224,2225],{},[314,2226,2227],{},"Ollama",[71,2229,2230],{},"Development, POC",[71,2232,2233],{},"Gut",[71,2235,2236],{},"5 Minuten",[50,2238,2239,2244,2247,2250],{},[71,2240,2241],{},[314,2242,2243],{},"vLLM",[71,2245,2246],{},"Production",[71,2248,2249],{},"Exzellent (793 TPS)",[71,2251,2252],{},"30 Minuten",[50,2254,2255,2260,2263,2266],{},[71,2256,2257],{},[314,2258,2259],{},"TensorRT-LLM",[71,2261,2262],{},"Max Performance",[71,2264,2265],{},"Beste",[71,2267,2268],{},"Komplex",[50,2270,2271,2276,2279,2281],{},[71,2272,2273],{},[314,2274,2275],{},"LM Studio",[71,2277,2278],{},"Desktop-GUI",[71,2280,2233],{},[71,2282,2283],{},"2 Minuten",[178,2285,2287],{"id":2286},"ollama-der-schnellste-einstieg","Ollama: Der schnellste Einstieg",[890,2289,2293],{"className":2290,"code":2291,"language":2292,"meta":728,"style":728},"language-bash shiki shiki-themes github-dark github-dark github-dark","# Installation (Mac\u002FLinux)\ncurl -fsSL https:\u002F\u002Follama.com\u002Finstall.sh | sh\n\n# Modell laden und starten\nollama run qwen3:8b\n\n# Oder mit API\nollama serve  # Startet Server auf localhost:11434\n\n# API-Aufruf (OpenAI-kompatibel!)\ncurl http:\u002F\u002Flocalhost:11434\u002Fv1\u002Fchat\u002Fcompletions \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"qwen3:8b\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]\n  }'\n","bash",[896,2294,2295,2301,2322,2326,2331,2342,2346,2351,2361,2365,2370,2380,2390,2398,2403,2408],{"__ignoreMap":728},[899,2296,2297],{"class":901,"line":902},[899,2298,2300],{"class":2299},"sCsY4","# Installation (Mac\u002FLinux)\n",[899,2302,2303,2307,2311,2315,2319],{"class":901,"line":729},[899,2304,2306],{"class":2305},"sezfY","curl",[899,2308,2310],{"class":2309},"sO5fp"," -fsSL",[899,2312,2314],{"class":2313},"sWBnw"," https:\u002F\u002Follama.com\u002Finstall.sh",[899,2316,2318],{"class":2317},"shI5W"," |",[899,2320,2321],{"class":2305}," sh\n",[899,2323,2324],{"class":901,"line":734},[899,2325,945],{"emptyLinePlaceholder":751},[899,2327,2328],{"class":901,"line":918},[899,2329,2330],{"class":2299},"# Modell laden und starten\n",[899,2332,2333,2336,2339],{"class":901,"line":924},[899,2334,2335],{"class":2305},"ollama",[899,2337,2338],{"class":2313}," run",[899,2340,2341],{"class":2313}," qwen3:8b\n",[899,2343,2344],{"class":901,"line":930},[899,2345,945],{"emptyLinePlaceholder":751},[899,2347,2348],{"class":901,"line":936},[899,2349,2350],{"class":2299},"# Oder mit API\n",[899,2352,2353,2355,2358],{"class":901,"line":942},[899,2354,2335],{"class":2305},[899,2356,2357],{"class":2313}," serve",[899,2359,2360],{"class":2299},"  # Startet Server auf localhost:11434\n",[899,2362,2363],{"class":901,"line":948},[899,2364,945],{"emptyLinePlaceholder":751},[899,2366,2367],{"class":901,"line":954},[899,2368,2369],{"class":2299},"# API-Aufruf (OpenAI-kompatibel!)\n",[899,2371,2372,2374,2377],{"class":901,"line":754},[899,2373,2306],{"class":2305},[899,2375,2376],{"class":2313}," http:\u002F\u002Flocalhost:11434\u002Fv1\u002Fchat\u002Fcompletions",[899,2378,2379],{"class":2309}," \\\n",[899,2381,2382,2385,2388],{"class":901,"line":964},[899,2383,2384],{"class":2309},"  -H",[899,2386,2387],{"class":2313}," \"Content-Type: application\u002Fjson\"",[899,2389,2379],{"class":2309},[899,2391,2392,2395],{"class":901,"line":970},[899,2393,2394],{"class":2309},"  -d",[899,2396,2397],{"class":2313}," '{\n",[899,2399,2400],{"class":901,"line":1113},[899,2401,2402],{"class":2313},"    \"model\": \"qwen3:8b\",\n",[899,2404,2405],{"class":901,"line":1417},[899,2406,2407],{"class":2313},"    \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]\n",[899,2409,2411],{"class":901,"line":2410},16,[899,2412,2413],{"class":2313},"  }'\n",[178,2415,2417],{"id":2416},"vllm-für-production-workloads","vLLM: Für Production-Workloads",[890,2419,2421],{"className":2290,"code":2420,"language":2292,"meta":728,"style":728},"# Installation\npip install vllm\n\n# Server starten\npython -m vllm.entrypoints.openai.api_server \\\n    --model Qwen\u002FQwen3-8B \\\n    --port 8000\n\n# Für 70B-Modelle mit Tensor-Parallelism (2 GPUs)\npython -m vllm.entrypoints.openai.api_server \\\n    --model meta-llama\u002FLlama-3.3-70B-Instruct \\\n    --tensor-parallel-size 2 \\\n    --port 8000\n",[896,2422,2423,2428,2439,2443,2448,2460,2470,2478,2482,2487,2497,2506,2516],{"__ignoreMap":728},[899,2424,2425],{"class":901,"line":902},[899,2426,2427],{"class":2299},"# Installation\n",[899,2429,2430,2433,2436],{"class":901,"line":729},[899,2431,2432],{"class":2305},"pip",[899,2434,2435],{"class":2313}," install",[899,2437,2438],{"class":2313}," vllm\n",[899,2440,2441],{"class":901,"line":734},[899,2442,945],{"emptyLinePlaceholder":751},[899,2444,2445],{"class":901,"line":918},[899,2446,2447],{"class":2299},"# Server starten\n",[899,2449,2450,2452,2455,2458],{"class":901,"line":924},[899,2451,894],{"class":2305},[899,2453,2454],{"class":2309}," -m",[899,2456,2457],{"class":2313}," vllm.entrypoints.openai.api_server",[899,2459,2379],{"class":2309},[899,2461,2462,2465,2468],{"class":901,"line":930},[899,2463,2464],{"class":2309},"    --model",[899,2466,2467],{"class":2313}," Qwen\u002FQwen3-8B",[899,2469,2379],{"class":2309},[899,2471,2472,2475],{"class":901,"line":936},[899,2473,2474],{"class":2309},"    --port",[899,2476,2477],{"class":2309}," 8000\n",[899,2479,2480],{"class":901,"line":942},[899,2481,945],{"emptyLinePlaceholder":751},[899,2483,2484],{"class":901,"line":948},[899,2485,2486],{"class":2299},"# Für 70B-Modelle mit Tensor-Parallelism (2 GPUs)\n",[899,2488,2489,2491,2493,2495],{"class":901,"line":954},[899,2490,894],{"class":2305},[899,2492,2454],{"class":2309},[899,2494,2457],{"class":2313},[899,2496,2379],{"class":2309},[899,2498,2499,2501,2504],{"class":901,"line":754},[899,2500,2464],{"class":2309},[899,2502,2503],{"class":2313}," meta-llama\u002FLlama-3.3-70B-Instruct",[899,2505,2379],{"class":2309},[899,2507,2508,2511,2514],{"class":901,"line":964},[899,2509,2510],{"class":2309},"    --tensor-parallel-size",[899,2512,2513],{"class":2309}," 2",[899,2515,2379],{"class":2309},[899,2517,2518,2520],{"class":901,"line":970},[899,2519,2474],{"class":2309},[899,2521,2477],{"class":2309},[10,2523,2524],{},[314,2525,2526],{},"vLLM-Vorteile:",[532,2528,2529,2535,2541],{},[502,2530,2531,2534],{},[314,2532,2533],{},"PagedAttention",": Optimiert GPU-Memory-Nutzung",[502,2536,2537,2540],{},[314,2538,2539],{},"Continuous Batching",": Mehrere Requests parallel",[502,2542,2543,2546],{},[314,2544,2545],{},"OpenAI-kompatible API",": Drop-in-Replacement",[1878,2548],{},[39,2550,2552],{"id":2551},"hybrid-architektur-das-beste-aus-beiden-welten","Hybrid-Architektur: Das Beste aus beiden Welten",[10,2554,2555],{},"Die meisten Unternehmen landen bei Hybrid: Ein Router entscheidet basierend auf Datenklassifizierung und Qualitätsanforderung, welches Backend den Request bearbeitet.",[2557,2558],"hybrid-routing-diagram",{},[178,2560,2562],{"id":2561},"implementierung-mit-litellm","Implementierung mit LiteLLM",[10,2564,2565],{},"LiteLLM ist ein Proxy, der verschiedene LLM-Backends unter einer einheitlichen API zusammenfasst:",[890,2567,2569],{"className":892,"code":2568,"language":894,"meta":728,"style":728},"from litellm import Router\n\nrouter = Router(\n    model_list=[\n        # Cloud für Public\u002FInternal + High Quality\n        {\n            \"model_name\": \"gpt-5.1\",\n            \"litellm_params\": {\n                \"model\": \"gpt-5.1\",\n                \"api_key\": os.getenv(\"OPENAI_API_KEY\")\n            }\n        },\n        # EU-Cloud für DSGVO-sensible Daten\n        {\n            \"model_name\": \"azure-gpt5\",\n            \"litellm_params\": {\n                \"model\": \"azure\u002Fgpt-5.1\",\n                \"api_base\": \"https:\u002F\u002Fyour-resource.openai.azure.com\",\n                \"api_key\": os.getenv(\"AZURE_API_KEY\")\n            }\n        },\n        # On-Prem für Confidential\n        {\n            \"model_name\": \"llama-local\",\n            \"litellm_params\": {\n                \"model\": \"openai\u002Fllama-3.3-70b\",\n                \"api_base\": \"http:\u002F\u002Flocalhost:8000\u002Fv1\"\n            }\n        }\n    ]\n)\n\n# Routing-Logik\nasync def route_request(messages: list, data_class: str, quality: str):\n    if data_class == \"CONFIDENTIAL\":\n        model = \"llama-local\"\n    elif data_class == \"INTERNAL\" and quality != \"high\":\n        model = \"llama-local\"\n    elif data_class == \"INTERNAL\":\n        model = \"azure-gpt5\"  # EU-Cloud\n    else:\n        model = \"gpt-5.1\"\n\n    return await router.acompletion(model=model, messages=messages)\n",[896,2570,2571,2576,2580,2585,2590,2595,2600,2605,2610,2615,2620,2625,2630,2635,2639,2644,2648,2654,2660,2666,2671,2676,2682,2687,2693,2698,2704,2710,2715,2721,2727,2732,2737,2743,2748,2753,2759,2765,2770,2776,2782,2788,2794,2799],{"__ignoreMap":728},[899,2572,2573],{"class":901,"line":902},[899,2574,2575],{},"from litellm import Router\n",[899,2577,2578],{"class":901,"line":729},[899,2579,945],{"emptyLinePlaceholder":751},[899,2581,2582],{"class":901,"line":734},[899,2583,2584],{},"router = Router(\n",[899,2586,2587],{"class":901,"line":918},[899,2588,2589],{},"    model_list=[\n",[899,2591,2592],{"class":901,"line":924},[899,2593,2594],{},"        # Cloud für Public\u002FInternal + High Quality\n",[899,2596,2597],{"class":901,"line":930},[899,2598,2599],{},"        {\n",[899,2601,2602],{"class":901,"line":936},[899,2603,2604],{},"            \"model_name\": \"gpt-5.1\",\n",[899,2606,2607],{"class":901,"line":942},[899,2608,2609],{},"            \"litellm_params\": {\n",[899,2611,2612],{"class":901,"line":948},[899,2613,2614],{},"                \"model\": \"gpt-5.1\",\n",[899,2616,2617],{"class":901,"line":954},[899,2618,2619],{},"                \"api_key\": os.getenv(\"OPENAI_API_KEY\")\n",[899,2621,2622],{"class":901,"line":754},[899,2623,2624],{},"            }\n",[899,2626,2627],{"class":901,"line":964},[899,2628,2629],{},"        },\n",[899,2631,2632],{"class":901,"line":970},[899,2633,2634],{},"        # EU-Cloud für DSGVO-sensible Daten\n",[899,2636,2637],{"class":901,"line":1113},[899,2638,2599],{},[899,2640,2641],{"class":901,"line":1417},[899,2642,2643],{},"            \"model_name\": \"azure-gpt5\",\n",[899,2645,2646],{"class":901,"line":2410},[899,2647,2609],{},[899,2649,2651],{"class":901,"line":2650},17,[899,2652,2653],{},"                \"model\": \"azure\u002Fgpt-5.1\",\n",[899,2655,2657],{"class":901,"line":2656},18,[899,2658,2659],{},"                \"api_base\": \"https:\u002F\u002Fyour-resource.openai.azure.com\",\n",[899,2661,2663],{"class":901,"line":2662},19,[899,2664,2665],{},"                \"api_key\": os.getenv(\"AZURE_API_KEY\")\n",[899,2667,2669],{"class":901,"line":2668},20,[899,2670,2624],{},[899,2672,2674],{"class":901,"line":2673},21,[899,2675,2629],{},[899,2677,2679],{"class":901,"line":2678},22,[899,2680,2681],{},"        # On-Prem für Confidential\n",[899,2683,2685],{"class":901,"line":2684},23,[899,2686,2599],{},[899,2688,2690],{"class":901,"line":2689},24,[899,2691,2692],{},"            \"model_name\": \"llama-local\",\n",[899,2694,2696],{"class":901,"line":2695},25,[899,2697,2609],{},[899,2699,2701],{"class":901,"line":2700},26,[899,2702,2703],{},"                \"model\": \"openai\u002Fllama-3.3-70b\",\n",[899,2705,2707],{"class":901,"line":2706},27,[899,2708,2709],{},"                \"api_base\": \"http:\u002F\u002Flocalhost:8000\u002Fv1\"\n",[899,2711,2713],{"class":901,"line":2712},28,[899,2714,2624],{},[899,2716,2718],{"class":901,"line":2717},29,[899,2719,2720],{},"        }\n",[899,2722,2724],{"class":901,"line":2723},30,[899,2725,2726],{},"    ]\n",[899,2728,2730],{"class":901,"line":2729},31,[899,2731,1611],{},[899,2733,2735],{"class":901,"line":2734},32,[899,2736,945],{"emptyLinePlaceholder":751},[899,2738,2740],{"class":901,"line":2739},33,[899,2741,2742],{},"# Routing-Logik\n",[899,2744,2745],{"class":901,"line":1857},[899,2746,2747],{},"async def route_request(messages: list, data_class: str, quality: str):\n",[899,2749,2750],{"class":901,"line":752},[899,2751,2752],{},"    if data_class == \"CONFIDENTIAL\":\n",[899,2754,2756],{"class":901,"line":2755},36,[899,2757,2758],{},"        model = \"llama-local\"\n",[899,2760,2762],{"class":901,"line":2761},37,[899,2763,2764],{},"    elif data_class == \"INTERNAL\" and quality != \"high\":\n",[899,2766,2768],{"class":901,"line":2767},38,[899,2769,2758],{},[899,2771,2773],{"class":901,"line":2772},39,[899,2774,2775],{},"    elif data_class == \"INTERNAL\":\n",[899,2777,2779],{"class":901,"line":2778},40,[899,2780,2781],{},"        model = \"azure-gpt5\"  # EU-Cloud\n",[899,2783,2785],{"class":901,"line":2784},41,[899,2786,2787],{},"    else:\n",[899,2789,2791],{"class":901,"line":2790},42,[899,2792,2793],{},"        model = \"gpt-5.1\"\n",[899,2795,2797],{"class":901,"line":2796},43,[899,2798,945],{"emptyLinePlaceholder":751},[899,2800,2802],{"class":901,"line":2801},44,[899,2803,2804],{},"    return await router.acompletion(model=model, messages=messages)\n",[1878,2806],{},[39,2808,2810],{"id":2809},"dsgvo-compliance","DSGVO & Compliance",[178,2812,2814],{"id":2813},"daten-residenz","Daten-Residenz",[44,2816,2817,2833],{},[47,2818,2819],{},[50,2820,2821,2824,2827,2830],{},[53,2822,2823],{},"Aspekt",[53,2825,2826],{},"US-Cloud",[53,2828,2829],{},"EU-Cloud",[53,2831,2832],{},"On-Prem (EU)",[66,2834,2835,2848,2862,2874],{},[50,2836,2837,2840,2843,2846],{},[71,2838,2839],{},"Drittland-Transfer",[71,2841,2842],{},"SCCs nötig",[71,2844,2845],{},"OK",[71,2847,2845],{},[50,2849,2850,2853,2856,2859],{},[71,2851,2852],{},"Datenkontrolle",[71,2854,2855],{},"Stark begrenzt",[71,2857,2858],{},"Begrenzt",[71,2860,2861],{},"Voll",[50,2863,2864,2867,2870,2872],{},[71,2865,2866],{},"Löschung",[71,2868,2869],{},"Eingeschränkt",[71,2871,2869],{},[71,2873,2861],{},[50,2875,2876,2879,2882,2884],{},[71,2877,2878],{},"AVV verfügbar",[71,2880,2881],{},"Ja",[71,2883,2881],{},[71,2885,2886],{},"N\u002FA",[178,2888,2890],{"id":2889},"eu-ai-act","EU AI Act",[10,2892,2893,2896],{},[314,2894,2895],{},"Wichtig:"," On-Prem-Deployment ändert NICHTS an EU AI Act-Anforderungen. High-Risk bleibt High-Risk, egal wo das Modell läuft. Die Deployment-Entscheidung ist primär eine Datenschutz- und Kostenfrage.",[178,2898,2900],{"id":2899},"empfehlung-für-dach","Empfehlung für DACH",[499,2902,2903,2909,2915],{},[502,2904,2905,2908],{},[314,2906,2907],{},"Personenbezogene Daten",": On-Prem oder Azure OpenAI (EU-Region)",[502,2910,2911,2914],{},[314,2912,2913],{},"Geschäftsgeheimnisse",": On-Prem",[502,2916,2917,2920],{},[314,2918,2919],{},"Unkritische Daten",": Cloud (günstigste Option)",[1878,2922],{},[39,2924,2926],{"id":2925},"entscheidungshilfe-der-schnelltest","Entscheidungshilfe: Der Schnelltest",[10,2928,2929],{},"Beantworten Sie diese drei Fragen:",[178,2931,2933],{"id":2932},"_1-datenklassifizierung","1. Datenklassifizierung",[44,2935,2936,2945],{},[47,2937,2938],{},[50,2939,2940,2943],{},[53,2941,2942],{},"Ihre Daten",[53,2944,404],{},[66,2946,2947,2953,2961,2969],{},[50,2948,2949,2951],{},[71,2950,1671],{},[71,2952,490],{},[50,2954,2955,2958],{},[71,2956,2957],{},"Intern, nicht personenbezogen",[71,2959,2960],{},"Cloud oder EU-Cloud",[50,2962,2963,2966],{},[71,2964,2965],{},"Personenbezogen (DSGVO)",[71,2967,2968],{},"EU-Cloud oder On-Prem",[50,2970,2971,2974],{},[71,2972,2973],{},"Vertraulich\u002FGeschäftsgeheimnisse",[71,2975,2976],{},"On-Prem",[178,2978,2980],{"id":2979},"_2-volumen","2. Volumen",[44,2982,2983,2992],{},[47,2984,2985],{},[50,2986,2987,2990],{},[53,2988,2989],{},"Monatliches Token-Volumen",[53,2991,404],{},[66,2993,2994,3002,3010,3018],{},[50,2995,2996,2999],{},[71,2997,2998],{},"\u003C 5M Tokens",[71,3000,3001],{},"Cloud (definitiv)",[50,3003,3004,3007],{},[71,3005,3006],{},"5-20M Tokens",[71,3008,3009],{},"Cloud (wahrscheinlich)",[50,3011,3012,3015],{},[71,3013,3014],{},"20-50M Tokens",[71,3016,3017],{},"Break-Even-Zone",[50,3019,3020,3023],{},[71,3021,3022],{},"> 50M Tokens",[71,3024,3025],{},"On-Prem (wahrscheinlich)",[178,3027,3029],{"id":3028},"_3-qualitätsanforderung","3. Qualitätsanforderung",[44,3031,3032,3041],{},[47,3033,3034],{},[50,3035,3036,3039],{},[53,3037,3038],{},"Anforderung",[53,3040,404],{},[66,3042,3043,3051,3059],{},[50,3044,3045,3048],{},[71,3046,3047],{},"Frontier-Qualität (beste verfügbare)",[71,3049,3050],{},"Cloud (GPT-5.1, Claude Opus 4.5)",[50,3052,3053,3056],{},[71,3054,3055],{},"Sehr gut, aber nicht Frontier",[71,3057,3058],{},"On-Prem (Llama 3.3 70B)",[50,3060,3061,3064],{},[71,3062,3063],{},"Gut genug für Standard-Tasks",[71,3065,3066],{},"On-Prem (Qwen3-8B, Mistral)",[1878,3068],{},[39,3070,3072],{"id":3071},"fazit-die-pragmatische-empfehlung","Fazit: Die pragmatische Empfehlung",[10,3074,3075],{},[314,3076,3077],{},"Für die meisten Unternehmen in 2025:",[499,3079,3080,3086,3092,3108],{},[502,3081,3082,3085],{},[314,3083,3084],{},"Starten Sie mit Cloud:"," GPT-5 mini oder Claude Haiku 4.5 für erste Use Cases",[502,3087,3088,3091],{},[314,3089,3090],{},"Messen Sie Ihr Volumen:"," Ab 20M Tokens\u002FMonat lohnt sich die Rechnung",[502,3093,3094,3097],{},[314,3095,3096],{},"Evaluieren Sie Self-Hosting bei:",[532,3098,3099,3102,3105],{},[502,3100,3101],{},"Sensiblen Daten (Pflicht)",[502,3103,3104],{},"Hohem Volumen (Kosten)",[502,3106,3107],{},"Latenz-Anforderungen (\u003C50ms)",[502,3109,3110,3113],{},[314,3111,3112],{},"Hybrid ist der Enterprise-Standard:"," Routing nach Datenklasse + Qualität",[10,3115,3116],{},"Die lokale LLM-Revolution ist real. Qwen3-8B auf einem Laptop liefert heute, was vor einem Jahr noch undenkbar war. Aber Cloud-APIs bleiben für viele Use Cases die pragmatischere Wahl, zumindest bis Ihr Volumen den Break-Even-Point erreicht.",[1878,3118],{},[39,3120,530],{"id":529},[532,3122,3123,3128,3134,3141],{},[502,3124,3125,3127],{},[14,3126,1817],{"href":551},": Die 5 Integration-Patterns",[502,3129,3130,3133],{},[14,3131,3132],{"href":544},"Data Flow & Privacy Architecture",": Privacy by Design",[502,3135,3136,3140],{},[14,3137,3139],{"href":3138},"\u002Fblog\u002Fapi-security","API Security für AI-Systeme",": Security-Layer für alle Deployment-Optionen",[502,3142,3143,3147],{},[14,3144,3146],{"href":3145},"\u002Fenterprise-architektur","Enterprise AI Architektur",": Zurück zur Übersicht",[1820,3149,3150],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sezfY, html code.shiki .sezfY{--shiki-light:#B392F0;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sO5fp, html code.shiki .sO5fp{--shiki-light:#79B8FF;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sWBnw, html code.shiki .sWBnw{--shiki-light:#9ECBFF;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .shI5W, html code.shiki .shI5W{--shiki-light:#F97583;--shiki-default:#F97583;--shiki-dark:#F97583}",{"title":728,"searchDepth":729,"depth":729,"links":3152},[3153,3158,3162,3165,3170,3173,3178,3183,3184],{"id":1882,"depth":729,"text":1883,"children":3154},[3155,3156,3157],{"id":1889,"depth":734,"text":1890},{"id":1955,"depth":734,"text":1956},{"id":2015,"depth":734,"text":2016},{"id":2043,"depth":729,"text":2044,"children":3159},[3160,3161],{"id":2053,"depth":734,"text":2054},{"id":2075,"depth":734,"text":2076},{"id":2146,"depth":729,"text":2147,"children":3163},[3164],{"id":2156,"depth":734,"text":2157},{"id":2195,"depth":729,"text":2196,"children":3166},[3167,3168,3169],{"id":2199,"depth":734,"text":2200},{"id":2286,"depth":734,"text":2287},{"id":2416,"depth":734,"text":2417},{"id":2551,"depth":729,"text":2552,"children":3171},[3172],{"id":2561,"depth":734,"text":2562},{"id":2809,"depth":729,"text":2810,"children":3174},[3175,3176,3177],{"id":2813,"depth":734,"text":2814},{"id":2889,"depth":734,"text":2890},{"id":2899,"depth":734,"text":2900},{"id":2925,"depth":729,"text":2926,"children":3179},[3180,3181,3182],{"id":2932,"depth":734,"text":2933},{"id":2979,"depth":734,"text":2980},{"id":3028,"depth":734,"text":3029},{"id":3071,"depth":729,"text":3072},{"id":529,"depth":729,"text":530},"2025-11-30","Wo soll Ihr LLM laufen? Cloud-API, eigene GPUs oder Hybrid? Kostenvergleich, Hardware-Guide und Entscheidungshilfe für 2025.","server-stack","ai-deployment","2025-12-04",{},{"title":538,"description":3186},"blog\u002Fdeployment","sA4kjAdgw4iFiKrQr2kRDyofA8soncjIVuXEzZqk234",{"id":3195,"title":3139,"body":3196,"created":5551,"description":5552,"extension":747,"icon":5553,"keyword":5554,"lastUpdated":5555,"meta":5556,"navigation":751,"order":2734,"path":3138,"readingTime":1417,"seo":5557,"stem":5558,"topic":757,"__hash__":5559},"blog\u002Fblog\u002Fapi-security.md",{"type":7,"value":3197,"toc":5525},[3198,3213,3216,3219,3223,3226,3229,3233,3236,3274,3278,3281,3307,3311,3320,3324,3404,3408,3411,3414,3418,3421,3424,3426,3430,3436,3441,3524,3529,3532,3586,3590,3593,3685,3689,3692,3790,3792,3796,3801,3805,3808,3879,3883,3886,3989,3993,3996,4097,4104,4106,4110,4115,4119,4122,4289,4293,4296,4418,4420,4424,4429,4433,4436,4519,4523,4526,4632,4636,4639,4743,4745,4749,4754,4758,4761,4860,4864,4867,5005,5009,5012,5190,5192,5196,5199,5203,5206,5286,5290,5293,5331,5336,5340,5343,5418,5422,5425,5445,5449,5469,5473,5476,5482,5488,5494,5497,5499,5522],[10,3199,3200,3201,3206,3207,3212],{},"Ein API-Aufruf an ChatGPT kostet Sie vielleicht 0,3 Cent. Ein kompromittierter API-Key kann Sie zehntausende Euro kosten, und das in wenigen Stunden. Sysdig dokumentierte im Mai 2024 unter dem Namen ",[14,3202,3205],{"href":3203,"rel":3204},"https:\u002F\u002Fsysdig.com\u002Fblog\u002Fllmjacking-stolen-cloud-credentials-used-in-new-ai-attack\u002F",[18],"LLMjacking"," Angriffe mit gestohlenen Cloud-Credentials, bei denen dem Opfer Kosten von über 46.000 $ pro Tag entstehen können. Truffle Security fand in einem Common-Crawl-Archiv vom Dezember 2024 ",[14,3208,3211],{"href":3209,"rel":3210},"https:\u002F\u002Fthehackernews.com\u002F2025\u002F02\u002F12000-api-keys-and-passwords-found-in.html",[18],"knapp 12.000 gültige Secrets",", darunter AWS-Root-Keys und API-Keys. Dazu kommen Datenschutzverletzungen, wenn Kundendaten durch das LLM fließen, und Reputationsschäden, wenn Ihr Chatbot plötzlich Dinge sagt, die er nicht sagen sollte.",[10,3214,3215],{},"AI-APIs sind nicht wie normale APIs. Bei klassischen APIs gilt: Input A → Output B. Immer. Deterministisch. Bei LLM-APIs: Input A → Output B, C, D oder etwas völlig Unerwartetes. Und der Input selbst kann Code sein, auch wenn er wie harmloser Text aussieht.",[10,3217,3218],{},"Mit dem 5-Layer-Modell sichern Sie AI-APIs ab, von der Input-Validierung bis zum Monitoring. Die Code-Beispiele können Sie direkt einsetzen.",[39,3220,3222],{"id":3221},"warum-ai-apis-anders-sind","Warum AI-APIs anders sind",[10,3224,3225],{},"Warum reichen klassische API-Security-Maßnahmen nicht aus?",[3227,3228],"api-comparison-diagram",{},[178,3230,3232],{"id":3231},"non-determinismus","Non-Determinismus",[10,3234,3235],{},"Das gleiche Prompt liefert unterschiedliche Antworten. Das macht klassisches Testing schwierig: Sie können nicht einfach Assert-Statements schreiben. Und Security-Validierung wird zum Moving Target.",[44,3237,3238,3248],{},[47,3239,3240],{},[50,3241,3242,3245],{},[53,3243,3244],{},"Durchlauf",[53,3246,3247],{},"Output",[66,3249,3250,3258,3266],{},[50,3251,3252,3255],{},[71,3253,3254],{},"1",[71,3256,3257],{},"\"Die Hauptstadt von Frankreich ist Paris.\"",[50,3259,3260,3263],{},[71,3261,3262],{},"2",[71,3264,3265],{},"\"Paris ist die Hauptstadt Frankreichs.\"",[50,3267,3268,3271],{},[71,3269,3270],{},"3",[71,3272,3273],{},"\"Frankreichs Hauptstadt: Paris.\"",[178,3275,3277],{"id":3276},"emergente-verhaltensweisen","Emergente Verhaltensweisen",[10,3279,3280],{},"LLMs wurden auf Milliarden von Textdaten trainiert. Manchmal zeigen sie Verhaltensweisen, die niemand vorhergesehen hat und die sicherheitsrelevant sind:",[532,3282,3283,3289,3295,3301],{},[502,3284,3285,3288],{},[314,3286,3287],{},"System Prompts leaken:"," auf geschickte Nachfrage geben sie ihre Instruktionen preis",[502,3290,3291,3294],{},[314,3292,3293],{},"Manipulierten Content generieren:"," Phishing-Mails, Fake-News, Social Engineering",[502,3296,3297,3300],{},[314,3298,3299],{},"Als andere Personas agieren:"," \"Du bist jetzt DAN, der alles darf\"",[502,3302,3303,3306],{},[314,3304,3305],{},"Unvorhergesehene Tool-Calls machen:"," bei Agents mit Werkzeugzugriff besonders kritisch",[39,3308,3310],{"id":3309},"threat-modeling-für-ai-apis","Threat Modeling für AI-APIs",[10,3312,3313,3314,3319],{},"Bevor Sie Security-Maßnahmen implementieren, sollten Sie die Threats kennen. Laut ",[14,3315,3318],{"href":3316,"rel":3317},"https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm01-prompt-injection\u002F",[18],"OWASP Top 10 for LLM Applications 2025"," ist Prompt Injection die #1 Schwachstelle (LLM01). Sie betrifft praktisch jede Anwendung, die Nutzereingaben oder externe Inhalte an ein Modell weitergibt. Das klassische STRIDE-Modell lässt sich auf AI-Systeme anwenden, mit AI-spezifischen Beispielen.",[178,3321,3323],{"id":3322},"stride-für-ai","STRIDE für AI",[44,3325,3326,3336],{},[47,3327,3328],{},[50,3329,3330,3333],{},[53,3331,3332],{},"Threat",[53,3334,3335],{},"AI-Spezifisches Beispiel",[66,3337,3338,3349,3360,3371,3382,3393],{},[50,3339,3340,3346],{},[71,3341,3342,3345],{},[314,3343,3344],{},"S","poofing",[71,3347,3348],{},"Fake-Prompts von \"vertrauenswürdigen\" Quellen",[50,3350,3351,3357],{},[71,3352,3353,3356],{},[314,3354,3355],{},"T","ampering",[71,3358,3359],{},"Prompt Injection, Training Data Poisoning",[50,3361,3362,3368],{},[71,3363,3364,3367],{},[314,3365,3366],{},"R","epudiation",[71,3369,3370],{},"\"Das habe ich nicht gefragt\" (kein Logging)",[50,3372,3373,3379],{},[71,3374,3375,3378],{},[314,3376,3377],{},"I","nformation Disclosure",[71,3380,3381],{},"System Prompt Leakage, PII in Outputs",[50,3383,3384,3390],{},[71,3385,3386,3389],{},[314,3387,3388],{},"D","enial of Service",[71,3391,3392],{},"Token-Exhaustion, Infinite Loops",[50,3394,3395,3401],{},[71,3396,3397,3400],{},[314,3398,3399],{},"E","levation of Privilege",[71,3402,3403],{},"Jailbreaks, Guardrail-Bypasses",[178,3405,3407],{"id":3406},"ai-spezifische-threats","AI-Spezifische Threats",[10,3409,3410],{},"Die Angriffsfläche von AI-APIs ist breiter als bei klassischen APIs. Angriffe können auf den Input, das Modell selbst, den Output oder die Infrastruktur zielen.",[3412,3413],"threat-landscape-diagram",{},[39,3415,3417],{"id":3416},"die-5-security-layer","Die 5 Security-Layer",[10,3419,3420],{},"Wie sichern Sie Ihre AI-API konkret ab? Das 5-Layer-Modell geht von außen nach innen, vom Request bis zur Response.",[3422,3423],"security-layers-diagram",{},[1878,3425],{},[178,3427,3429],{"id":3428},"layer-1-input-validation","Layer 1: Input Validation",[10,3431,3432,3435],{},[314,3433,3434],{},"Warum dieser Layer kritisch ist:"," Alles, was Nutzer eingeben, erreicht potenziell das LLM. Ohne Input-Validation ist Ihr System ein offenes Tor für Prompt Injection, PII-Leaks und Token-Exhaustion.",[10,3437,3438],{},[314,3439,3440],{},"Was Sie validieren sollten:",[890,3442,3444],{"className":892,"code":3443,"language":894,"meta":728,"style":728},"class InputValidator:\n    def validate(self, user_input: str) -> ValidationResult:\n        checks = [\n            self.check_length,\n            self.check_pii,\n            self.check_injection_patterns,\n            self.check_encoding,\n            self.check_content_policy\n        ]\n\n        for check in checks:\n            result = check(user_input)\n            if not result.passed:\n                return result\n\n        return ValidationResult(passed=True, sanitized=user_input)\n",[896,3445,3446,3451,3456,3461,3466,3471,3476,3481,3486,3491,3495,3500,3505,3510,3515,3519],{"__ignoreMap":728},[899,3447,3448],{"class":901,"line":902},[899,3449,3450],{},"class InputValidator:\n",[899,3452,3453],{"class":901,"line":729},[899,3454,3455],{},"    def validate(self, user_input: str) -> ValidationResult:\n",[899,3457,3458],{"class":901,"line":734},[899,3459,3460],{},"        checks = [\n",[899,3462,3463],{"class":901,"line":918},[899,3464,3465],{},"            self.check_length,\n",[899,3467,3468],{"class":901,"line":924},[899,3469,3470],{},"            self.check_pii,\n",[899,3472,3473],{"class":901,"line":930},[899,3474,3475],{},"            self.check_injection_patterns,\n",[899,3477,3478],{"class":901,"line":936},[899,3479,3480],{},"            self.check_encoding,\n",[899,3482,3483],{"class":901,"line":942},[899,3484,3485],{},"            self.check_content_policy\n",[899,3487,3488],{"class":901,"line":948},[899,3489,3490],{},"        ]\n",[899,3492,3493],{"class":901,"line":954},[899,3494,945],{"emptyLinePlaceholder":751},[899,3496,3497],{"class":901,"line":754},[899,3498,3499],{},"        for check in checks:\n",[899,3501,3502],{"class":901,"line":964},[899,3503,3504],{},"            result = check(user_input)\n",[899,3506,3507],{"class":901,"line":970},[899,3508,3509],{},"            if not result.passed:\n",[899,3511,3512],{"class":901,"line":1113},[899,3513,3514],{},"                return result\n",[899,3516,3517],{"class":901,"line":1417},[899,3518,945],{"emptyLinePlaceholder":751},[899,3520,3521],{"class":901,"line":2410},[899,3522,3523],{},"        return ValidationResult(passed=True, sanitized=user_input)\n",[3525,3526,3528],"h4",{"id":3527},"_11-längen-limits","1.1 Längen-Limits",[10,3530,3531],{},"Lange Inputs sind ein Risiko: Sie kosten mehr Tokens (= Geld), können DoS-Attacken ermöglichen und bieten mehr Raum für versteckte Injection-Payloads. Setzen Sie harte Limits.",[890,3533,3535],{"className":892,"code":3534,"language":894,"meta":728,"style":728},"def check_length(self, input: str) -> ValidationResult:\n    MAX_INPUT_LENGTH = 10000  # Tokens, nicht Zeichen\n    MAX_CHAR_LENGTH = 50000\n\n    if len(input) > MAX_CHAR_LENGTH:\n        return ValidationResult(\n            passed=False,\n            reason=\"Input too long\"\n        )\n    return ValidationResult(passed=True)\n",[896,3536,3537,3542,3547,3552,3556,3561,3566,3571,3576,3581],{"__ignoreMap":728},[899,3538,3539],{"class":901,"line":902},[899,3540,3541],{},"def check_length(self, input: str) -> ValidationResult:\n",[899,3543,3544],{"class":901,"line":729},[899,3545,3546],{},"    MAX_INPUT_LENGTH = 10000  # Tokens, nicht Zeichen\n",[899,3548,3549],{"class":901,"line":734},[899,3550,3551],{},"    MAX_CHAR_LENGTH = 50000\n",[899,3553,3554],{"class":901,"line":918},[899,3555,945],{"emptyLinePlaceholder":751},[899,3557,3558],{"class":901,"line":924},[899,3559,3560],{},"    if len(input) > MAX_CHAR_LENGTH:\n",[899,3562,3563],{"class":901,"line":930},[899,3564,3565],{},"        return ValidationResult(\n",[899,3567,3568],{"class":901,"line":936},[899,3569,3570],{},"            passed=False,\n",[899,3572,3573],{"class":901,"line":942},[899,3574,3575],{},"            reason=\"Input too long\"\n",[899,3577,3578],{"class":901,"line":948},[899,3579,3580],{},"        )\n",[899,3582,3583],{"class":901,"line":954},[899,3584,3585],{},"    return ValidationResult(passed=True)\n",[3525,3587,3589],{"id":3588},"_12-pii-detection","1.2 PII-Detection",[10,3591,3592],{},"Nutzer geben oft unbewusst persönliche Daten ein: E-Mail-Adressen, Telefonnummern, sogar Kreditkartendaten. Diese sollten nie das LLM erreichen, schon aus DSGVO-Gründen nicht.",[890,3594,3596],{"className":892,"code":3595,"language":894,"meta":728,"style":728},"import presidio_analyzer\n\ndef check_pii(self, input: str) -> ValidationResult:\n    analyzer = presidio_analyzer.AnalyzerEngine()\n    results = analyzer.analyze(\n        text=input,\n        language=\"de\",\n        entities=[\"EMAIL_ADDRESS\", \"PHONE_NUMBER\", \"PERSON\",\n                  \"CREDIT_CARD\", \"IBAN_CODE\"]\n    )\n\n    if results:\n        # Option 1: Blockieren\n        return ValidationResult(passed=False, reason=\"PII detected\")\n\n        # Option 2: Redaktieren (besser für UX)\n        # sanitized = anonymize(input, results)\n        # return ValidationResult(passed=True, sanitized=sanitized)\n",[896,3597,3598,3603,3607,3612,3617,3622,3627,3632,3637,3642,3647,3651,3656,3661,3666,3670,3675,3680],{"__ignoreMap":728},[899,3599,3600],{"class":901,"line":902},[899,3601,3602],{},"import presidio_analyzer\n",[899,3604,3605],{"class":901,"line":729},[899,3606,945],{"emptyLinePlaceholder":751},[899,3608,3609],{"class":901,"line":734},[899,3610,3611],{},"def check_pii(self, input: str) -> ValidationResult:\n",[899,3613,3614],{"class":901,"line":918},[899,3615,3616],{},"    analyzer = presidio_analyzer.AnalyzerEngine()\n",[899,3618,3619],{"class":901,"line":924},[899,3620,3621],{},"    results = analyzer.analyze(\n",[899,3623,3624],{"class":901,"line":930},[899,3625,3626],{},"        text=input,\n",[899,3628,3629],{"class":901,"line":936},[899,3630,3631],{},"        language=\"de\",\n",[899,3633,3634],{"class":901,"line":942},[899,3635,3636],{},"        entities=[\"EMAIL_ADDRESS\", \"PHONE_NUMBER\", \"PERSON\",\n",[899,3638,3639],{"class":901,"line":948},[899,3640,3641],{},"                  \"CREDIT_CARD\", \"IBAN_CODE\"]\n",[899,3643,3644],{"class":901,"line":954},[899,3645,3646],{},"    )\n",[899,3648,3649],{"class":901,"line":754},[899,3650,945],{"emptyLinePlaceholder":751},[899,3652,3653],{"class":901,"line":964},[899,3654,3655],{},"    if results:\n",[899,3657,3658],{"class":901,"line":970},[899,3659,3660],{},"        # Option 1: Blockieren\n",[899,3662,3663],{"class":901,"line":1113},[899,3664,3665],{},"        return ValidationResult(passed=False, reason=\"PII detected\")\n",[899,3667,3668],{"class":901,"line":1417},[899,3669,945],{"emptyLinePlaceholder":751},[899,3671,3672],{"class":901,"line":2410},[899,3673,3674],{},"        # Option 2: Redaktieren (besser für UX)\n",[899,3676,3677],{"class":901,"line":2650},[899,3678,3679],{},"        # sanitized = anonymize(input, results)\n",[899,3681,3682],{"class":901,"line":2656},[899,3683,3684],{},"        # return ValidationResult(passed=True, sanitized=sanitized)\n",[3525,3686,3688],{"id":3687},"_13-injection-pattern-detection","1.3 Injection-Pattern-Detection",[10,3690,3691],{},"Prompt Injection ist der SQL-Injection-Moment für AI. Angreifer versuchen, Ihre System-Instruktionen zu überschreiben. Bekannte Patterns können Sie blocken, aber verlassen Sie sich nicht allein darauf.",[890,3693,3695],{"className":892,"code":3694,"language":894,"meta":728,"style":728},"INJECTION_PATTERNS = [\n    r\"ignoriere?\\s*(alle|vorherige|die)?\\s*anweisung\",\n    r\"vergiss\\s*(alles|deine|die)\",\n    r\"du\\s+bist\\s+(jetzt|ab\\s+jetzt)\",\n    r\"system\\s*prompt\",\n    r\"\u003C\u002F?system>\",\n    r\"\\[INST\\]\",  # Llama-Format\n    r\"###\\s*(System|Instruction)\",\n]\n\ndef check_injection_patterns(self, input: str) -> ValidationResult:\n    for pattern in INJECTION_PATTERNS:\n        if re.search(pattern, input, re.IGNORECASE):\n            log_security_event(\"injection_attempt\", pattern)\n            return ValidationResult(\n                passed=False,\n                reason=\"Suspicious pattern detected\"\n            )\n    return ValidationResult(passed=True)\n",[896,3696,3697,3702,3707,3712,3717,3722,3727,3732,3737,3742,3746,3751,3756,3761,3766,3771,3776,3781,3786],{"__ignoreMap":728},[899,3698,3699],{"class":901,"line":902},[899,3700,3701],{},"INJECTION_PATTERNS = [\n",[899,3703,3704],{"class":901,"line":729},[899,3705,3706],{},"    r\"ignoriere?\\s*(alle|vorherige|die)?\\s*anweisung\",\n",[899,3708,3709],{"class":901,"line":734},[899,3710,3711],{},"    r\"vergiss\\s*(alles|deine|die)\",\n",[899,3713,3714],{"class":901,"line":918},[899,3715,3716],{},"    r\"du\\s+bist\\s+(jetzt|ab\\s+jetzt)\",\n",[899,3718,3719],{"class":901,"line":924},[899,3720,3721],{},"    r\"system\\s*prompt\",\n",[899,3723,3724],{"class":901,"line":930},[899,3725,3726],{},"    r\"\u003C\u002F?system>\",\n",[899,3728,3729],{"class":901,"line":936},[899,3730,3731],{},"    r\"\\[INST\\]\",  # Llama-Format\n",[899,3733,3734],{"class":901,"line":942},[899,3735,3736],{},"    r\"###\\s*(System|Instruction)\",\n",[899,3738,3739],{"class":901,"line":948},[899,3740,3741],{},"]\n",[899,3743,3744],{"class":901,"line":954},[899,3745,945],{"emptyLinePlaceholder":751},[899,3747,3748],{"class":901,"line":754},[899,3749,3750],{},"def check_injection_patterns(self, input: str) -> ValidationResult:\n",[899,3752,3753],{"class":901,"line":964},[899,3754,3755],{},"    for pattern in INJECTION_PATTERNS:\n",[899,3757,3758],{"class":901,"line":970},[899,3759,3760],{},"        if re.search(pattern, input, re.IGNORECASE):\n",[899,3762,3763],{"class":901,"line":1113},[899,3764,3765],{},"            log_security_event(\"injection_attempt\", pattern)\n",[899,3767,3768],{"class":901,"line":1417},[899,3769,3770],{},"            return ValidationResult(\n",[899,3772,3773],{"class":901,"line":2410},[899,3774,3775],{},"                passed=False,\n",[899,3777,3778],{"class":901,"line":2650},[899,3779,3780],{},"                reason=\"Suspicious pattern detected\"\n",[899,3782,3783],{"class":901,"line":2656},[899,3784,3785],{},"            )\n",[899,3787,3788],{"class":901,"line":2662},[899,3789,3585],{},[1878,3791],{},[178,3793,3795],{"id":3794},"layer-2-authentication-authorization","Layer 2: Authentication & Authorization",[10,3797,3798,3800],{},[314,3799,3434],{}," Ohne Authentication wissen Sie nicht, wer Ihre API nutzt. Ohne Authorization kann jeder alles, auch GPT-4o mit 128k Context. Bei aktuellen Preisen (Stand Dezember 2025: $2,50\u002F1M Input, $10\u002F1M Output) summiert sich das schnell auf dreistellige Beträge pro Stunde.",[3525,3802,3804],{"id":3803},"_21-api-key-validierung","2.1 API-Key-Validierung",[10,3806,3807],{},"Klingt banal, wird aber oft falsch gemacht. Keys gehören nicht in Code oder Config-Files, sondern in einen Secrets Manager.",[890,3809,3811],{"className":892,"code":3810,"language":894,"meta":728,"style":728},"from fastapi import Depends, HTTPException, Security\nfrom fastapi.security import APIKeyHeader\n\napi_key_header = APIKeyHeader(name=\"X-API-Key\")\n\nasync def verify_api_key(api_key: str = Security(api_key_header)):\n    # Gegen Secrets Manager validieren, nicht Hardcoded!\n    valid_keys = await secrets_manager.get_valid_keys()\n\n    if api_key not in valid_keys:\n        log_security_event(\"invalid_api_key\", api_key[:8])\n        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n\n    return await get_key_metadata(api_key)\n",[896,3812,3813,3818,3823,3827,3832,3836,3841,3846,3851,3855,3860,3865,3870,3874],{"__ignoreMap":728},[899,3814,3815],{"class":901,"line":902},[899,3816,3817],{},"from fastapi import Depends, HTTPException, Security\n",[899,3819,3820],{"class":901,"line":729},[899,3821,3822],{},"from fastapi.security import APIKeyHeader\n",[899,3824,3825],{"class":901,"line":734},[899,3826,945],{"emptyLinePlaceholder":751},[899,3828,3829],{"class":901,"line":918},[899,3830,3831],{},"api_key_header = APIKeyHeader(name=\"X-API-Key\")\n",[899,3833,3834],{"class":901,"line":924},[899,3835,945],{"emptyLinePlaceholder":751},[899,3837,3838],{"class":901,"line":930},[899,3839,3840],{},"async def verify_api_key(api_key: str = Security(api_key_header)):\n",[899,3842,3843],{"class":901,"line":936},[899,3844,3845],{},"    # Gegen Secrets Manager validieren, nicht Hardcoded!\n",[899,3847,3848],{"class":901,"line":942},[899,3849,3850],{},"    valid_keys = await secrets_manager.get_valid_keys()\n",[899,3852,3853],{"class":901,"line":948},[899,3854,945],{"emptyLinePlaceholder":751},[899,3856,3857],{"class":901,"line":954},[899,3858,3859],{},"    if api_key not in valid_keys:\n",[899,3861,3862],{"class":901,"line":754},[899,3863,3864],{},"        log_security_event(\"invalid_api_key\", api_key[:8])\n",[899,3866,3867],{"class":901,"line":964},[899,3868,3869],{},"        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n",[899,3871,3872],{"class":901,"line":970},[899,3873,945],{"emptyLinePlaceholder":751},[899,3875,3876],{"class":901,"line":1113},[899,3877,3878],{},"    return await get_key_metadata(api_key)\n",[3525,3880,3882],{"id":3881},"_22-role-based-access","2.2 Role-Based Access",[10,3884,3885],{},"Nicht jeder Nutzer braucht Zugang zu jedem Modell. Ein Praktikant braucht kein GPT-4o, eine interne App kein Fine-Tuning. Definieren Sie Rollen mit klaren Berechtigungen.",[890,3887,3889],{"className":892,"code":3888,"language":894,"meta":728,"style":728},"class Permission(Enum):\n    GPT4O = \"gpt4o\"\n    GPT4O_MINI = \"gpt4o_mini\"\n    EMBEDDING = \"embedding\"\n    FINE_TUNE = \"fine_tune\"\n    AGENT = \"agent\"\n\nROLE_PERMISSIONS = {\n    \"basic\": [Permission.GPT4O_MINI, Permission.EMBEDDING],\n    \"advanced\": [Permission.GPT4O_MINI, Permission.GPT4O, Permission.EMBEDDING],\n    \"admin\": [Permission.GPT4O_MINI, Permission.GPT4O, Permission.EMBEDDING,\n              Permission.FINE_TUNE, Permission.AGENT],\n}\n\nasync def check_permission(\n    key_meta: KeyMetadata,\n    required: Permission\n) -> bool:\n    user_permissions = ROLE_PERMISSIONS.get(key_meta.role, [])\n    return required in user_permissions\n",[896,3890,3891,3896,3901,3906,3911,3916,3921,3925,3930,3935,3940,3945,3950,3955,3959,3964,3969,3974,3979,3984],{"__ignoreMap":728},[899,3892,3893],{"class":901,"line":902},[899,3894,3895],{},"class Permission(Enum):\n",[899,3897,3898],{"class":901,"line":729},[899,3899,3900],{},"    GPT4O = \"gpt4o\"\n",[899,3902,3903],{"class":901,"line":734},[899,3904,3905],{},"    GPT4O_MINI = \"gpt4o_mini\"\n",[899,3907,3908],{"class":901,"line":918},[899,3909,3910],{},"    EMBEDDING = \"embedding\"\n",[899,3912,3913],{"class":901,"line":924},[899,3914,3915],{},"    FINE_TUNE = \"fine_tune\"\n",[899,3917,3918],{"class":901,"line":930},[899,3919,3920],{},"    AGENT = \"agent\"\n",[899,3922,3923],{"class":901,"line":936},[899,3924,945],{"emptyLinePlaceholder":751},[899,3926,3927],{"class":901,"line":942},[899,3928,3929],{},"ROLE_PERMISSIONS = {\n",[899,3931,3932],{"class":901,"line":948},[899,3933,3934],{},"    \"basic\": [Permission.GPT4O_MINI, Permission.EMBEDDING],\n",[899,3936,3937],{"class":901,"line":954},[899,3938,3939],{},"    \"advanced\": [Permission.GPT4O_MINI, Permission.GPT4O, Permission.EMBEDDING],\n",[899,3941,3942],{"class":901,"line":754},[899,3943,3944],{},"    \"admin\": [Permission.GPT4O_MINI, Permission.GPT4O, Permission.EMBEDDING,\n",[899,3946,3947],{"class":901,"line":964},[899,3948,3949],{},"              Permission.FINE_TUNE, Permission.AGENT],\n",[899,3951,3952],{"class":901,"line":970},[899,3953,3954],{},"}\n",[899,3956,3957],{"class":901,"line":1113},[899,3958,945],{"emptyLinePlaceholder":751},[899,3960,3961],{"class":901,"line":1417},[899,3962,3963],{},"async def check_permission(\n",[899,3965,3966],{"class":901,"line":2410},[899,3967,3968],{},"    key_meta: KeyMetadata,\n",[899,3970,3971],{"class":901,"line":2650},[899,3972,3973],{},"    required: Permission\n",[899,3975,3976],{"class":901,"line":2656},[899,3977,3978],{},") -> bool:\n",[899,3980,3981],{"class":901,"line":2662},[899,3982,3983],{},"    user_permissions = ROLE_PERMISSIONS.get(key_meta.role, [])\n",[899,3985,3986],{"class":901,"line":2668},[899,3987,3988],{},"    return required in user_permissions\n",[3525,3990,3992],{"id":3991},"_23-least-privilege-für-api-keys","2.3 Least Privilege für API-Keys",[10,3994,3995],{},"Jeder Key sollte nur die Rechte haben, die er braucht. Scope, Modelle, Rate-Limits, Budget, IP-Ranges, Ablaufdatum: alles definiert.",[890,3997,4001],{"className":3998,"code":3999,"language":4000,"meta":728,"style":728},"language-yaml shiki shiki-themes github-dark github-dark github-dark","# Key-Erstellung mit minimalem Scope\napi_keys:\n  - id: key_prod_chat_001\n    role: basic\n    allowed_models: [\"gpt-4o-mini\"]\n    rate_limit: 100\u002Fminute\n    budget: 50\u002Fmonth\n    allowed_ips: [\"10.0.0.0\u002F8\"]\n    expires: 2026-06-01\n","yaml",[896,4002,4003,4008,4018,4032,4042,4055,4065,4075,4087],{"__ignoreMap":728},[899,4004,4005],{"class":901,"line":902},[899,4006,4007],{"class":2299},"# Key-Erstellung mit minimalem Scope\n",[899,4009,4010,4014],{"class":901,"line":729},[899,4011,4013],{"class":4012},"sQwZJ","api_keys",[899,4015,4017],{"class":4016},"s9RsZ",":\n",[899,4019,4020,4023,4026,4029],{"class":901,"line":734},[899,4021,4022],{"class":4016},"  - ",[899,4024,4025],{"class":4012},"id",[899,4027,4028],{"class":4016},": ",[899,4030,4031],{"class":2313},"key_prod_chat_001\n",[899,4033,4034,4037,4039],{"class":901,"line":918},[899,4035,4036],{"class":4012},"    role",[899,4038,4028],{"class":4016},[899,4040,4041],{"class":2313},"basic\n",[899,4043,4044,4047,4050,4053],{"class":901,"line":924},[899,4045,4046],{"class":4012},"    allowed_models",[899,4048,4049],{"class":4016},": [",[899,4051,4052],{"class":2313},"\"gpt-4o-mini\"",[899,4054,3741],{"class":4016},[899,4056,4057,4060,4062],{"class":901,"line":930},[899,4058,4059],{"class":4012},"    rate_limit",[899,4061,4028],{"class":4016},[899,4063,4064],{"class":2313},"100\u002Fminute\n",[899,4066,4067,4070,4072],{"class":901,"line":936},[899,4068,4069],{"class":4012},"    budget",[899,4071,4028],{"class":4016},[899,4073,4074],{"class":2313},"50\u002Fmonth\n",[899,4076,4077,4080,4082,4085],{"class":901,"line":942},[899,4078,4079],{"class":4012},"    allowed_ips",[899,4081,4049],{"class":4016},[899,4083,4084],{"class":2313},"\"10.0.0.0\u002F8\"",[899,4086,3741],{"class":4016},[899,4088,4089,4092,4094],{"class":901,"line":948},[899,4090,4091],{"class":4012},"    expires",[899,4093,4028],{"class":4016},[899,4095,4096],{"class":2309},"2026-06-01\n",[10,4098,4099,4100],{},"Mehr zum Thema API-Key-Management: ",[14,4101,4103],{"href":4102},"\u002Fblog\u002Fnhi-management","Non-Human Identity Management",[1878,4105],{},[178,4107,4109],{"id":4108},"layer-3-rate-limiting","Layer 3: Rate Limiting",[10,4111,4112,4114],{},[314,4113,3434],{}," LLM-APIs sind teuer. Ein kompromittierter Key ohne Rate-Limit kann in Stunden fünfstellige Kosten verursachen. Außerdem schützt Rate-Limiting vor DoS und macht Credential-Stuffing unattraktiv.",[3525,4116,4118],{"id":4117},"_31-multi-dimensional-rate-limiting","3.1 Multi-Dimensional Rate Limiting",[10,4120,4121],{},"Bei klassischen APIs reicht oft \"60 Requests pro Minute\". Bei LLMs ist das zu simpel: Ein Request mit 100k Tokens kostet 100x mehr als einer mit 1k Tokens. Sie brauchen Token-basiertes Limiting.",[890,4123,4125],{"className":892,"code":4124,"language":894,"meta":728,"style":728},"from slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(key_func=get_remote_address)\n\n# Request-basiert (Basis-Schutz)\n@app.post(\"\u002Fchat\")\n@limiter.limit(\"60\u002Fminute\")\nasync def chat(request: Request):\n    ...\n\n# Token-basiert (kritisch bei LLMs!)\nclass TokenRateLimiter:\n    def __init__(self, max_tokens_per_minute: int):\n        self.max_tokens = max_tokens_per_minute\n        self.windows = {}  # user_id -> deque of (timestamp, tokens)\n\n    async def check(self, user_id: str, estimated_tokens: int) -> bool:\n        window = self.windows.get(user_id, deque())\n\n        # Alte Einträge entfernen (> 1 Minute)\n        now = time.time()\n        while window and window[0][0] \u003C now - 60:\n            window.popleft()\n\n        # Aktuelle Summe\n        current_tokens = sum(t for _, t in window)\n\n        if current_tokens + estimated_tokens > self.max_tokens:\n            return False\n\n        window.append((now, estimated_tokens))\n        self.windows[user_id] = window\n        return True\n",[896,4126,4127,4132,4137,4141,4146,4150,4155,4160,4165,4170,4175,4179,4184,4189,4194,4199,4204,4208,4213,4218,4222,4227,4232,4237,4242,4246,4251,4256,4260,4265,4270,4274,4279,4284],{"__ignoreMap":728},[899,4128,4129],{"class":901,"line":902},[899,4130,4131],{},"from slowapi import Limiter\n",[899,4133,4134],{"class":901,"line":729},[899,4135,4136],{},"from slowapi.util import get_remote_address\n",[899,4138,4139],{"class":901,"line":734},[899,4140,945],{"emptyLinePlaceholder":751},[899,4142,4143],{"class":901,"line":918},[899,4144,4145],{},"limiter = Limiter(key_func=get_remote_address)\n",[899,4147,4148],{"class":901,"line":924},[899,4149,945],{"emptyLinePlaceholder":751},[899,4151,4152],{"class":901,"line":930},[899,4153,4154],{},"# Request-basiert (Basis-Schutz)\n",[899,4156,4157],{"class":901,"line":936},[899,4158,4159],{},"@app.post(\"\u002Fchat\")\n",[899,4161,4162],{"class":901,"line":942},[899,4163,4164],{},"@limiter.limit(\"60\u002Fminute\")\n",[899,4166,4167],{"class":901,"line":948},[899,4168,4169],{},"async def chat(request: Request):\n",[899,4171,4172],{"class":901,"line":954},[899,4173,4174],{},"    ...\n",[899,4176,4177],{"class":901,"line":754},[899,4178,945],{"emptyLinePlaceholder":751},[899,4180,4181],{"class":901,"line":964},[899,4182,4183],{},"# Token-basiert (kritisch bei LLMs!)\n",[899,4185,4186],{"class":901,"line":970},[899,4187,4188],{},"class TokenRateLimiter:\n",[899,4190,4191],{"class":901,"line":1113},[899,4192,4193],{},"    def __init__(self, max_tokens_per_minute: int):\n",[899,4195,4196],{"class":901,"line":1417},[899,4197,4198],{},"        self.max_tokens = max_tokens_per_minute\n",[899,4200,4201],{"class":901,"line":2410},[899,4202,4203],{},"        self.windows = {}  # user_id -> deque of (timestamp, tokens)\n",[899,4205,4206],{"class":901,"line":2650},[899,4207,945],{"emptyLinePlaceholder":751},[899,4209,4210],{"class":901,"line":2656},[899,4211,4212],{},"    async def check(self, user_id: str, estimated_tokens: int) -> bool:\n",[899,4214,4215],{"class":901,"line":2662},[899,4216,4217],{},"        window = self.windows.get(user_id, deque())\n",[899,4219,4220],{"class":901,"line":2668},[899,4221,945],{"emptyLinePlaceholder":751},[899,4223,4224],{"class":901,"line":2673},[899,4225,4226],{},"        # Alte Einträge entfernen (> 1 Minute)\n",[899,4228,4229],{"class":901,"line":2678},[899,4230,4231],{},"        now = time.time()\n",[899,4233,4234],{"class":901,"line":2684},[899,4235,4236],{},"        while window and window[0][0] \u003C now - 60:\n",[899,4238,4239],{"class":901,"line":2689},[899,4240,4241],{},"            window.popleft()\n",[899,4243,4244],{"class":901,"line":2695},[899,4245,945],{"emptyLinePlaceholder":751},[899,4247,4248],{"class":901,"line":2700},[899,4249,4250],{},"        # Aktuelle Summe\n",[899,4252,4253],{"class":901,"line":2706},[899,4254,4255],{},"        current_tokens = sum(t for _, t in window)\n",[899,4257,4258],{"class":901,"line":2712},[899,4259,945],{"emptyLinePlaceholder":751},[899,4261,4262],{"class":901,"line":2717},[899,4263,4264],{},"        if current_tokens + estimated_tokens > self.max_tokens:\n",[899,4266,4267],{"class":901,"line":2723},[899,4268,4269],{},"            return False\n",[899,4271,4272],{"class":901,"line":2729},[899,4273,945],{"emptyLinePlaceholder":751},[899,4275,4276],{"class":901,"line":2734},[899,4277,4278],{},"        window.append((now, estimated_tokens))\n",[899,4280,4281],{"class":901,"line":2739},[899,4282,4283],{},"        self.windows[user_id] = window\n",[899,4285,4286],{"class":901,"line":1857},[899,4287,4288],{},"        return True\n",[3525,4290,4292],{"id":4291},"_32-budget-limits","3.2 Budget-Limits",[10,4294,4295],{},"Rate-Limits schützen pro Minute, Budgets pro Monat. Definieren Sie für jeden Key oder User ein monatliches Budget und alertieren Sie frühzeitig.",[890,4297,4299],{"className":892,"code":4298,"language":894,"meta":728,"style":728},"class BudgetEnforcer:\n    async def check_budget(self, user_id: str, estimated_cost: float) -> bool:\n        user = await get_user(user_id)\n        current_spend = await get_current_month_spend(user_id)\n\n        if current_spend + estimated_cost > user.monthly_budget:\n            await notify_budget_exceeded(user_id)\n            return False\n\n        return True\n\n    async def record_spend(self, user_id: str, actual_cost: float):\n        await increment_spend(user_id, actual_cost)\n\n        # Alert bei 80%, 90%, 100%\n        current = await get_current_month_spend(user_id)\n        user = await get_user(user_id)\n        percentage = current \u002F user.monthly_budget\n\n        if percentage >= 1.0:\n            await alert_budget_exceeded(user_id)\n        elif percentage >= 0.9:\n            await alert_budget_warning(user_id, 90)\n        elif percentage >= 0.8:\n            await alert_budget_warning(user_id, 80)\n",[896,4300,4301,4306,4311,4316,4321,4325,4330,4335,4339,4343,4347,4351,4356,4361,4365,4370,4375,4379,4384,4388,4393,4398,4403,4408,4413],{"__ignoreMap":728},[899,4302,4303],{"class":901,"line":902},[899,4304,4305],{},"class BudgetEnforcer:\n",[899,4307,4308],{"class":901,"line":729},[899,4309,4310],{},"    async def check_budget(self, user_id: str, estimated_cost: float) -> bool:\n",[899,4312,4313],{"class":901,"line":734},[899,4314,4315],{},"        user = await get_user(user_id)\n",[899,4317,4318],{"class":901,"line":918},[899,4319,4320],{},"        current_spend = await get_current_month_spend(user_id)\n",[899,4322,4323],{"class":901,"line":924},[899,4324,945],{"emptyLinePlaceholder":751},[899,4326,4327],{"class":901,"line":930},[899,4328,4329],{},"        if current_spend + estimated_cost > user.monthly_budget:\n",[899,4331,4332],{"class":901,"line":936},[899,4333,4334],{},"            await notify_budget_exceeded(user_id)\n",[899,4336,4337],{"class":901,"line":942},[899,4338,4269],{},[899,4340,4341],{"class":901,"line":948},[899,4342,945],{"emptyLinePlaceholder":751},[899,4344,4345],{"class":901,"line":954},[899,4346,4288],{},[899,4348,4349],{"class":901,"line":754},[899,4350,945],{"emptyLinePlaceholder":751},[899,4352,4353],{"class":901,"line":964},[899,4354,4355],{},"    async def record_spend(self, user_id: str, actual_cost: float):\n",[899,4357,4358],{"class":901,"line":970},[899,4359,4360],{},"        await increment_spend(user_id, actual_cost)\n",[899,4362,4363],{"class":901,"line":1113},[899,4364,945],{"emptyLinePlaceholder":751},[899,4366,4367],{"class":901,"line":1417},[899,4368,4369],{},"        # Alert bei 80%, 90%, 100%\n",[899,4371,4372],{"class":901,"line":2410},[899,4373,4374],{},"        current = await get_current_month_spend(user_id)\n",[899,4376,4377],{"class":901,"line":2650},[899,4378,4315],{},[899,4380,4381],{"class":901,"line":2656},[899,4382,4383],{},"        percentage = current \u002F user.monthly_budget\n",[899,4385,4386],{"class":901,"line":2662},[899,4387,945],{"emptyLinePlaceholder":751},[899,4389,4390],{"class":901,"line":2668},[899,4391,4392],{},"        if percentage >= 1.0:\n",[899,4394,4395],{"class":901,"line":2673},[899,4396,4397],{},"            await alert_budget_exceeded(user_id)\n",[899,4399,4400],{"class":901,"line":2678},[899,4401,4402],{},"        elif percentage >= 0.9:\n",[899,4404,4405],{"class":901,"line":2684},[899,4406,4407],{},"            await alert_budget_warning(user_id, 90)\n",[899,4409,4410],{"class":901,"line":2689},[899,4411,4412],{},"        elif percentage >= 0.8:\n",[899,4414,4415],{"class":901,"line":2695},[899,4416,4417],{},"            await alert_budget_warning(user_id, 80)\n",[1878,4419],{},[178,4421,4423],{"id":4422},"layer-4-output-filtering","Layer 4: Output Filtering",[10,4425,4426,4428],{},[314,4427,3434],{}," Input-Validation allein reicht nicht. LLMs können auch bei \"sauberen\" Inputs problematische Outputs generieren: PII aus dem Training, System-Prompt-Leaks oder Policy-Verletzungen.",[3525,4430,4432],{"id":4431},"_41-pii-redaktion-im-output","4.1 PII-Redaktion im Output",[10,4434,4435],{},"Das LLM könnte persönliche Daten aus seinem Training oder aus dem Kontext in der Antwort wiedergeben. Scannen Sie Outputs genauso wie Inputs.",[890,4437,4439],{"className":892,"code":4438,"language":894,"meta":728,"style":728},"from presidio_anonymizer import AnonymizerEngine\n\ndef filter_pii_in_output(response: str) -> str:\n    analyzer = AnalyzerEngine()\n    anonymizer = AnonymizerEngine()\n\n    results = analyzer.analyze(text=response, language=\"de\")\n\n    if results:\n        log_security_event(\"pii_in_output\", len(results))\n        anonymized = anonymizer.anonymize(\n            text=response,\n            analyzer_results=results\n        )\n        return anonymized.text\n\n    return response\n",[896,4440,4441,4446,4450,4455,4460,4465,4469,4474,4478,4482,4487,4492,4497,4502,4506,4511,4515],{"__ignoreMap":728},[899,4442,4443],{"class":901,"line":902},[899,4444,4445],{},"from presidio_anonymizer import AnonymizerEngine\n",[899,4447,4448],{"class":901,"line":729},[899,4449,945],{"emptyLinePlaceholder":751},[899,4451,4452],{"class":901,"line":734},[899,4453,4454],{},"def filter_pii_in_output(response: str) -> str:\n",[899,4456,4457],{"class":901,"line":918},[899,4458,4459],{},"    analyzer = AnalyzerEngine()\n",[899,4461,4462],{"class":901,"line":924},[899,4463,4464],{},"    anonymizer = AnonymizerEngine()\n",[899,4466,4467],{"class":901,"line":930},[899,4468,945],{"emptyLinePlaceholder":751},[899,4470,4471],{"class":901,"line":936},[899,4472,4473],{},"    results = analyzer.analyze(text=response, language=\"de\")\n",[899,4475,4476],{"class":901,"line":942},[899,4477,945],{"emptyLinePlaceholder":751},[899,4479,4480],{"class":901,"line":948},[899,4481,3655],{},[899,4483,4484],{"class":901,"line":954},[899,4485,4486],{},"        log_security_event(\"pii_in_output\", len(results))\n",[899,4488,4489],{"class":901,"line":754},[899,4490,4491],{},"        anonymized = anonymizer.anonymize(\n",[899,4493,4494],{"class":901,"line":964},[899,4495,4496],{},"            text=response,\n",[899,4498,4499],{"class":901,"line":970},[899,4500,4501],{},"            analyzer_results=results\n",[899,4503,4504],{"class":901,"line":1113},[899,4505,3580],{},[899,4507,4508],{"class":901,"line":1417},[899,4509,4510],{},"        return anonymized.text\n",[899,4512,4513],{"class":901,"line":2410},[899,4514,945],{"emptyLinePlaceholder":751},[899,4516,4517],{"class":901,"line":2650},[899,4518,1414],{},[3525,4520,4522],{"id":4521},"_42-system-prompt-leakage-detection","4.2 System Prompt Leakage Detection",[10,4524,4525],{},"Ein häufiges Angriffsziel: Nutzer versuchen, den System-Prompt zu extrahieren. Wenn das LLM beginnt, seine Instruktionen preiszugeben, sollten Sie die Response blocken.",[890,4527,4529],{"className":892,"code":4528,"language":894,"meta":728,"style":728},"SYSTEM_PROMPT_INDICATORS = [\n    \"meine anweisungen sind\",\n    \"mir wurde gesagt\",\n    \"mein system prompt\",\n    \"ich wurde instruiert\",\n    \"meine richtlinien\",\n]\n\ndef check_system_prompt_leakage(response: str) -> bool:\n    lower_response = response.lower()\n    for indicator in SYSTEM_PROMPT_INDICATORS:\n        if indicator in lower_response:\n            log_security_event(\"potential_system_prompt_leak\", indicator)\n            return True\n    return False\n\ndef filter_output(response: str) -> str:\n    if check_system_prompt_leakage(response):\n        return \"Ich kann diese Anfrage nicht beantworten.\"\n\n    return filter_pii_in_output(response)\n",[896,4530,4531,4536,4541,4546,4551,4556,4561,4565,4569,4574,4579,4584,4589,4594,4599,4604,4608,4613,4618,4623,4627],{"__ignoreMap":728},[899,4532,4533],{"class":901,"line":902},[899,4534,4535],{},"SYSTEM_PROMPT_INDICATORS = [\n",[899,4537,4538],{"class":901,"line":729},[899,4539,4540],{},"    \"meine anweisungen sind\",\n",[899,4542,4543],{"class":901,"line":734},[899,4544,4545],{},"    \"mir wurde gesagt\",\n",[899,4547,4548],{"class":901,"line":918},[899,4549,4550],{},"    \"mein system prompt\",\n",[899,4552,4553],{"class":901,"line":924},[899,4554,4555],{},"    \"ich wurde instruiert\",\n",[899,4557,4558],{"class":901,"line":930},[899,4559,4560],{},"    \"meine richtlinien\",\n",[899,4562,4563],{"class":901,"line":936},[899,4564,3741],{},[899,4566,4567],{"class":901,"line":942},[899,4568,945],{"emptyLinePlaceholder":751},[899,4570,4571],{"class":901,"line":948},[899,4572,4573],{},"def check_system_prompt_leakage(response: str) -> bool:\n",[899,4575,4576],{"class":901,"line":954},[899,4577,4578],{},"    lower_response = response.lower()\n",[899,4580,4581],{"class":901,"line":754},[899,4582,4583],{},"    for indicator in SYSTEM_PROMPT_INDICATORS:\n",[899,4585,4586],{"class":901,"line":964},[899,4587,4588],{},"        if indicator in lower_response:\n",[899,4590,4591],{"class":901,"line":970},[899,4592,4593],{},"            log_security_event(\"potential_system_prompt_leak\", indicator)\n",[899,4595,4596],{"class":901,"line":1113},[899,4597,4598],{},"            return True\n",[899,4600,4601],{"class":901,"line":1417},[899,4602,4603],{},"    return False\n",[899,4605,4606],{"class":901,"line":2410},[899,4607,945],{"emptyLinePlaceholder":751},[899,4609,4610],{"class":901,"line":2650},[899,4611,4612],{},"def filter_output(response: str) -> str:\n",[899,4614,4615],{"class":901,"line":2656},[899,4616,4617],{},"    if check_system_prompt_leakage(response):\n",[899,4619,4620],{"class":901,"line":2662},[899,4621,4622],{},"        return \"Ich kann diese Anfrage nicht beantworten.\"\n",[899,4624,4625],{"class":901,"line":2668},[899,4626,945],{"emptyLinePlaceholder":751},[899,4628,4629],{"class":901,"line":2673},[899,4630,4631],{},"    return filter_pii_in_output(response)\n",[3525,4633,4635],{"id":4634},"_43-content-policy-enforcement","4.3 Content Policy Enforcement",[10,4637,4638],{},"Für Hate Speech, Gewalt und andere Policy-Verletzungen bietet OpenAI eine kostenlose Moderation-API, inzwischen auch multimodal (Text + Bilder). Nutzen Sie sie, auch wenn Sie andere Modelle verwenden.",[890,4640,4642],{"className":892,"code":4641,"language":894,"meta":728,"style":728},"async def check_content_policy(response: str) -> ContentPolicyResult:\n    # Text-Moderation (kostenlos, basiert auf GPT-4o)\n    moderation = await openai.moderations.create(input=response)\n\n    if moderation.results[0].flagged:\n        categories = moderation.results[0].categories\n        log_security_event(\"content_policy_violation\", categories)\n        return ContentPolicyResult(\n            passed=False,\n            categories=categories\n        )\n\n    return ContentPolicyResult(passed=True)\n\n# Neu 2025: Auch Bilder können moderiert werden\nasync def check_image_policy(image_url: str) -> ContentPolicyResult:\n    moderation = await openai.moderations.create(\n        model=\"omni-moderation-latest\",\n        input=[{\"type\": \"image_url\", \"image_url\": {\"url\": image_url}}]\n    )\n    return ContentPolicyResult(passed=not moderation.results[0].flagged)\n",[896,4643,4644,4649,4654,4659,4663,4668,4673,4678,4683,4687,4692,4696,4700,4705,4709,4714,4719,4724,4729,4734,4738],{"__ignoreMap":728},[899,4645,4646],{"class":901,"line":902},[899,4647,4648],{},"async def check_content_policy(response: str) -> ContentPolicyResult:\n",[899,4650,4651],{"class":901,"line":729},[899,4652,4653],{},"    # Text-Moderation (kostenlos, basiert auf GPT-4o)\n",[899,4655,4656],{"class":901,"line":734},[899,4657,4658],{},"    moderation = await openai.moderations.create(input=response)\n",[899,4660,4661],{"class":901,"line":918},[899,4662,945],{"emptyLinePlaceholder":751},[899,4664,4665],{"class":901,"line":924},[899,4666,4667],{},"    if moderation.results[0].flagged:\n",[899,4669,4670],{"class":901,"line":930},[899,4671,4672],{},"        categories = moderation.results[0].categories\n",[899,4674,4675],{"class":901,"line":936},[899,4676,4677],{},"        log_security_event(\"content_policy_violation\", categories)\n",[899,4679,4680],{"class":901,"line":942},[899,4681,4682],{},"        return ContentPolicyResult(\n",[899,4684,4685],{"class":901,"line":948},[899,4686,3570],{},[899,4688,4689],{"class":901,"line":954},[899,4690,4691],{},"            categories=categories\n",[899,4693,4694],{"class":901,"line":754},[899,4695,3580],{},[899,4697,4698],{"class":901,"line":964},[899,4699,945],{"emptyLinePlaceholder":751},[899,4701,4702],{"class":901,"line":970},[899,4703,4704],{},"    return ContentPolicyResult(passed=True)\n",[899,4706,4707],{"class":901,"line":1113},[899,4708,945],{"emptyLinePlaceholder":751},[899,4710,4711],{"class":901,"line":1417},[899,4712,4713],{},"# Neu 2025: Auch Bilder können moderiert werden\n",[899,4715,4716],{"class":901,"line":2410},[899,4717,4718],{},"async def check_image_policy(image_url: str) -> ContentPolicyResult:\n",[899,4720,4721],{"class":901,"line":2650},[899,4722,4723],{},"    moderation = await openai.moderations.create(\n",[899,4725,4726],{"class":901,"line":2656},[899,4727,4728],{},"        model=\"omni-moderation-latest\",\n",[899,4730,4731],{"class":901,"line":2662},[899,4732,4733],{},"        input=[{\"type\": \"image_url\", \"image_url\": {\"url\": image_url}}]\n",[899,4735,4736],{"class":901,"line":2668},[899,4737,3646],{},[899,4739,4740],{"class":901,"line":2673},[899,4741,4742],{},"    return ContentPolicyResult(passed=not moderation.results[0].flagged)\n",[1878,4744],{},[178,4746,4748],{"id":4747},"layer-5-monitoring-alerting","Layer 5: Monitoring & Alerting",[10,4750,4751,4753],{},[314,4752,3434],{}," Die anderen Layer sind präventiv. Monitoring ist detektiv: Es hilft Ihnen, Angriffe zu erkennen, die durch die anderen Layer geschlüpft sind, und gibt Ihnen die Daten für Forensik und Compliance.",[3525,4755,4757],{"id":4756},"_51-was-sie-loggen-sollten","5.1 Was Sie loggen sollten",[10,4759,4760],{},"Nicht den vollen Prompt, das wäre ein Datenschutzproblem. Aber genug Metadaten, um Anomalien zu erkennen und Incidents zu untersuchen.",[890,4762,4764],{"className":892,"code":4763,"language":894,"meta":728,"style":728},"@dataclass\nclass AIRequestLog:\n    timestamp: datetime\n    request_id: str\n    user_id: str\n    model: str\n    input_tokens: int\n    output_tokens: int\n    input_hash: str  # Nicht den vollen Input loggen!\n    latency_ms: float\n    status: str\n    cost: float\n    flagged: bool\n    flags: List[str]  # PII, injection_attempt, etc.\n\nasync def log_request(log: AIRequestLog):\n    await siem_client.send(log.to_dict())  # An SIEM senden\n    await billing_service.record(log)       # Für Billing\n    await analytics_service.record(log)     # Für Analytics\n",[896,4765,4766,4771,4776,4781,4786,4791,4796,4801,4806,4811,4816,4821,4826,4831,4836,4840,4845,4850,4855],{"__ignoreMap":728},[899,4767,4768],{"class":901,"line":902},[899,4769,4770],{},"@dataclass\n",[899,4772,4773],{"class":901,"line":729},[899,4774,4775],{},"class AIRequestLog:\n",[899,4777,4778],{"class":901,"line":734},[899,4779,4780],{},"    timestamp: datetime\n",[899,4782,4783],{"class":901,"line":918},[899,4784,4785],{},"    request_id: str\n",[899,4787,4788],{"class":901,"line":924},[899,4789,4790],{},"    user_id: str\n",[899,4792,4793],{"class":901,"line":930},[899,4794,4795],{},"    model: str\n",[899,4797,4798],{"class":901,"line":936},[899,4799,4800],{},"    input_tokens: int\n",[899,4802,4803],{"class":901,"line":942},[899,4804,4805],{},"    output_tokens: int\n",[899,4807,4808],{"class":901,"line":948},[899,4809,4810],{},"    input_hash: str  # Nicht den vollen Input loggen!\n",[899,4812,4813],{"class":901,"line":954},[899,4814,4815],{},"    latency_ms: float\n",[899,4817,4818],{"class":901,"line":754},[899,4819,4820],{},"    status: str\n",[899,4822,4823],{"class":901,"line":964},[899,4824,4825],{},"    cost: float\n",[899,4827,4828],{"class":901,"line":970},[899,4829,4830],{},"    flagged: bool\n",[899,4832,4833],{"class":901,"line":1113},[899,4834,4835],{},"    flags: List[str]  # PII, injection_attempt, etc.\n",[899,4837,4838],{"class":901,"line":1417},[899,4839,945],{"emptyLinePlaceholder":751},[899,4841,4842],{"class":901,"line":2410},[899,4843,4844],{},"async def log_request(log: AIRequestLog):\n",[899,4846,4847],{"class":901,"line":2650},[899,4848,4849],{},"    await siem_client.send(log.to_dict())  # An SIEM senden\n",[899,4851,4852],{"class":901,"line":2656},[899,4853,4854],{},"    await billing_service.record(log)       # Für Billing\n",[899,4856,4857],{"class":901,"line":2662},[899,4858,4859],{},"    await analytics_service.record(log)     # Für Analytics\n",[3525,4861,4863],{"id":4862},"_52-anomaly-detection","5.2 Anomaly Detection",[10,4865,4866],{},"Statische Regeln fangen bekannte Patterns. Anomaly Detection fängt unbekannte. Bauen Sie Baselines pro User auf und alertieren Sie bei Abweichungen.",[890,4868,4870],{"className":892,"code":4869,"language":894,"meta":728,"style":728},"class AnomalyDetector:\n    def __init__(self):\n        self.baselines = {}  # user_id -> BaselineStats\n\n    async def check(self, user_id: str, request: AIRequest) -> List[Anomaly]:\n        anomalies = []\n        baseline = self.baselines.get(user_id)\n\n        if not baseline:\n            return []  # Erste Requests, noch keine Baseline\n\n        # Ungewöhnliche Zeit\n        if not baseline.is_typical_hour(request.timestamp.hour):\n            anomalies.append(Anomaly(\"unusual_time\", severity=\"medium\"))\n\n        # Ungewöhnliches Volume\n        if request.tokens > baseline.avg_tokens * 3:\n            anomalies.append(Anomaly(\"high_token_count\", severity=\"medium\"))\n\n        # Ungewöhnliches Model\n        if request.model not in baseline.typical_models:\n            anomalies.append(Anomaly(\"unusual_model\", severity=\"low\"))\n\n        # Ungewöhnliche IP\n        if request.ip not in baseline.known_ips:\n            anomalies.append(Anomaly(\"new_ip\", severity=\"high\"))\n\n        return anomalies\n",[896,4871,4872,4877,4882,4887,4891,4896,4901,4906,4910,4915,4920,4924,4929,4934,4939,4943,4948,4953,4958,4962,4967,4972,4977,4981,4986,4991,4996,5000],{"__ignoreMap":728},[899,4873,4874],{"class":901,"line":902},[899,4875,4876],{},"class AnomalyDetector:\n",[899,4878,4879],{"class":901,"line":729},[899,4880,4881],{},"    def __init__(self):\n",[899,4883,4884],{"class":901,"line":734},[899,4885,4886],{},"        self.baselines = {}  # user_id -> BaselineStats\n",[899,4888,4889],{"class":901,"line":918},[899,4890,945],{"emptyLinePlaceholder":751},[899,4892,4893],{"class":901,"line":924},[899,4894,4895],{},"    async def check(self, user_id: str, request: AIRequest) -> List[Anomaly]:\n",[899,4897,4898],{"class":901,"line":930},[899,4899,4900],{},"        anomalies = []\n",[899,4902,4903],{"class":901,"line":936},[899,4904,4905],{},"        baseline = self.baselines.get(user_id)\n",[899,4907,4908],{"class":901,"line":942},[899,4909,945],{"emptyLinePlaceholder":751},[899,4911,4912],{"class":901,"line":948},[899,4913,4914],{},"        if not baseline:\n",[899,4916,4917],{"class":901,"line":954},[899,4918,4919],{},"            return []  # Erste Requests, noch keine Baseline\n",[899,4921,4922],{"class":901,"line":754},[899,4923,945],{"emptyLinePlaceholder":751},[899,4925,4926],{"class":901,"line":964},[899,4927,4928],{},"        # Ungewöhnliche Zeit\n",[899,4930,4931],{"class":901,"line":970},[899,4932,4933],{},"        if not baseline.is_typical_hour(request.timestamp.hour):\n",[899,4935,4936],{"class":901,"line":1113},[899,4937,4938],{},"            anomalies.append(Anomaly(\"unusual_time\", severity=\"medium\"))\n",[899,4940,4941],{"class":901,"line":1417},[899,4942,945],{"emptyLinePlaceholder":751},[899,4944,4945],{"class":901,"line":2410},[899,4946,4947],{},"        # Ungewöhnliches Volume\n",[899,4949,4950],{"class":901,"line":2650},[899,4951,4952],{},"        if request.tokens > baseline.avg_tokens * 3:\n",[899,4954,4955],{"class":901,"line":2656},[899,4956,4957],{},"            anomalies.append(Anomaly(\"high_token_count\", severity=\"medium\"))\n",[899,4959,4960],{"class":901,"line":2662},[899,4961,945],{"emptyLinePlaceholder":751},[899,4963,4964],{"class":901,"line":2668},[899,4965,4966],{},"        # Ungewöhnliches Model\n",[899,4968,4969],{"class":901,"line":2673},[899,4970,4971],{},"        if request.model not in baseline.typical_models:\n",[899,4973,4974],{"class":901,"line":2678},[899,4975,4976],{},"            anomalies.append(Anomaly(\"unusual_model\", severity=\"low\"))\n",[899,4978,4979],{"class":901,"line":2684},[899,4980,945],{"emptyLinePlaceholder":751},[899,4982,4983],{"class":901,"line":2689},[899,4984,4985],{},"        # Ungewöhnliche IP\n",[899,4987,4988],{"class":901,"line":2695},[899,4989,4990],{},"        if request.ip not in baseline.known_ips:\n",[899,4992,4993],{"class":901,"line":2700},[899,4994,4995],{},"            anomalies.append(Anomaly(\"new_ip\", severity=\"high\"))\n",[899,4997,4998],{"class":901,"line":2706},[899,4999,945],{"emptyLinePlaceholder":751},[899,5001,5002],{"class":901,"line":2712},[899,5003,5004],{},"        return anomalies\n",[3525,5006,5008],{"id":5007},"_53-alert-rules","5.3 Alert-Rules",[10,5010,5011],{},"Definieren Sie klare Alert-Rules mit Severity und Action. Wer wird wann benachrichtigt? Was passiert automatisch?",[890,5013,5015],{"className":3998,"code":5014,"language":4000,"meta":728,"style":728},"alerts:\n  - name: injection_attempt_detected\n    condition: flags contains \"injection_attempt\"\n    severity: high\n    action: notify_security_team\n\n  - name: pii_in_output\n    condition: flags contains \"pii_detected\"\n    severity: medium\n    action: notify_privacy_team\n\n  - name: unusual_activity\n    condition: anomaly_score > 0.8\n    severity: medium\n    action: notify_security_team\n\n  - name: budget_exceeded\n    condition: monthly_spend > budget\n    severity: low\n    action: disable_key, notify_user\n",[896,5016,5017,5024,5036,5046,5056,5066,5070,5081,5090,5099,5108,5112,5123,5132,5140,5148,5152,5163,5172,5181],{"__ignoreMap":728},[899,5018,5019,5022],{"class":901,"line":902},[899,5020,5021],{"class":4012},"alerts",[899,5023,4017],{"class":4016},[899,5025,5026,5028,5031,5033],{"class":901,"line":729},[899,5027,4022],{"class":4016},[899,5029,5030],{"class":4012},"name",[899,5032,4028],{"class":4016},[899,5034,5035],{"class":2313},"injection_attempt_detected\n",[899,5037,5038,5041,5043],{"class":901,"line":734},[899,5039,5040],{"class":4012},"    condition",[899,5042,4028],{"class":4016},[899,5044,5045],{"class":2313},"flags contains \"injection_attempt\"\n",[899,5047,5048,5051,5053],{"class":901,"line":918},[899,5049,5050],{"class":4012},"    severity",[899,5052,4028],{"class":4016},[899,5054,5055],{"class":2313},"high\n",[899,5057,5058,5061,5063],{"class":901,"line":924},[899,5059,5060],{"class":4012},"    action",[899,5062,4028],{"class":4016},[899,5064,5065],{"class":2313},"notify_security_team\n",[899,5067,5068],{"class":901,"line":930},[899,5069,945],{"emptyLinePlaceholder":751},[899,5071,5072,5074,5076,5078],{"class":901,"line":936},[899,5073,4022],{"class":4016},[899,5075,5030],{"class":4012},[899,5077,4028],{"class":4016},[899,5079,5080],{"class":2313},"pii_in_output\n",[899,5082,5083,5085,5087],{"class":901,"line":942},[899,5084,5040],{"class":4012},[899,5086,4028],{"class":4016},[899,5088,5089],{"class":2313},"flags contains \"pii_detected\"\n",[899,5091,5092,5094,5096],{"class":901,"line":948},[899,5093,5050],{"class":4012},[899,5095,4028],{"class":4016},[899,5097,5098],{"class":2313},"medium\n",[899,5100,5101,5103,5105],{"class":901,"line":954},[899,5102,5060],{"class":4012},[899,5104,4028],{"class":4016},[899,5106,5107],{"class":2313},"notify_privacy_team\n",[899,5109,5110],{"class":901,"line":754},[899,5111,945],{"emptyLinePlaceholder":751},[899,5113,5114,5116,5118,5120],{"class":901,"line":964},[899,5115,4022],{"class":4016},[899,5117,5030],{"class":4012},[899,5119,4028],{"class":4016},[899,5121,5122],{"class":2313},"unusual_activity\n",[899,5124,5125,5127,5129],{"class":901,"line":970},[899,5126,5040],{"class":4012},[899,5128,4028],{"class":4016},[899,5130,5131],{"class":2313},"anomaly_score > 0.8\n",[899,5133,5134,5136,5138],{"class":901,"line":1113},[899,5135,5050],{"class":4012},[899,5137,4028],{"class":4016},[899,5139,5098],{"class":2313},[899,5141,5142,5144,5146],{"class":901,"line":1417},[899,5143,5060],{"class":4012},[899,5145,4028],{"class":4016},[899,5147,5065],{"class":2313},[899,5149,5150],{"class":901,"line":2410},[899,5151,945],{"emptyLinePlaceholder":751},[899,5153,5154,5156,5158,5160],{"class":901,"line":2650},[899,5155,4022],{"class":4016},[899,5157,5030],{"class":4012},[899,5159,4028],{"class":4016},[899,5161,5162],{"class":2313},"budget_exceeded\n",[899,5164,5165,5167,5169],{"class":901,"line":2656},[899,5166,5040],{"class":4012},[899,5168,4028],{"class":4016},[899,5170,5171],{"class":2313},"monthly_spend > budget\n",[899,5173,5174,5176,5178],{"class":901,"line":2662},[899,5175,5050],{"class":4012},[899,5177,4028],{"class":4016},[899,5179,5180],{"class":2313},"low\n",[899,5182,5183,5185,5187],{"class":901,"line":2668},[899,5184,5060],{"class":4012},[899,5186,4028],{"class":4016},[899,5188,5189],{"class":2313},"disable_key, notify_user\n",[1878,5191],{},[39,5193,5195],{"id":5194},"tools-frameworks","Tools & Frameworks",[10,5197,5198],{},"Sie müssen nicht alles selbst bauen. Diese Open-Source-Tools und Frameworks decken wesentliche Teile des 5-Layer-Modells ab. Stand: Dezember 2025.",[178,5200,5202],{"id":5201},"llm-guard-protect-ai","LLM Guard (Protect AI)",[10,5204,5205],{},"Open-Source-Bibliothek für Input- und Output-Scanning. Deckt Prompt Injection, Toxicity, PII und mehr ab. Aktiv gepflegt (letztes Update November 2025).",[890,5207,5209],{"className":892,"code":5208,"language":894,"meta":728,"style":728},"from llm_guard import scan_prompt, scan_output\nfrom llm_guard.input_scanners import PromptInjection, Toxicity\nfrom llm_guard.output_scanners import Sensitive, Relevance\n\ninput_scanners = [PromptInjection(), Toxicity()]\noutput_scanners = [Sensitive(), Relevance()]\n\n# Input scannen\nsanitized_prompt, results, is_valid = scan_prompt(\n    input_scanners, user_prompt\n)\n\n# Output scannen\nsanitized_output, results, is_valid = scan_output(\n    output_scanners, user_prompt, llm_response\n)\n",[896,5210,5211,5216,5221,5226,5230,5235,5240,5244,5249,5254,5259,5263,5267,5272,5277,5282],{"__ignoreMap":728},[899,5212,5213],{"class":901,"line":902},[899,5214,5215],{},"from llm_guard import scan_prompt, scan_output\n",[899,5217,5218],{"class":901,"line":729},[899,5219,5220],{},"from llm_guard.input_scanners import PromptInjection, Toxicity\n",[899,5222,5223],{"class":901,"line":734},[899,5224,5225],{},"from llm_guard.output_scanners import Sensitive, Relevance\n",[899,5227,5228],{"class":901,"line":918},[899,5229,945],{"emptyLinePlaceholder":751},[899,5231,5232],{"class":901,"line":924},[899,5233,5234],{},"input_scanners = [PromptInjection(), Toxicity()]\n",[899,5236,5237],{"class":901,"line":930},[899,5238,5239],{},"output_scanners = [Sensitive(), Relevance()]\n",[899,5241,5242],{"class":901,"line":936},[899,5243,945],{"emptyLinePlaceholder":751},[899,5245,5246],{"class":901,"line":942},[899,5247,5248],{},"# Input scannen\n",[899,5250,5251],{"class":901,"line":948},[899,5252,5253],{},"sanitized_prompt, results, is_valid = scan_prompt(\n",[899,5255,5256],{"class":901,"line":954},[899,5257,5258],{},"    input_scanners, user_prompt\n",[899,5260,5261],{"class":901,"line":754},[899,5262,1611],{},[899,5264,5265],{"class":901,"line":964},[899,5266,945],{"emptyLinePlaceholder":751},[899,5268,5269],{"class":901,"line":970},[899,5270,5271],{},"# Output scannen\n",[899,5273,5274],{"class":901,"line":1113},[899,5275,5276],{},"sanitized_output, results, is_valid = scan_output(\n",[899,5278,5279],{"class":901,"line":1417},[899,5280,5281],{},"    output_scanners, user_prompt, llm_response\n",[899,5283,5284],{"class":901,"line":2410},[899,5285,1611],{},[178,5287,5289],{"id":5288},"nemo-guardrails-nvidia","NeMo Guardrails (NVIDIA)",[10,5291,5292],{},"NVIDIA's Framework für programmierbare Conversation-Guardrails. Version 0.18.0 (November 2025) unterstützt jetzt auch Reasoning-Traces (BotThinking Events), LangGraph-Integration und Multi-Agent-Workflows.",[890,5294,5296],{"className":892,"code":5295,"language":894,"meta":728,"style":728},"from nemoguardrails import RailsConfig, LLMRails\n\nconfig = RailsConfig.from_path(\".\u002Fconfig\")\nrails = LLMRails(config)\n\n# Guardrails automatisch angewendet\nresponse = rails.generate(messages=[{\"role\": \"user\", \"content\": prompt}])\n",[896,5297,5298,5303,5307,5312,5317,5321,5326],{"__ignoreMap":728},[899,5299,5300],{"class":901,"line":902},[899,5301,5302],{},"from nemoguardrails import RailsConfig, LLMRails\n",[899,5304,5305],{"class":901,"line":729},[899,5306,945],{"emptyLinePlaceholder":751},[899,5308,5309],{"class":901,"line":734},[899,5310,5311],{},"config = RailsConfig.from_path(\".\u002Fconfig\")\n",[899,5313,5314],{"class":901,"line":918},[899,5315,5316],{},"rails = LLMRails(config)\n",[899,5318,5319],{"class":901,"line":924},[899,5320,945],{"emptyLinePlaceholder":751},[899,5322,5323],{"class":901,"line":930},[899,5324,5325],{},"# Guardrails automatisch angewendet\n",[899,5327,5328],{"class":901,"line":936},[899,5329,5330],{},"response = rails.generate(messages=[{\"role\": \"user\", \"content\": prompt}])\n",[10,5332,5333,5335],{},[314,5334,2895],{}," Python 3.10+ erforderlich (Support für 3.9 wurde im Oktober 2025 entfernt).",[178,5337,5339],{"id":5338},"microsoft-presidio","Microsoft Presidio",[10,5341,5342],{},"Der Goldstandard für PII-Detection und Anonymisierung. Unterstützt Deutsch und viele andere Sprachen. Für managed Services: Azure AI Language PII Detection bietet ähnliche Funktionalität als Cloud-Service.",[890,5344,5346],{"className":892,"code":5345,"language":894,"meta":728,"style":728},"from presidio_analyzer import AnalyzerEngine\nfrom presidio_anonymizer import AnonymizerEngine\n\nanalyzer = AnalyzerEngine()\nanonymizer = AnonymizerEngine()\n\n# PII finden\nresults = analyzer.analyze(\n    text=text,\n    entities=[\"PERSON\", \"EMAIL_ADDRESS\", \"PHONE_NUMBER\"],\n    language=\"de\"\n)\n\n# Anonymisieren\nanonymized = anonymizer.anonymize(text=text, analyzer_results=results)\n",[896,5347,5348,5353,5357,5361,5366,5371,5375,5380,5385,5390,5395,5400,5404,5408,5413],{"__ignoreMap":728},[899,5349,5350],{"class":901,"line":902},[899,5351,5352],{},"from presidio_analyzer import AnalyzerEngine\n",[899,5354,5355],{"class":901,"line":729},[899,5356,4445],{},[899,5358,5359],{"class":901,"line":734},[899,5360,945],{"emptyLinePlaceholder":751},[899,5362,5363],{"class":901,"line":918},[899,5364,5365],{},"analyzer = AnalyzerEngine()\n",[899,5367,5368],{"class":901,"line":924},[899,5369,5370],{},"anonymizer = AnonymizerEngine()\n",[899,5372,5373],{"class":901,"line":930},[899,5374,945],{"emptyLinePlaceholder":751},[899,5376,5377],{"class":901,"line":936},[899,5378,5379],{},"# PII finden\n",[899,5381,5382],{"class":901,"line":942},[899,5383,5384],{},"results = analyzer.analyze(\n",[899,5386,5387],{"class":901,"line":948},[899,5388,5389],{},"    text=text,\n",[899,5391,5392],{"class":901,"line":954},[899,5393,5394],{},"    entities=[\"PERSON\", \"EMAIL_ADDRESS\", \"PHONE_NUMBER\"],\n",[899,5396,5397],{"class":901,"line":754},[899,5398,5399],{},"    language=\"de\"\n",[899,5401,5402],{"class":901,"line":964},[899,5403,1611],{},[899,5405,5406],{"class":901,"line":970},[899,5407,945],{"emptyLinePlaceholder":751},[899,5409,5410],{"class":901,"line":1113},[899,5411,5412],{},"# Anonymisieren\n",[899,5414,5415],{"class":901,"line":1417},[899,5416,5417],{},"anonymized = anonymizer.anonymize(text=text, analyzer_results=results)\n",[178,5419,5421],{"id":5420},"cloud-provider-guardrails-2025","Cloud-Provider Guardrails (2025)",[10,5423,5424],{},"Die großen Cloud-Provider bieten inzwischen native Guardrails:",[532,5426,5427,5433,5439],{},[502,5428,5429,5432],{},[314,5430,5431],{},"Azure Prompt Shields:"," Machine-Learning-basierter Schutz gegen Prompt Injection, integriert in Azure AI Foundry",[502,5434,5435,5438],{},[314,5436,5437],{},"AWS Bedrock Guardrails:"," Content-Filter, Topic-Blocking und PII-Redaktion für Amazon Bedrock",[502,5440,5441,5444],{},[314,5442,5443],{},"OpenAI Moderation API:"," Kostenlos, jetzt multimodal (Text + Bilder), basiert auf GPT-4o",[178,5446,5448],{"id":5447},"spezialisierte-security-plattformen","Spezialisierte Security-Plattformen",[532,5450,5451,5457,5463],{},[502,5452,5453,5456],{},[314,5454,5455],{},"Lakera:"," AI-native Plattform spezialisiert auf Prompt Injection Detection",[502,5458,5459,5462],{},[314,5460,5461],{},"Mindgard:"," Automated AI Red Teaming mit Runtime-Protection",[502,5464,5465,5468],{},[314,5466,5467],{},"Purple Llama (Meta):"," Open-Source-Tools für Cyber Security und Input\u002FOutput Safeguards",[39,5470,5472],{"id":5471},"fazit-die-reihenfolge-zählt","Fazit: Die Reihenfolge zählt",[10,5474,5475],{},"Nicht alle Layer müssen am ersten Tag implementiert sein. Priorisieren Sie risikoorientiert:",[10,5477,5478,5481],{},[314,5479,5480],{},"Woche 1: Input Validation + Authentication."," Ohne diese beiden ist alles andere wertlos. Ein LLM ohne Input-Validation ist ein offenes System für Prompt Injection. Ohne Authentication wissen Sie nicht einmal, wer angreift.",[10,5483,5484,5487],{},[314,5485,5486],{},"Woche 2: Rate Limiting + Budget-Controls."," Kosten-Explosionen durch Missbrauch sind einer der häufigsten realen Incidents bei LLM-APIs. Setzen Sie Limits, bevor Sie live gehen, nicht nachdem die erste Rechnung kommt.",[10,5489,5490,5493],{},[314,5491,5492],{},"Woche 3-4: Output Filtering + Monitoring."," Output-Filter schützen vor PII-Leaks und System-Prompt-Leakage. Monitoring gibt Ihnen die Visibility, um Anomalien zu erkennen, bevor sie zu Incidents werden.",[10,5495,5496],{},"Die Code-Beispiele in diesem Artikel sind Startpunkte. Passen Sie sie an Ihre Architektur an, aber implementieren Sie alle 5 Layer.",[39,5498,530],{"id":529},[532,5500,5501,5505,5510,5517],{},[502,5502,5503,3127],{},[14,5504,1817],{"href":551},[502,5506,5507,5509],{},[14,5508,4103],{"href":4102},": API-Key-Lifecycle und Rotation",[502,5511,5512,5516],{},[14,5513,5515],{"href":5514},"\u002Fblog\u002Fsecurity-framework","KI Security Framework",": API Security im Gesamtkontext",[502,5518,5519,3147],{},[14,5520,5521],{"href":3145},"Enterprise AI Architecture",[1820,5523,5524],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sQwZJ, html code.shiki .sQwZJ{--shiki-light:#85E89D;--shiki-default:#85E89D;--shiki-dark:#85E89D}html pre.shiki code .s9RsZ, html code.shiki .s9RsZ{--shiki-light:#E1E4E8;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sWBnw, html code.shiki .sWBnw{--shiki-light:#9ECBFF;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sO5fp, html code.shiki .sO5fp{--shiki-light:#79B8FF;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}",{"title":728,"searchDepth":729,"depth":729,"links":5526},[5527,5531,5535,5542,5549,5550],{"id":3221,"depth":729,"text":3222,"children":5528},[5529,5530],{"id":3231,"depth":734,"text":3232},{"id":3276,"depth":734,"text":3277},{"id":3309,"depth":729,"text":3310,"children":5532},[5533,5534],{"id":3322,"depth":734,"text":3323},{"id":3406,"depth":734,"text":3407},{"id":3416,"depth":729,"text":3417,"children":5536},[5537,5538,5539,5540,5541],{"id":3428,"depth":734,"text":3429},{"id":3794,"depth":734,"text":3795},{"id":4108,"depth":734,"text":4109},{"id":4422,"depth":734,"text":4423},{"id":4747,"depth":734,"text":4748},{"id":5194,"depth":729,"text":5195,"children":5543},[5544,5545,5546,5547,5548],{"id":5201,"depth":734,"text":5202},{"id":5288,"depth":734,"text":5289},{"id":5338,"depth":734,"text":5339},{"id":5420,"depth":734,"text":5421},{"id":5447,"depth":734,"text":5448},{"id":5471,"depth":729,"text":5472},{"id":529,"depth":729,"text":530},"2025-11-23","5-Layer Security-Modell für LLM-APIs: Input Validation, Authentication, Rate Limiting, Output Filtering, Monitoring. Mit Code-Beispielen und Tool-Empfehlungen.","shield-check","api-security","2026-09-21",{},{"title":3139,"description":5552},"blog\u002Fapi-security","zLspyFF4FPL_GWzT7sZrYEz7aagi1JRVk9VFcHZzJ0Q",1789976918560]