feat(public-mood): Haiku-Moderationspass fuer Foren-Beitraege

Vor der Stimmungs-Zusammenfassung laeuft ein separater Haiku-Call, der pro
Forum-Beitrag entscheidet:
  - publishable: unveraendert uebernehmen
  - redact: thematisch wertvoll, aber PII/Beleidigungen — Haiku liefert eine
    bereinigte Kurzfassung
  - discard: Hassrede gegen Gruppen, NSFW, glaubhafte Drohungen, reines
    Trolling — entfernen

Damit liefert die jp_demo-Org keine ungefilterten 5ch/Hatena/Note-Posts
in die Lagen-Anzeige. Fail-open: Bei API-/Parse-Fehler wird die Original-
liste durchgereicht (Pipeline bricht nicht ab).

- analyzer.moderate_forum_articles: Batch (max 25/Call), JSON-Output, Logging
  pro Entscheidungs-Klasse.
- orchestrator: Moderation laeuft vor generate_public_mood, gefilterte Liste
  geht in die Stimmungs-Zusammenfassung.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
2026-05-22 00:28:30 +02:00
Ursprung d65f0180d9
Commit 16d1133442
2 geänderte Dateien mit 156 neuen und 4 gelöschten Zeilen

Datei anzeigen

@@ -1524,8 +1524,15 @@ class AgentOrchestrator:
await _pipe_start("public_mood")
try:
mood_agent = AnalyzerAgent()
# 1. Moderationspass: Hassrede/PII/NSFW vorab filtern.
moderated_articles, mod_usage = await mood_agent.moderate_forum_articles(
forum_articles_in_db,
)
if mod_usage:
usage_acc.add(mod_usage)
# 2. Stimmungs-Zusammenfassung aus gefilterten Beitraegen.
mood_text, mood_usage = await mood_agent.generate_public_mood(
title, description, forum_articles_in_db,
title, description, moderated_articles,
output_language=output_language,
)
if mood_usage:
@@ -1537,12 +1544,12 @@ class AgentOrchestrator:
)
await db.commit()
logger.info(
"Public-Mood gespeichert fuer Incident %d (%d Foren-Artikel)",
incident_id, len(forum_articles_in_db),
"Public-Mood gespeichert fuer Incident %d (%d -> %d Foren-Artikel nach Moderation)",
incident_id, len(forum_articles_in_db), len(moderated_articles),
)
await _pipe_done(
"public_mood",
count_value=len(forum_articles_in_db),
count_value=len(moderated_articles),
count_secondary=(1 if mood_text else 0),
)
except Exception as mood_err: