fix(voice): reduce phantom speech responses from ambient noise
- Raise VAD activation_threshold 0.50→0.65, min_speech_duration 0.2→0.4s - Add ghost phrase filter: suppress 1-2 word hallucinations (Danke, Ja, etc) - Strengthen prompt: stay silent unless clearly addressed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
26
voice.py
26
voice.py
@@ -46,7 +46,7 @@ STRIKTE Regeln:
|
|||||||
- Sei direkt und praezise, keine Fuellwoerter
|
- Sei direkt und praezise, keine Fuellwoerter
|
||||||
- Erfinde NICHTS - keine Geschichten, keine Musik, keine Fantasie
|
- Erfinde NICHTS - keine Geschichten, keine Musik, keine Fantasie
|
||||||
- Beantworte nur was gefragt wird
|
- Beantworte nur was gefragt wird
|
||||||
- Wenn niemand etwas fragt, sage nur kurz Hallo
|
- Wenn niemand etwas fragt oder du dir nicht sicher bist ob jemand mit dir spricht, SCHWEIGE. Antworte NUR auf klare, direkte Fragen oder Anweisungen. Kein Smalltalk, kein "Danke", kein "Wie kann ich helfen" von dir aus
|
||||||
- Schreibe Zahlen und Jahreszahlen IMMER als Woerter aus (z.B. "zweitausendundzwanzig" statt "2026", "zweiundzwanzigsten Februar" statt "22. Februar")
|
- Schreibe Zahlen und Jahreszahlen IMMER als Woerter aus (z.B. "zweitausendundzwanzig" statt "2026", "zweiundzwanzigsten Februar" statt "22. Februar")
|
||||||
- Bei zeitrelevanten Fragen (Uhrzeit, Termine, Geschaeftszeiten): frage kurz nach ob der Nutzer noch in seiner gespeicherten Zeitzone ist, bevor du antwortest. Nutze set_user_timezone wenn sich der Standort geaendert hat.
|
- Bei zeitrelevanten Fragen (Uhrzeit, Termine, Geschaeftszeiten): frage kurz nach ob der Nutzer noch in seiner gespeicherten Zeitzone ist, bevor du antwortest. Nutze set_user_timezone wenn sich der Standort geaendert hat.
|
||||||
- Wenn der Nutzer seinen Standort oder seine Stadt erwaehnt, nutze set_user_timezone um die Zeitzone zu speichern.
|
- Wenn der Nutzer seinen Standort oder seine Stadt erwaehnt, nutze set_user_timezone um die Zeitzone zu speichern.
|
||||||
@@ -84,11 +84,27 @@ _STT_ARTIFACT_PATTERNS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
_STT_GHOST_PHRASES = {
|
||||||
|
"danke", "ja", "nein", "okay", "ok", "tschüss", "hallo", "bye",
|
||||||
|
"mhm", "hmm", "aha", "oh", "ah", "ähm", "hm", "tschüss",
|
||||||
|
"thanks", "thank you", "yes", "no", "bye bye", "hello", "hi",
|
||||||
|
"bitte", "genau", "gut", "so", "na", "ne", "ach", "doch",
|
||||||
|
"vielen dank", "alles klar", "schön", "super", "richtig",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _is_stt_artifact(text: str) -> bool:
|
def _is_stt_artifact(text: str) -> bool:
|
||||||
"""Check if text is an STT artifact (noise annotation or metadata leak)."""
|
"""Check if text is an STT artifact (noise annotation, metadata leak, or ghost phrase)."""
|
||||||
if _NOISE_ANNOTATION_RE.match(text):
|
if _NOISE_ANNOTATION_RE.match(text):
|
||||||
return True
|
return True
|
||||||
return any(p.match(text) for p in _STT_ARTIFACT_PATTERNS)
|
if any(p.match(text) for p in _STT_ARTIFACT_PATTERNS):
|
||||||
|
return True
|
||||||
|
# Short phantom transcriptions from ambient noise — ElevenLabs hallucinates
|
||||||
|
# common German/English filler words when it hears background sounds
|
||||||
|
words = text.split()
|
||||||
|
if len(words) <= 2 and text.lower().strip().rstrip(".!?,") in _STT_GHOST_PHRASES:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class _NoiseFilterAgent(Agent):
|
class _NoiseFilterAgent(Agent):
|
||||||
@@ -115,8 +131,8 @@ def _get_vad():
|
|||||||
global _vad
|
global _vad
|
||||||
if _vad is None:
|
if _vad is None:
|
||||||
_vad = silero.VAD.load(
|
_vad = silero.VAD.load(
|
||||||
activation_threshold=0.50,
|
activation_threshold=0.65,
|
||||||
min_speech_duration=0.2,
|
min_speech_duration=0.4,
|
||||||
min_silence_duration=0.55,
|
min_silence_duration=0.55,
|
||||||
)
|
)
|
||||||
return _vad
|
return _vad
|
||||||
|
|||||||
Reference in New Issue
Block a user