feat(search): deterministischer Backstop für heikle Kategorien
Schliesst die ~5-15 % Erst-Miss bei Fragen, deren veraltete Antwort
konfident-falsch waere (Amtstraeger, Wohnort lebender Personen, "lebt X noch").
- app/pipeline/search_backstop.py: should_force_search() erkennt solche
Phrasierungen per mehrsprachiger Regex (de/en/nl + etwas fr/es) mit
Gegenwarts-Schutz ("wer ist", nicht "wer war"). 22 Offline-Tests.
- ToolCallingLLM: bei Treffer wird die Suche DETERMINISTISCH erzwungen.
Wichtig: NICHT per tool_choice-Forcen (das honoriert das Modell nicht
zuverlaessig -> beobachtet: ignoriert, veraltete Antwort). Stattdessen
fuehrt der Wrapper die Suche selbst aus und speist das Ergebnis als
synthetischen Tool-Turn ein (_inject_forced_search). Metrik
search_forced_total. Filler/Geduld feuern auch hier.
- Haertung: _chat faengt non-JSON-200 ab (war ein Crash-/Hänger-Ausloeser,
betrifft auch Produktion).
Live verifiziert: "Wer ist Bundeskanzler?" sucht jetzt 3/3 -> Merz.
Tests: 312 gruen. Doc: §5.7.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
96dcd87ca8
commit
6cd6e783aa
4 changed files with 148 additions and 6 deletions
46
tests/test_search_backstop.py
Normal file
46
tests/test_search_backstop.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"""Offline-Tests für den deterministischen Such-Backstop (heikle Kategorien)."""
|
||||
import pytest
|
||||
|
||||
from app.pipeline.search_backstop import should_force_search
|
||||
|
||||
FORCE = [
|
||||
"Wer ist Bundeskanzler?",
|
||||
"Wer ist aktuell Bundeskanzler?",
|
||||
"Who is the president of the United States?",
|
||||
"Wie heißt der Papst?",
|
||||
"Wie is de huidige minister-president van Nederland?",
|
||||
"Wer ist gerade Papst?",
|
||||
"Wo wohnt Heino?",
|
||||
"Wo lebt Heino heute?",
|
||||
"Where does Madonna live these days?",
|
||||
"Waar woont André Rieu tegenwoordig?",
|
||||
"Lebt Heino noch?",
|
||||
"Is Brigitte Bardot still alive?",
|
||||
"Leeft Willeke Alberti nog?",
|
||||
]
|
||||
|
||||
NO_FORCE = [
|
||||
"Was ist die Hauptstadt von Frankreich?",
|
||||
"Erzähl mir einen Witz.",
|
||||
"Wie alt ist Heino?",
|
||||
"Wer war der erste Bundeskanzler?", # historisch (Vergangenheit)
|
||||
"Wann hat Heino Geburtstag?",
|
||||
"Wie geht es dir heute?",
|
||||
"Kannst du mir ein Rezept für Kartoffelsuppe geben?",
|
||||
"Wer hat den Faust geschrieben?",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text", FORCE)
|
||||
def test_forces_on_heikle_kategorien(text):
|
||||
assert should_force_search(text) is True, text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text", NO_FORCE)
|
||||
def test_no_force_on_harmless(text):
|
||||
assert should_force_search(text) is False, text
|
||||
|
||||
|
||||
def test_empty_and_none():
|
||||
assert should_force_search(None) is False
|
||||
assert should_force_search("") is False
|
||||
Loading…
Add table
Add a link
Reference in a new issue