From cb9d430cfce8f10c1c3420bb2d6d194b3fcc3bcd Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 5 Apr 2026 20:27:37 -0700 Subject: [PATCH] fix: skip system-injected user messages, only send real user query to Antaf The xiaozhi server injects tool_call reminders and system prompts as role=user messages into dialogue. These were being picked up as the "last user message" and sent to Antaf bridge instead of the actual query. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../core/providers/llm/antaf/antaf.py | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py b/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py index b8acd94..ddc6900 100644 --- a/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py +++ b/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py @@ -36,13 +36,33 @@ class LLMProvider(LLMProviderBase): return True return False + @staticmethod + def _is_system_injected(content): + """检测是否为系统注入的消息(非用户真实输入)""" + if not content: + return True + markers = [ + "[系统提示]", "tool_call", "", "TOOL USE", + "系统提示", "工具调用", "function_call", + "handle_exit_intent", "你有以下工具", "You have access", + ] + for m in markers: + if m in content: + return True + # 超过200字的 user 消息大概率是系统注入的 + if len(content) > 200: + return True + return False + def response(self, session_id, dialogue, **kwargs): - # 提取最后一条用户消息 + # 从 dialogue 中提取真正的用户消息(跳过系统注入的 user 消息) query = "" for msg in reversed(dialogue): if msg.get("role") == "user": - query = msg.get("content", "") - break + content = msg.get("content", "") + if not self._is_system_injected(content): + query = content + break if not query: logger.bind(tag=TAG).warning("对话中没有用户消息")