feat: KI-gestützte Inhaltsanalyse via OpenRouter (hash-gegated)
Optionale semantische Prüfung von Text und Bildern (inkl. OCR) auf problematische Inhalte ohne Link-Signal: Pornografie, Propaganda, diffamierende/strafbare Texte, versteckter Spam, themenfremde Werbung, widersprüchliche Aussagen. Bewertet die thematische Passung zum deklarierten site_context — eingestreute Heimat-Begriffe täuschen die Erkennung nicht. Kern: - scanner/ai_analyzer.py: run_ai_analysis + score_ai_findings. Hash-Gate über data/ai_ledger.json → unveränderte Inhalte = Cache- Treffer = kein API-Call. Nur neue/geänderte Inhalte kosten etwas. - Modell-Kette mit zweifacher Eskalation (Stufe 1+2 free, Stufe 3 günstig bezahlt); eskaliert bei Fehler ODER Timeout (attempt_timeout). Erfolgreiches Modell wird im Ledger vermerkt. - KI-Funde sind auf GELB gedeckelt — ROT bleibt harten Integritäts- Signalen vorbehalten. Graceful degradation: ohne Key/bei Fehler wird übersprungen, Scan läuft unverändert weiter. Integration: - baseline.py: load/save_ai_ledger, dismiss_ai_entries. - config.py: ai_analysis-Block + ai_* Scoring-Schlüssel. - __main__.py: Einhängung in cmd_scan/cmd_check, ai-dismiss-Subcommand, approve quittiert zugehörige Funde, status-Anzeige, diff-only + report. - alerter.py + __main__.py: beanstandete Dateien erscheinen mit URL, Begründung und Quittier-Fingerprint in E-Mail UND Markdown-Report. - plain.py: laienverständliche KI-Sätze. API-Key nur aus Umgebungsvariable (OPENROUTER_API_KEY). Audio/Video als abschaltbare Hooks vorbereitet (default aus). Modelle live gegen OpenRouter verifiziert; Demo auf bredelar.info zeigte korrekte Erkennung (echter Inhalt clean, eingeschleuster Casino-Spam mit Heimat-Begriffen als hidden_spam erkannt). Tests: 227 grün (+26 für ai_analyzer, +1 für E-Mail-KI-Abschnitt). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0aaf53135a
commit
cae3dbb985
11 changed files with 1301 additions and 7 deletions
|
|
@ -41,6 +41,14 @@ DEFAULT_CONFIG: dict = {
|
|||
"changed_script": 40,
|
||||
"changed_stylesheet": 30,
|
||||
"changed_asset": 20,
|
||||
# KI-Inhaltsanalyse (additiv; Gesamt-Level aus KI ist auf gelb gedeckelt)
|
||||
"ai_pornography": 50,
|
||||
"ai_defamation_illegal": 50,
|
||||
"ai_propaganda": 40,
|
||||
"ai_hidden_spam": 40,
|
||||
"ai_off_topic_commercial": 30,
|
||||
"ai_contradiction": 20,
|
||||
"ai_suspicious_image": 40,
|
||||
},
|
||||
"thresholds": {
|
||||
"yellow": 20,
|
||||
|
|
@ -71,6 +79,49 @@ DEFAULT_CONFIG: dict = {
|
|||
"url": "",
|
||||
},
|
||||
},
|
||||
# KI-gestützte semantische Inhaltsanalyse (OpenRouter). Optional, opt-in.
|
||||
# Hash-gegated: nur neue/geänderte Inhalte lösen einen API-Call aus — siehe
|
||||
# ai_ledger.json. Der API-Key kommt NUR aus der Umgebungsvariable (nie in config.yaml).
|
||||
"ai_analysis": {
|
||||
"enabled": False,
|
||||
"api_key_env": "OPENROUTER_API_KEY",
|
||||
"site_context": "", # Themenbeschreibung der Website (Pflicht wenn enabled)
|
||||
"ai_confidence_min": 0.7, # Mindest-Konfidenz, damit ein Fund gewertet wird
|
||||
"request_timeout": 60, # Ceiling (auch für Asset-Fetch der Bilder)
|
||||
"attempt_timeout": 30, # Zeitlimit je Modell-Versuch → Eskalation bei Langsamkeit
|
||||
# Modell-Kette mit zweifacher Eskalation: Stufe 1+2 free, Stufe 3 günstig bezahlt.
|
||||
# Schlägt ein Modell fehl oder antwortet zu langsam, wird zur nächsten Stufe eskaliert.
|
||||
"text": {
|
||||
"enabled": True,
|
||||
"models": [
|
||||
"qwen/qwen3-next-80b-a3b-instruct:free", # Stufe 1: free
|
||||
"meta-llama/llama-3.3-70b-instruct:free", # Stufe 2: free
|
||||
"google/gemini-2.5-flash-lite", # Stufe 3: günstig bezahlt, zuverlässig
|
||||
],
|
||||
"min_chars": 200, # nur Seitentexte ab dieser Größe prüfen
|
||||
"max_pages_per_scan": 20, # Kostendeckel pro Lauf
|
||||
},
|
||||
"image": {
|
||||
"enabled": True,
|
||||
"models": [
|
||||
"google/gemma-4-31b-it:free", # Stufe 1: free, multimodal + OCR
|
||||
"nvidia/nemotron-nano-12b-v2-vl:free", # Stufe 2: free, Vision
|
||||
"google/gemini-2.5-flash-lite", # Stufe 3: günstig bezahlt, Vision
|
||||
],
|
||||
"max_images_per_scan": 15,
|
||||
},
|
||||
# Vorbereitet, default aus — Medien sind auf statischen Heimat-Seiten selten.
|
||||
"audio": {
|
||||
"enabled": False,
|
||||
"models": ["google/gemini-2.5-flash"],
|
||||
"max_files_per_scan": 5,
|
||||
},
|
||||
"video": {
|
||||
"enabled": False,
|
||||
"models": ["google/gemini-2.5-flash"],
|
||||
"max_files_per_scan": 3,
|
||||
},
|
||||
},
|
||||
"normalization": {
|
||||
"strip_html_comments": True,
|
||||
"collapse_whitespace": True,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue