fix(eu): drei Fehler beheben, die den Ertrag des Faktenchecks aufzehrten

Der Vergleichslauf zur Innenministerkonferenz (Lage 49) zeigte, dass der
verbesserte Faktencheck zwar zehn Fakten lieferte, davon aber nur drei
uebrig blieben. Die Ursachen lagen in drei nachgelagerten Stellen.

1. Quellenzuordnung stufte alle zehn Fakten herab.
   Durch den groesseren Belegblock stuetzt das Modell seine Fakten jetzt
   staerker auf die europaeische Suche als auf die gespeicherten Meldungen.
   Es zitiert dabei die Belegnummern statt vollstaendiger Adressen. Die
   Quellenzuordnung suchte daraufhin vergeblich nach passenden Meldungen und
   stufte jeden Fakt herab. Im Vergleich: Lauf 45 hatte null Herabstufungen,
   Lauf 44 eine, Lauf 49 zehn von zehn.
   Behoben an zwei Stellen. Die Belegsuche gibt die gefundenen Quellen jetzt
   einzeln zurueck, der Faktencheck reicht sie an die Zuordnung durch, und
   der Auftrag verlangt ausdruecklich die vollstaendige Adresse je Beleg.

2. Duplikatpruefung loeschte sieben von zehn Fakten.
   Das Clustering warf inhaltlich verschiedene Beschluesse in eine Gruppe,
   weil viele Behauptungen gleich beginnen. Es gab keinerlei Absicherung, bei
   kleinen Faktenmengen entschied das Modell sogar voellig allein.
   Zwei Sicherungen greifen jetzt. Eine Gruppe, die mehr als 40 Prozent aller
   Fakten umfasst, wird verworfen. Und jeder Loeschkandidat muss dem
   behaltenen Fakt auch rechnerisch aehnlich sein, Grenze 0,55 im selben Mass
   wie im Vorfilter. Beide Werte sind ueber Umgebungsvariablen einstellbar.

3. Leerrunden in der Recherche.
   War die Treffer-Obergrenze erreicht, brach nur die innere Schleife ab. Die
   Rundenschleife lief bis zum Ende weiter und befragte jedes Mal das teuerste
   Modell, ohne noch eine einzige Suche auszufuehren. Das kostete rund 0,17
   USD je Durchgang, bei drei Durchgaengen etwa 0,50 USD pro Aktualisierung.

Der Weg ueber die Anthropic-CLI bleibt unveraendert. Neu sind 16 Pruefungen,
darunter der nachgebildete Fall aus Lage 49, insgesamt laufen jetzt 80
Pruefungen ohne Netzzugriff und ohne Kosten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-08-01 13:26:32 +00:00
Ursprung c4e19777f9
Commit 0f39154e39
6 geänderte Dateien mit 413 neuen und 30 gelöschten Zeilen

Datei anzeigen

@@ -35,6 +35,13 @@ def pruefe(name, bedingung, extra=""):
aufrufe = {"such": [], "modell": []}
SUCHQUELLE = {
"headline": "Innenministerkonferenz beschliesst Fahrplan",
"source": "example.org",
"source_url": "https://example.org/a",
}
async def fake_plan(*, title, search_items, output_language="Deutsch",
max_queries=7, avoid_queries=None, label="Stuetzsuche"):
aufrufe["such"].append({
@@ -45,7 +52,7 @@ async def fake_plan(*, title, search_items, output_language="Deutsch",
})
u = ClaudeUsage(input_tokens=10, output_tokens=5, cost_usd=0.01)
block = "\n\nBELEGE [" + label + "]\n[S1] Beleg | example.org | https://example.org/a"
return block, u, [label + "-q1", label + "-q2"]
return eur.Belegsuche(block, u, [label + "-q1", label + "-q2"], [dict(SUCHQUELLE)])
antworten = []
@@ -240,5 +247,33 @@ asyncio.run(fc._eu_pruefen(
))
pruefe("I1 followup_queries=0 unterbindet die Nachrunde", len(aufrufe["such"]) == 1, len(aufrufe["such"]))
print("\nJ) Suchbelege zaehlen bei der Quellenzuordnung")
_ai_backend_var.set("bedrock")
neu()
# Behauptung, die zu KEINEM gespeicherten Artikel passt, wohl aber zur
# Suchquelle. Vor der Korrektur wurde so ein Fakt herabgestuft.
NUR_SUCHE = "Die Innenministerkonferenz beschliesst einen Fahrplan"
antworten.append(json_fakten([
(NUR_SUCHE, "established", "belegt durch die Suche"),
(F_GRENZE, "confirmed", "belegt"),
]))
facts_j, _ = asyncio.run(fc.check("Ceuta", ARTS, "research", "Deutsch"))
treffer_j = [f for f in facts_j if f["claim"].startswith("Die Innenministerkonferenz")]
pruefe("J1 Fakt allein aus der Suche bleibt belegt",
treffer_j and treffer_j[0]["status"] == "established",
[(f["claim"][:35], f["status"]) for f in facts_j])
pruefe("J2 Adresse der Suchquelle steht in der Evidenz",
treffer_j and "https://example.org/a" in treffer_j[0]["evidence"],
treffer_j[0]["evidence"][:160] if treffer_j else "")
print("\nK) Ohne Suchbelege bleibt die Zuordnung wie bisher")
_ai_backend_var.set("cli")
neu()
antworten.append(json_fakten([(NUR_SUCHE, "established", "belegt")]))
facts_k, _ = asyncio.run(fc.check("Ceuta", ARTS, "research", "Deutsch"))
pruefe("K1 CLI stuft ohne zuordenbare Quelle weiterhin herab",
facts_k and facts_k[0]["status"] != "established",
[(f["claim"][:35], f["status"]) for f in facts_k])
print("\nErgebnis: " + str(ok) + " bestanden, " + str(fail) + " fehlgeschlagen")
sys.exit(1 if fail else 0)