From 5a123ef3b857bd7e9a95bfa13659a8e3518f7dc7 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 9 May 2026 03:52:36 +0000 Subject: [PATCH] fix(researcher): Lagentitel-Eigennamen als Pflicht-Keywords (Bug 2 Buckelwal-Diagnose) KEYWORD_EXTRACTION_PROMPT explizit erweitert: - Eigennamen/Tiernamen/Personennamen aus dem THEMA als ZWINGEND markiert. - Hinweis dass DE und EN identisch sein duerfen (Eigennamen). - Klar gesagt: bei spezifischen Begriffen (>=7 Zeichen) reicht 1 Treffer in RSS-Headlines (passt zu rss_parser.py adaptive Schwelle aus a08df3d). Code-Post-Processing (researcher.py _extract_keywords): - Nach dem Parser werden Lagentitel-Woerter (>=4 Zeichen, nicht in Stopwords) ggf. in die Keyword-Liste injiziert, falls Haiku sie weggelassen hat. - Verhindert konkret den "Buckelwal timmy"-Bug: "timmy" fehlte in Haikus Liste, damit fielen Headlines mit nur "Buckelwal" durch das min_matches. Hintergrund: Memory-Eintrag rss_match_und_keyword_bug.md, Bug 2 von 3. Bug 1 (rss_parser min_matches adaptiv) ist seit Commit a08df3d auf Live. Bug 3 (international=True default) bleibt offen, ist primaer UX-Frage. --- src/agents/researcher.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/agents/researcher.py b/src/agents/researcher.py index ef5d4a8..76b25dc 100644 --- a/src/agents/researcher.py +++ b/src/agents/researcher.py @@ -199,14 +199,22 @@ AKTUELLE HEADLINES (die letzten Meldungen zu diesem Thema): AUFGABE: Generiere 5 Begriffspaare (DE + EN), mit denen neue RSS-Artikel zu diesem Thema gefunden werden. -Ein Artikel gilt als relevant, wenn mindestens 2 dieser Begriffe im Titel oder der Beschreibung vorkommen. +Ein Artikel gilt als relevant, wenn mindestens 2 dieser Begriffe im Titel oder der Beschreibung vorkommen +- bei spezifischen Begriffen (Eigennamen, lange Begriffe ab 7 Zeichen) reicht 1 Treffer. REGELN: -- Die ersten 2 Begriffspaare MUESSEN die zentralen Akteure/Laender/Themen sein (z.B. iran, israel, usa) — also die Begriffe, die in fast JEDEM Artikel zum Thema vorkommen -- Die letzten 3 Begriffspaare sind aktuelle Entwicklungen aus den Headlines (Orte, Akteure, Schluesselwoerter der aktuellen Phase) -- Begriffe muessen so gewaehlt sein, dass sie in kurzen RSS-Titeln matchen (einzelne Woerter, keine Phrasen) -- Alle Begriffe in Kleinbuchstaben -- Exakt 5 Begriffspaare +- ZWINGEND: Eigennamen oder spezifische Begriffe aus dem THEMA (z.B. Personennamen, Tiernamen, + Ortsnamen wie "timmy", "buckelwal", "merz", "dobrindt") MUESSEN als eigene Begriffspaare + enthalten sein. Solche Begriffe sind oft das einzige, was in kurzen Headlines vorkommt. +- Die ersten 2 Begriffspaare sind die zentralen Akteure/Laender/Themen (z.B. iran, israel, + buckelwal, timmy) — also die Begriffe, die in fast JEDEM Artikel zum Thema vorkommen. +- Die uebrigen 3 Begriffspaare sind aktuelle Entwicklungen aus den Headlines (Orte, Akteure, + Schluesselwoerter der aktuellen Phase). +- Wenn DE und EN identisch sind (Eigennamen), trotzdem das Paar einreichen. +- Begriffe muessen so gewaehlt sein, dass sie in kurzen RSS-Titeln matchen (einzelne Woerter, + keine Phrasen, keine Konjunktionen). +- Alle Begriffe in Kleinbuchstaben. +- Exakt 5 Begriffspaare. Antwort NUR als JSON-Array: [{{"de": "iran", "en": "iran"}}, {{"de": "israel", "en": "israel"}}, {{"de": "teheran", "en": "tehran"}}, {{"de": "luftangriff", "en": "airstrike"}}, {{"de": "trump", "en": "trump"}}]""" @@ -365,6 +373,17 @@ class ResearcherAgent: if en and en != de: keywords.append(en) + # Bug-2-Fallback: Lagentitel-Wörter (>=4 Zeichen) zwingend in Keyword-Liste, + # falls Haiku sie weggelassen hat. Verhindert "Buckelwal timmy"-Bug, bei dem + # der Eigenname "timmy" fehlte und damit Headlines mit nur "Buckelwal" durchfielen. + STOPWORDS = {"der", "die", "das", "und", "oder", "von", "vom", "zum", "zur", + "the", "and", "for", "with", "ueber", "über", "von", "for"} + for word in (title or "").lower().split(): + w = word.strip(".,;:!?\"\'()[]{}") + if len(w) >= 4 and w not in STOPWORDS and w not in keywords: + keywords.append(w) + logger.info(f"Lagentitel-Keyword '{w}' nachträglich injiziert") + if keywords: logger.info(f"Dynamische Keywords ({len(keywords)}): {keywords}") return keywords if keywords else None, usage