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:
Dieter Schlüter 2026-06-13 00:04:33 +02:00
commit cae3dbb985
11 changed files with 1301 additions and 7 deletions

View file

@ -127,6 +127,45 @@ alerting:
enabled: false
url: "" # z.B. Slack-Webhook oder Telegram-Bot-URL
# --- KI-gestützte Inhaltsanalyse (optional, OpenRouter) ---
# Prüft Text und Bilder semantisch auf problematische Inhalte (Pornografie,
# Propaganda, Spam, themenfremde Werbung, strafbare/widersprüchliche Aussagen).
# Kostengate: nur NEUE/GEÄNDERTE Inhalte lösen einen API-Call aus (Hash-Cache).
# KI-Funde sind auf GELB gedeckelt. API-Key NUR als Umgebungsvariable setzen:
# export OPENROUTER_API_KEY="sk-or-..."
ai_analysis:
enabled: false
api_key_env: "OPENROUTER_API_KEY"
# Themenbeschreibung der Website — die KI bewertet die Passung dazu, nicht
# einzelne Schlüsselwörter. Bitte ausfüllen, wenn enabled: true.
site_context: ""
ai_confidence_min: 0.7
attempt_timeout: 30 # Zeitlimit je Modell-Versuch (Sek.) → Auslöser der Eskalation
# 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
max_pages_per_scan: 20
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
# Audio/Video: vorbereitet, default aus (Medien auf statischen Seiten selten).
audio:
enabled: false
models: ["google/gemini-2.5-flash"]
video:
enabled: false
models: ["google/gemini-2.5-flash"]
# --- Normalisierung ---
# Elemente, die vor dem Vergleich aus dem HTML entfernt werden
# (z. B. dynamische Datums-/Zeitanzeigen die sich täglich ändern).