From a22f27bc60446ee50023bd70aaa8f32a7ef973de Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Thu, 16 Jul 2026 16:55:14 +0200 Subject: [PATCH] Gateway: No-Think-Schnellspur fuer Lucys Voice-Turns (Hirn-Latenz 6-21s -> <1s) Live-Diagnose 16.07.: Die 'Hirn'-Zeit der Voice-Turns (Dashboard 6,4-21,5s) war fast vollstaendig Qwen3.6-Reasoning VOR dem ersten sprechbaren Wort (reasoning_content 2500+ Zeichen bei ~100 t/s; /no_think-Softswitch wird ignoriert; Prefix-Cache war NICHT das Problem - live gemessen: Zeitstempel-Aenderung kostet nur ~0,8s). Fix: Lucy traegt Marker [[MC:NO_THINK]] im System-Prompt; das Gateway strippt ihn aus allen Messages (konstanter Text -> Prefix-Cache stabil) und setzt chat_template_kwargs enable_thinking:false. Direkt am Hirn gemessen: 9,9s -> 0,8s, Persona-Qualitaet unveraendert. Requests ohne Marker (Crons/Telegram/Werkstatt) denken unveraendert weiter. Abschaltbar via MC_NO_THINK_MARKER="". Co-Authored-By: Claude Fable 5 --- backend/routers/gateway_proxy.py | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/backend/routers/gateway_proxy.py b/backend/routers/gateway_proxy.py index 25d4ed8..e037501 100644 --- a/backend/routers/gateway_proxy.py +++ b/backend/routers/gateway_proxy.py @@ -33,6 +33,38 @@ _BILD_BESCHREIB_PROMPT = os.environ.get( "Sichtbaren Code und Fehlermeldungen gib WOERTLICH wieder.") +# Lucy-Voice-Schnellspur (16.07.): Lucys Sprach-Turns tragen diesen Marker im System-Prompt. +# Er schaltet das Qwen-Denken für GENAU diese Requests ab (gemessen direkt am Hirn: 9,9 s -> 0,8 s +# bis zur Antwort; reasoning_content 2500 Zeichen -> 0) — die „Hirn"-Latenz der Voice-Turns war +# fast vollständig Reasoning-Generierung VOR dem ersten sprechbaren Wort. Der Marker wird VOR dem +# Modell aus allen Messages entfernt (konstanter Text -> Prefix-Cache bleibt stabil). Requests ohne +# Marker (Crons, Telegram, Werkstatt) bleiben unangetastet. Leerer Env-Wert schaltet die Spur ab. +_NO_THINK_MARKER = os.environ.get("MC_NO_THINK_MARKER", "[[MC:NO_THINK]]") + + +def _apply_no_think_marker(body: dict) -> None: + """Marker aus allen Message-Inhalten strippen; war er da, Thinking abschalten + (sofern der Client chat_template_kwargs nicht selbst gesetzt hat).""" + if not _NO_THINK_MARKER: + return + found = False + for m in body.get("messages") or []: + if not isinstance(m, dict): + continue + c = m.get("content") + if isinstance(c, str) and _NO_THINK_MARKER in c: + m["content"] = c.replace(_NO_THINK_MARKER, "").strip() + found = True + elif isinstance(c, list): + for part in c: + if (isinstance(part, dict) and isinstance(part.get("text"), str) + and _NO_THINK_MARKER in part["text"]): + part["text"] = part["text"].replace(_NO_THINK_MARKER, "").strip() + found = True + if found and "chat_template_kwargs" not in body: + body["chat_template_kwargs"] = {"enable_thinking": False} + + def _ist_coder_alias(alias: str) -> bool: """Coder-Ziele (coder, rohe Qwen-Coder-IDs) bekommen Bild-BESCHREIBUNGEN statt der stumpfen Vision-Umleitung — die Code-Frage bleibt beim Spezialisten.""" @@ -158,6 +190,7 @@ async def models(request: Request): async def _proxy(path: str, request: Request): body = await request.json() + _apply_no_think_marker(body) # Lucy-Voice-Schnellspur: Marker strippen + Thinking aus requested = str(body.get("model") or "auto") if requested.lower() in ("auto", "chat", "coding"): lane = requested.lower()