From 1e754910ee1d910eeb2cbe95a6dde9a094977175 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Wed, 13 May 2026 02:13:32 +0200 Subject: [PATCH] =?UTF-8?q?fix(brain):=20Cold=20Memory=20mit=20Score-Thres?= =?UTF-8?q?hold=20=E2=80=94=20kein=20Crosstalk=20mehr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: Agent.chat() rief store.search() OHNE score_threshold — die Top-5 wurden ungefiltert in den 'Moeglicherweise relevant'-Block des System-Prompts gepackt. Bei kleiner DB hatte das absurde Folgen: Stefan fragte 'hab ich ein flugzeug?', Cold-Search lieferte Top-1 'Watcher-Latenzproblem' mit Score 0.138 + 'Firmenadresse' mit 0.094, ARIA wob die Firmenadresse in die Antwort ein ('Die Adresse habe ich aus meinem Gedaechtnis...') — obwohl der User gar nicht danach gefragt hat. Fix: Konstante COLD_SCORE_THRESHOLD=0.30 in Agent eingefuehrt und an store.search() durchgereicht. Treffer unter 0.30 werden als Rauschen verworfen, ARIA bekommt nur substantielle Memories ins Cold-Set. Konsistent mit dem Threshold im /memory/search HTTP-Endpoint und dem Diagnostic UI. MiniLM-multilingual gibt fuer unverwandte deutsche Texte gerne 0.10- 0.25 Score — alles darunter ist Embedder-Noise, kein echter Bezug. Co-Authored-By: Claude Opus 4.7 (1M context) --- aria-brain/agent.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/aria-brain/agent.py b/aria-brain/agent.py index e451638..c8046d8 100644 --- a/aria-brain/agent.py +++ b/aria-brain/agent.py @@ -280,6 +280,14 @@ def _skill_to_tool(s: dict) -> dict: class Agent: + # Mindest-Score den ein Cold-Memory-Treffer haben muss um in den + # System-Prompt aufgenommen zu werden. Unter dieser Schwelle ist's + # Rauschen — die MiniLM-multilingual Embeddings haben fuer "irgendwas + # vs. irgendwas anderes" gerne mal 0.10-0.20 Score selbst bei voellig + # unverwandten Inhalten. Mit 0.30 als Untergrenze vermeiden wir + # Cross-Talk (z.B. 'hab ich ein flugzeug' triggert die Firmenadresse). + COLD_SCORE_THRESHOLD = 0.30 + def __init__(self, store: VectorStore, embedder: Embedder, conversation: Conversation, proxy: ProxyClient, cold_k: int = 5): @@ -317,10 +325,13 @@ class Agent: # 2. Hot Memory (alle pinned Punkte) hot = self.store.list_pinned() - # 3. Cold Memory (Top-K semantic) + # 3. Cold Memory (Top-K semantic) — mit Score-Threshold gegen Rauschen try: qvec = self.embedder.embed(user_message) - cold = self.store.search(qvec, k=self.cold_k, exclude_pinned=True) + cold = self.store.search( + qvec, k=self.cold_k, exclude_pinned=True, + score_threshold=self.COLD_SCORE_THRESHOLD, + ) except Exception as exc: logger.warning("Cold-Search fehlgeschlagen: %s", exc) cold = []