From 2aa6c5ee4926b48a999226760b61c0654c4a5096 Mon Sep 17 00:00:00 2001 From: DaGou12138 <991623169@qq.com> Date: Fri, 10 Jul 2026 15:05:02 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=201.=E4=BC=98=E5=8C=96context?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=E6=96=B9=E5=BC=8F=EF=BC=8C=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E4=B8=BA=E4=B8=80=E4=B8=AAsystem=EF=BC=8C=E8=A7=A3=E5=86=B3qwe?= =?UTF-8?q?n=E6=9C=AC=E5=9C=B0=E9=83=A8=E7=BD=B2=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=A4=9Asystem=E5=BC=82=E5=B8=B8400=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/utils/dialogue.py | 49 ++++++++-------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/main/xiaozhi-server/core/utils/dialogue.py b/main/xiaozhi-server/core/utils/dialogue.py index 80b57158..ccc1e2c2 100644 --- a/main/xiaozhi-server/core/utils/dialogue.py +++ b/main/xiaozhi-server/core/utils/dialogue.py @@ -104,42 +104,19 @@ class Dialogue: ) if system_message: - # 以 为分界点,拆分静态 system prompt 和动态上下文 - # 静态部分(规则、身份等)保持不变,可命中前缀缓存 - # 动态部分(时间、天气、记忆等)作为第二条 system 消息,保持 system 权威性 full_prompt = system_message.content - context_match = re.search(r"", full_prompt) - if context_match: - static_part = full_prompt[:context_match.start()] - dynamic_part = full_prompt[context_match.start():] - else: - static_part = full_prompt - dynamic_part = "" - # 第一段:静态 system prompt(前缀缓存可命中) - dialogue.append({"role": "system", "content": static_part}) - - # 第二段:few-shot 示例(会话内不变,也是缓存前缀的一部分) - non_system_messages = [m for m in self.dialogue if m.role != "system"] - fewshot_messages = [m for m in non_system_messages if m.is_temporary] - complete_fewshot = self._ensure_tool_calls_complete(fewshot_messages) - for m in complete_fewshot: - self.getMessages(m, dialogue) - - # 第三段:动态上下文 system prompt(时间、记忆、说话人等) - # 保持 system 角色以确保模型权威性,不降级为 user - if system_message and dynamic_part: # 替换时间占位符 - dynamic_part = dynamic_part.replace( + full_prompt = full_prompt.replace( "{{current_time}}", datetime.now().strftime("%H:%M") ) # 填充记忆 if memory_str is not None: - dynamic_part = re.sub( + full_prompt = re.sub( r".*?", f"\n{memory_str}\n", - dynamic_part, + full_prompt, flags=re.DOTALL, ) @@ -150,8 +127,8 @@ class Dialogue: # 重复出现诱导模型反复称呼;后续轮不再注入身份,靠对话历史首轮保留 if current_speaker_name and current_speaker_name != "未知说话人": speakers = voiceprint_config.get("speakers", []) - dynamic_part += "\n" - dynamic_part += f"\n当前说话人:{current_speaker_name}" + speakers_info = "\n" + speakers_info += f"\n当前说话人:{current_speaker_name}" for speaker_str in speakers: try: parts = speaker_str.split(",", 2) @@ -160,16 +137,24 @@ class Dialogue: description = ( parts[2].strip() if len(parts) >= 3 else "" ) - dynamic_part += f"\n- {name}:{description}" + speakers_info += f"\n- {name}:{description}" except: pass - dynamic_part += "\n" + speakers_info += "\n" + full_prompt += speakers_info except: pass - dialogue.append({"role": "system", "content": dynamic_part}) + dialogue.append({"role": "system", "content": full_prompt}) - # 第四段:实际对话历史(不含 few-shot) + # 第二段:few-shot 示例(会话内不变) + non_system_messages = [m for m in self.dialogue if m.role != "system"] + fewshot_messages = [m for m in non_system_messages if m.is_temporary] + complete_fewshot = self._ensure_tool_calls_complete(fewshot_messages) + for m in complete_fewshot: + self.getMessages(m, dialogue) + + # 第三段:实际对话历史(不含 few-shot) actual_messages = [m for m in non_system_messages if not m.is_temporary] complete_actual = self._ensure_tool_calls_complete(actual_messages) for m in complete_actual: