revert(router): Live-Wortliste raus — Modell soll selbst eskalieren

_LIVE_HINTS war die falsche Idee: aus offenem Freitext per Wortliste die
Absicht raten ist nie vollstaendig, jeder Miss = Halo (nur von per-Skill auf
per-Wort verschoben). Generisch heisst nicht 'groessere Regex', sondern: das
Modell entscheidet selbst ob es Grundwahrheit/ein Tool braucht (<<ESCALATE>>,
Prompt). Der 8B kann das noch nicht zuverlaessig → local bleibt per Einstellung
abschaltbar (aus, nicht raus); ein staerkeres lokales Modell uebernimmt spaeter
die Selbst-Erkennung. Absicherung bleibt der Output-Guard, nicht der Input.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 00:20:02 +02:00
co-authored by Claude Opus 4.8
parent fc13957000
commit 44220edbd1
2 changed files with 14 additions and 23 deletions
+5 -2
View File
@@ -1423,8 +1423,11 @@ class Agent:
# er lieber eine plausible Antwort ('der Song ist X'), statt das Tool zu
# rufen — das war die Halo-Quelle UND zwang zu per-Skill-Guards. Ohne
# Tools KANN er kein Skill-Ergebnis faelschen. Alles mit Grundwahrheit
# (Fakt/Live-Zustand/Gedaechtnis/Aktion) gehoert an Claude (Router-Gate
# vorab) oder an den deterministischen Fast-Path — nicht an den 8B.
# (Fakt/Live-Zustand/Gedaechtnis/Aktion) gehoert an Claude oder an den
# deterministischen Fast-Path — nicht an den 8B. WIE es dorthin kommt:
# das Modell eskaliert SELBST (<<ESCALATE>>, siehe Prompt) — bewusst KEINE
# Input-Wortliste im Router. Der Output-Guard unten faengt ab, wenn der
# 8B doch mal statt zu eskalieren einen Live-Zustand behauptet.
tools = []
sys_prompt = router_mod.build_local_system_prompt(IDENTITY_ANCHOR,
+9 -21
View File
@@ -75,25 +75,15 @@ _TOOL_HINTS = re.compile(
re.IGNORECASE,
)
# LIVE-/DYNAMISCH-Marker → Claude. Seit dem B1a-Rueckbau ist local TOOL-LOS
# (nur Reden), kann also nichts nachschlagen. Alles was aktuelle Grundwahrheit
# braucht — Wetter, News, Uhrzeit/Datum, Musik-/Spotify-Zustand, Preise/Kurse,
# Verkehr, Oeffnungszeiten — kann ein 8B nicht wissen und wuerde es erfinden.
# Darum vorab an Claude (der ruft das Tool). Das ist TOPIC-Ebene, nicht per-Skill:
# ein neuer Skill braucht hier keine Zeile — er faellt unter „braucht Grundwahrheit".
_LIVE_HINTS = re.compile(
r"\b(wetter|temperatur|regne\w*|schneit|grad draussen|"
r"news|nachrichten|schlagzeile\w*|"
r"uhrzeit|wie spaet|wie spät|welcher tag|welches datum|wochentag|"
r"spotify|musik|lied\w*|song\w*|playlist|lautstaerke|lautstärke|"
r"laeuft gerade|läuft gerade|spiele? (ab|weiter|die|den|das)|naechst\w*|nächst\w*|"
r"ueberspring\w*|überspring\w*|spring\w* .*weiter|skip\w*|pausier\w*|"
r"timer|wecker|weck mich|erinner\w*|"
r"preis|kurs|aktie|wechselkurs|bitcoin|"
r"stau|verkehr|zugverbindung|bahn|abfahrt|"
r"oeffnungszeit\w*|öffnungszeit\w*|geoeffnet|geöffnet|hat .* auf)\b",
re.IGNORECASE,
)
# HINWEIS (bewusst KEINE Live-/Topic-Wortliste mehr): frueher stand hier ein
# _LIVE_HINTS-Blacklist (Wetter/Musik/Uhrzeit/… → Claude). Das war die falsche
# Idee — aus offenem Freitext die Absicht per Wortliste zu erraten ist NIE
# vollstaendig, jeder Miss = ein Halo. Die generische Loesung ist keine groessere
# Regex, sondern: das Modell entscheidet selbst („brauche ich Grundwahrheit/ein
# Tool? → <<ESCALATE>>", siehe build_local_system_prompt). Ein 8B kann das noch
# nicht zuverlaessig → local bleibt per Einstellung abschaltbar; ein staerkeres
# lokales Modell uebernimmt spaeter genau diese Selbst-Erkennung. Absicherung ist
# der Output-Guard in agent.py, nicht eine Input-Wortliste.
# Technik-/Tiefe-Marker → Claude (lokales 8B soll das nicht raten).
_HARD_HINTS = re.compile(
@@ -146,8 +136,6 @@ def should_try_local(user_message: str, cfg: dict) -> bool:
return False
if _TOOL_HINTS.search(msg):
return False
if _LIVE_HINTS.search(msg):
return False
if _HARD_HINTS.search(msg):
return False
return True