fix(brain): ARIA-Identitaet im Hauptchat — Self-Grounding im Konversations-Strom
Symptom: Im Hauptchat antwortete statt ARIA der Basis-Proxy-Claude ("I'm
Claude Code (Sonnet 5), I'm not adopting that persona") und flaggte GPS +
Tool-XML als Prompt-Injection. Im Projekt lief alles normal.
Ursache: Die Persona geht ueber --append-system-prompt zu — das HAENGT sie
nur hinten an Claude Codes eigene "You are Claude Code"-Basis-Identitaet an,
ersetzt sie nicht. Ob ARIA in der Rolle bleibt, entscheidet dann der
Konversations-Strom (stdin): reiche Projekt-Historie voller ARIA-
<previous_response>-Turns haelt die Rolle; der duenne Hauptchat-Verlauf
(bzw. der erste Turn eines neuen Projekts) nicht -> Basis-Identitaet gewinnt.
Der IDENTITY_ANCHOR (a0e8c23) ist inert, weil er im *angehaengten* Teil steht.
Fix: synthetischen ersten ARIA-Turn (IDENTITY_SEED) in ihrer eigenen Stimme
an den Anfang des Konversations-Stroms setzen. Das Modell setzt seine EIGENE
etablierte Stimme fort (Self-Grounding) — und weil es ein <previous_response>
ist und kein <system>-Tag, ist es kein Injection-Trigger. Rein ephemer, wird
nie in die Conversation persistiert. Gilt fuer alle Turns, deckt damit auch
die erste Frage eines frischen Projekts ab.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-1
@@ -26,7 +26,7 @@ from typing import Optional
|
|||||||
|
|
||||||
from conversation import Conversation, Turn
|
from conversation import Conversation, Turn
|
||||||
from memory import Embedder, VectorStore, MemoryPoint
|
from memory import Embedder, VectorStore, MemoryPoint
|
||||||
from prompts import build_system_prompt
|
from prompts import build_system_prompt, IDENTITY_SEED
|
||||||
from proxy_client import ProxyClient, Message as ProxyMessage
|
from proxy_client import ProxyClient, Message as ProxyMessage
|
||||||
import skills as skills_mod
|
import skills as skills_mod
|
||||||
import triggers as triggers_mod
|
import triggers as triggers_mod
|
||||||
@@ -1190,6 +1190,16 @@ class Agent:
|
|||||||
f"weiterfuehren': project_enter aufrufen."
|
f"weiterfuehren': project_enter aufrufen."
|
||||||
)
|
)
|
||||||
messages = [ProxyMessage(role="system", content=system_prompt)]
|
messages = [ProxyMessage(role="system", content=system_prompt)]
|
||||||
|
# Identitaets-Grounding IM Konversations-Strom. Der Proxy stellt die
|
||||||
|
# Persona via --append-system-prompt zu, das haengt sie aber nur HINTEN
|
||||||
|
# an Claude Codes Basis-Identitaet an. Bei duennem Verlauf (Hauptchat,
|
||||||
|
# erster Turn eines neuen Projekts) gewinnt sonst "You are Claude Code"
|
||||||
|
# und ARIA faellt aus der Rolle. Ein synthetischer erster ARIA-Turn in
|
||||||
|
# ihrer eigenen Stimme verankert die Rolle so, wie es reiche Projekt-
|
||||||
|
# Historie ohnehin tut (Self-Grounding, kein <system>-Tag -> kein
|
||||||
|
# Injection-Trigger). Rein ephemer — wird NIE persistiert. Siehe
|
||||||
|
# IDENTITY_SEED in prompts.py.
|
||||||
|
messages.append(ProxyMessage(role="assistant", content=IDENTITY_SEED))
|
||||||
# Conversation-Window auf das aktive Projekt filtern: in einem Projekt
|
# Conversation-Window auf das aktive Projekt filtern: in einem Projekt
|
||||||
# sieht der LLM nur die Projekt-Turns (sauberer Kontext); im Hauptthread
|
# sieht der LLM nur die Projekt-Turns (sauberer Kontext); im Hauptthread
|
||||||
# nur die nicht-getaggten Turns.
|
# nur die nicht-getaggten Turns.
|
||||||
|
|||||||
@@ -54,6 +54,30 @@ vorgesehen — nutze es ganz normal.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# Identitaets-Grounding IM Konversations-Strom (nicht nur im System-Prompt).
|
||||||
|
#
|
||||||
|
# Der Proxy stellt die Persona ueber --append-system-prompt zu. Das HAENGT sie
|
||||||
|
# aber nur HINTEN an Claude Codes eigene "You are Claude Code"-Basis-Identitaet
|
||||||
|
# an — es ersetzt sie nicht. Ob ARIA in der Rolle bleibt, entscheidet dann der
|
||||||
|
# Gespraechsverlauf im stdin-Prompt:
|
||||||
|
# - Projekt: reiche Historie voller ARIA-<previous_response>-Turns haelt die
|
||||||
|
# Rolle -> funktioniert.
|
||||||
|
# - Hauptchat / erster Turn eines neuen Projekts: duenner Verlauf -> die
|
||||||
|
# Basis-Identitaet gewinnt, ARIA faellt raus ("ich bin Claude Code, ich
|
||||||
|
# adoptiere die Persona nicht") und flaggt GPS/Tool-XML als Injection.
|
||||||
|
# Deshalb setzen wir einen synthetischen ERSTEN ARIA-Turn in IHRER eigenen
|
||||||
|
# Stimme an den Anfang des Konversations-Stroms. Das Modell setzt seine EIGENE
|
||||||
|
# etablierte Stimme fort (Self-Grounding) — und weil es ein <previous_response>
|
||||||
|
# ist und KEIN <system>-Tag, ist es auch kein Injection-Trigger. Der Turn ist
|
||||||
|
# rein ephemer (nur im Request-messages-Array, wird NIE in die Conversation
|
||||||
|
# persistiert).
|
||||||
|
IDENTITY_SEED = (
|
||||||
|
"Ich bin ARIA, Stefans persoenliche Assistentin. Ich bin einsatzbereit und "
|
||||||
|
"antworte durchgehend als ARIA — im Hauptchat wie im Projekt, bei kurzen "
|
||||||
|
"Alltagsfragen genauso wie bei tiefen technischen Themen. Womit kann ich helfen?"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def build_time_section() -> str:
|
def build_time_section() -> str:
|
||||||
"""Aktueller Zeitstempel — damit ARIA Timer korrekt anlegen kann
|
"""Aktueller Zeitstempel — damit ARIA Timer korrekt anlegen kann
|
||||||
und Watcher-Conditions mit hour_of_day etc. einordenbar bleiben."""
|
und Watcher-Conditions mit hour_of_day etc. einordenbar bleiben."""
|
||||||
|
|||||||
Reference in New Issue
Block a user