From 08aad935c943b5f9071d96b1effce05dda14b1fb Mon Sep 17 00:00:00 2001 From: Claude Dev Date: Thu, 12 Mar 2026 19:08:13 +0100 Subject: [PATCH] refactor: Quellen-Merge vom KI-Prompt in Python-Code verlagern Claude liefert bei der Analyse nur noch neue Quellen statt alle bisherigen zu wiederholen. Der Merge mit bestehenden Quellen passiert deterministisch im Code. Spart Tokens und verhindert das versehentliche Vergessen von Quellen. Co-Authored-By: Claude Opus 4.6 --- src/agents/analyzer.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/agents/analyzer.py b/src/agents/analyzer.py index 019c030..0d58051 100644 --- a/src/agents/analyzer.py +++ b/src/agents/analyzer.py @@ -135,12 +135,11 @@ REGELN: - KEINE Gedankenstriche (—, –) verwenden — stattdessen Kommas, Doppelpunkte oder neue Saetze - Bei widersprüchlichen Angaben beide Seiten erwähnen - Quellen immer mit [Nr] referenzieren -- Das sources-Array muss ALLE Quellen enthalten (bisherige + neue) - Ältere Quellen zeitlich einordnen Antworte AUSSCHLIESSLICH als JSON-Objekt mit diesen Feldern: - "summary": Aktualisierte Zusammenfassung mit Quellenverweisen [1], [2] etc. -- "sources": VOLLSTÄNDIGES Array aller Quellen (alte + neue), je: {{"nr": 1, "name": "Quellenname", "url": "https://..."}} +- "sources": Array mit NUR den NEUEN Quellen aus den neuen Meldungen, je: {{"nr": , "name": "Quellenname", "url": "https://..."}}. Alte Quellen werden automatisch gemerged. - "key_facts": Array aller aktuellen Kernfakten (in Ausgabesprache) - "translations": Array von Objekten mit "article_id", "headline_de", "content_de" (nur für neue fremdsprachige Artikel) @@ -180,12 +179,11 @@ REGELN: - Neue Erkenntnisse einarbeiten - Veraltete Informationen aktualisieren - Quellen immer mit [Nr] referenzieren -- Das sources-Array muss ALLE Quellen enthalten (bisherige + neue) - Markdown-Überschriften (##) für die Abschnitte verwenden Antworte AUSSCHLIESSLICH als JSON-Objekt mit diesen Feldern: - "summary": Das aktualisierte Briefing als Markdown-Text mit Quellenverweisen -- "sources": VOLLSTÄNDIGES Array aller Quellen (alte + neue), je: {{"nr": 1, "name": "Quellenname", "url": "https://..."}} +- "sources": Array mit NUR den NEUEN Quellen aus den neuen Meldungen, je: {{"nr": , "name": "Quellenname", "url": "https://..."}}. Alte Quellen werden automatisch gemerged. - "key_facts": Array aller gesicherten Kernfakten (in Ausgabesprache) - "translations": Array von Objekten mit "article_id", "headline_de", "content_de" (nur für neue fremdsprachige Artikel) @@ -263,13 +261,21 @@ class AnalyzerAgent: new_articles_text = self._format_articles_text(new_articles, max_articles=20) previous_sources_text = "Keine bisherigen Quellen" + self._all_previous_sources = [] if previous_sources_json: try: - sources = json.loads(previous_sources_json) - lines = [] - for s in sources: - lines.append(f"[{s.get('nr', '?')}] {s.get('name', '?')} — {s.get('url', '?')}") - previous_sources_text = "\n".join(lines) + self._all_previous_sources = json.loads(previous_sources_json) + total = len(self._all_previous_sources) + recent = self._all_previous_sources[-100:] if total > 100 else self._all_previous_sources + src_lines = [] + if total > 100: + highest_nr = self._all_previous_sources[-1].get("nr", "?") + src_lines.append(f"(... {total - 100} aeltere Quellen ausgelassen, hoechste Nr: {highest_nr})") + for s in recent: + nr = s.get("nr", "?") + name = s.get("name", "?") + src_lines.append(f"[{nr}] {name}") + previous_sources_text = chr(10).join(src_lines) except (json.JSONDecodeError, TypeError): previous_sources_text = "Fehler beim Laden der bisherigen Quellen" @@ -290,7 +296,19 @@ class AnalyzerAgent: try: result, usage = await call_claude(prompt) analysis = self._parse_response(result) - if analysis: + if analysis and self._all_previous_sources: + # Merge: alte Quellen beibehalten, neue hinzufuegen + returned_sources = analysis.get("sources", []) + returned_nrs = {s.get("nr") for s in returned_sources} + merged = [s for s in self._all_previous_sources if s.get("nr") not in returned_nrs] + merged.extend(returned_sources) + merged.sort(key=lambda s: s.get("nr", 0) if isinstance(s.get("nr"), int) else 9999) + analysis["sources"] = merged + logger.info( + f"Inkrementelle Analyse abgeschlossen: {len(new_articles)} neue Artikel, " + f"{len(analysis.get('sources', []))} Quellen gesamt (merged)" + ) + elif analysis: logger.info( f"Inkrementelle Analyse abgeschlossen: {len(new_articles)} neue Artikel, " f"{len(analysis.get('sources', []))} Quellen gesamt"