mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-25 16:43:55 +08:00
perf:
1、优化工具调用相关提示词,拆分静态system-prompt和动态上下文。 2、新增few-shot示例,使用"调用→结果→回复"流程闭环,显著提高多次会话后工具调用准确性。 3、去除对话标题总结和记忆的模型思考模式。
This commit is contained in:
@@ -61,68 +61,6 @@ class Dialogue:
|
||||
else:
|
||||
self.put(Message(role="system", content=new_content))
|
||||
|
||||
def trim_history(self, max_turns: int = 10) -> int:
|
||||
"""
|
||||
智能截断对话历史,保留工具调用的完整性
|
||||
|
||||
Args:
|
||||
max_turns: 保留的最大对话轮数(每轮 = user + assistant/tool 相关消息)
|
||||
|
||||
Returns:
|
||||
int: 被移除的消息数量
|
||||
"""
|
||||
if len(self.dialogue) <= max_turns * 2 + 1: # +1 是系统消息
|
||||
return 0
|
||||
|
||||
# 分离系统消息和对话消息
|
||||
system_messages = [msg for msg in self.dialogue if msg.role == "system"]
|
||||
conversation_messages = [msg for msg in self.dialogue if msg.role != "system"]
|
||||
|
||||
if len(conversation_messages) <= max_turns * 2:
|
||||
return 0
|
||||
|
||||
# 智能截断:保留完整的工具调用链路
|
||||
keep_messages = []
|
||||
i = len(conversation_messages) - 1
|
||||
turn_count = 0
|
||||
|
||||
while i >= 0 and turn_count < max_turns:
|
||||
msg = conversation_messages[i]
|
||||
|
||||
# 从后向前收集消息
|
||||
if msg.role == "user":
|
||||
# 遇到 user 消息,说明一轮对话开始
|
||||
keep_messages.insert(0, msg)
|
||||
turn_count += 1
|
||||
i -= 1
|
||||
elif msg.role == "assistant":
|
||||
# 收集 assistant 消息
|
||||
keep_messages.insert(0, msg)
|
||||
|
||||
# 如果这个 assistant 有 tool_calls,需要收集对应的 tool 响应
|
||||
if msg.tool_calls is not None:
|
||||
i -= 1
|
||||
# 继续向后收集所有相关的 tool 消息
|
||||
while i >= 0 and conversation_messages[i].role == "tool":
|
||||
keep_messages.insert(0, conversation_messages[i])
|
||||
i -= 1
|
||||
else:
|
||||
i -= 1
|
||||
elif msg.role == "tool":
|
||||
# tool 消息应该已经被上面的逻辑收集了
|
||||
# 如果单独遇到,也要保留(防止边界情况)
|
||||
keep_messages.insert(0, msg)
|
||||
i -= 1
|
||||
else:
|
||||
i -= 1
|
||||
|
||||
removed_count = len(conversation_messages) - len(keep_messages)
|
||||
|
||||
# 重建对话列表
|
||||
self.dialogue = system_messages + keep_messages
|
||||
|
||||
return removed_count
|
||||
|
||||
def _ensure_tool_calls_complete(self, messages: List[Message]) -> List[Message]:
|
||||
"""
|
||||
确保所有 tool_calls 都有对应的 tool 响应
|
||||
@@ -167,7 +105,7 @@ class Dialogue:
|
||||
if system_message:
|
||||
# 以 <context> 为分界点,拆分静态 system prompt 和动态上下文
|
||||
# 静态部分(规则、身份等)保持不变,可命中前缀缓存
|
||||
# 动态部分(时间、天气、记忆等)放到对话末尾的 user 消息中
|
||||
# 动态部分(时间、天气、记忆等)作为第二条 system 消息,保持 system 权威性
|
||||
full_prompt = system_message.content
|
||||
context_match = re.search(r"<context>", full_prompt)
|
||||
if context_match:
|
||||
@@ -177,16 +115,18 @@ class Dialogue:
|
||||
static_part = full_prompt
|
||||
dynamic_part = ""
|
||||
|
||||
# 静态 system prompt:不含任何动态内容,前缀缓存可命中
|
||||
# 第一段:静态 system prompt(前缀缓存可命中)
|
||||
dialogue.append({"role": "system", "content": static_part})
|
||||
|
||||
# 添加用户和助手的对话
|
||||
# 第二段:few-shot 示例(会话内不变,也是缓存前缀的一部分)
|
||||
non_system_messages = [m for m in self.dialogue if m.role != "system"]
|
||||
complete_messages = self._ensure_tool_calls_complete(non_system_messages)
|
||||
for m in complete_messages:
|
||||
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)
|
||||
|
||||
# 动态上下文:时间、记忆、说话人信息,放到对话末尾的 user 消息中
|
||||
# 第三段:动态上下文 system prompt(时间、记忆、说话人等)
|
||||
# 保持 system 角色以确保模型权威性,不降级为 user
|
||||
if system_message and dynamic_part:
|
||||
# 替换时间占位符
|
||||
dynamic_part = dynamic_part.replace(
|
||||
@@ -222,6 +162,12 @@ class Dialogue:
|
||||
except:
|
||||
pass
|
||||
|
||||
dialogue.append({"role": "user", "content": dynamic_part})
|
||||
dialogue.append({"role": "system", "content": dynamic_part})
|
||||
|
||||
# 第四段:实际对话历史(不含 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:
|
||||
self.getMessages(m, dialogue)
|
||||
|
||||
return dialogue
|
||||
|
||||
Reference in New Issue
Block a user