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
|
|
@ -48,11 +48,23 @@ def _zaehle_seiten_befunde(diff: dict) -> dict:
|
|||
return z
|
||||
|
||||
|
||||
# Laienverständliche Beschreibung je KI-Kategorie.
|
||||
_KI_KATEGORIE_TEXT = {
|
||||
"pornography": "sexuell anstößige Inhalte",
|
||||
"propaganda": "politische Propaganda",
|
||||
"defamation_illegal": "möglicherweise strafbare oder verleumderische Aussagen",
|
||||
"hidden_spam": "versteckten Werbe-/Spam-Text",
|
||||
"off_topic_commercial": "Werbung, die nicht zum Thema Ihrer Website passt",
|
||||
"contradiction": "in sich widersprüchliche Aussagen",
|
||||
}
|
||||
|
||||
|
||||
def klartext_befunde(
|
||||
diff: dict | None = None,
|
||||
cloak_diff: dict | None = None,
|
||||
asset_diff: dict | None = None,
|
||||
ext_links: dict | None = None,
|
||||
ai_result: dict | None = None,
|
||||
) -> list[str]:
|
||||
"""
|
||||
Erzeugt eine Liste laienverständlicher Sätze aus den strukturierten Befunden.
|
||||
|
|
@ -159,6 +171,27 @@ def klartext_befunde(
|
|||
"Das ist meist harmlos — die fremde Seite wurde gelöscht oder umbenannt."
|
||||
)
|
||||
|
||||
# --- KI-Inhaltsanalyse ---
|
||||
if ai_result and ai_result.get("findings"):
|
||||
text_funde = [f for f in ai_result["findings"] if f.get("kind") == "text"]
|
||||
bild_funde = [f for f in ai_result["findings"] if f.get("kind") == "image"]
|
||||
if text_funde:
|
||||
kategorien = sorted({
|
||||
_KI_KATEGORIE_TEXT[f["category"]]
|
||||
for f in text_funde if f.get("category") in _KI_KATEGORIE_TEXT
|
||||
})
|
||||
beispiele = (" (z. B. " + ", ".join(kategorien[:3]) + ")") if kategorien else ""
|
||||
saetze.append(
|
||||
f"Eine automatische Inhaltsprüfung hat auf {len(text_funde)} Seite(n) Text "
|
||||
f"gefunden, der auffällig ist{beispiele}. "
|
||||
"Bitte schauen Sie sich die betroffenen Seiten an."
|
||||
)
|
||||
if bild_funde:
|
||||
saetze.append(
|
||||
f"Auf {len(bild_funde)} Bild(ern) wurden möglicherweise problematische "
|
||||
"Inhalte erkannt. Bitte prüfen Sie die betroffenen Bilder."
|
||||
)
|
||||
|
||||
if not saetze:
|
||||
saetze.append("Es hat sich nichts Verdächtiges verändert.")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue