fix: 工具名过滤、消息拆分提示词优化
- filterActions: 过滤DeepSeek直接输出工具名(如vision_analyze)的怪话 - 系统提示词: 明确告知用双换行(空行)拆分多条消息 - 群聊规则: 加入独立想法用双换行分隔的说明
This commit is contained in:
@@ -250,7 +250,7 @@ func (s *Synthesizer) buildSynthesizeMessages(params SynthesizeParams) []model.L
|
|||||||
if params.ChannelType == "group" {
|
if params.ChannelType == "group" {
|
||||||
messages = append(messages, model.LLMMessage{
|
messages = append(messages, model.LLMMessage{
|
||||||
Role: model.RoleSystem,
|
Role: model.RoleSystem,
|
||||||
Content: "【群聊规则 — 必须严格遵守】\n1. 这是群聊,你正在和多人同时交流。只在有人@你、叫你名字、或话题直接涉及你时才回复。\n2. 每次回复最多1-2句话,不要长篇大论,不要连发多条消息。\n3. 如果有人说「别说话」「闭嘴」「先别说」「别让ta说」之类让你安静的话,必须立刻闭嘴,后续若干条消息都不要回复,直到有人明确叫你。\n4. 消息前缀 [群聊 群号] 昵称 (OBv11账号) 标注了真实发送者,请用当前发送者的名字称呼对方,不要混用之前对话中别人的称呼。",
|
Content: "【群聊规则 — 必须严格遵守】\n1. 这是群聊,你正在和多人同时交流。只在有人@你、叫你名字、或话题直接涉及你时才回复。\n2. 每次回复最多1-2句话,不要长篇大论。如需发送多个独立想法(例如道别+提醒吃饭),请用双换行隔开,每条独立成段。\n3. 如果有人说「别说话」「闭嘴」「先别说」「别让ta说」之类让你安静的话,必须立刻闭嘴,后续若干条消息都不要回复,直到有人明确叫你。\n4. 消息前缀 [群聊 群号] 昵称 (OBv11账号) 标注了真实发送者,请用当前发送者的名字称呼对方,不要混用之前对话中别人的称呼。",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ func (pc *PersonaConfig) buildConversationStyle() string {
|
|||||||
}
|
}
|
||||||
if cs.AllowMultiMessage {
|
if cs.AllowMultiMessage {
|
||||||
if cs.MultiMessageSeparator != "" {
|
if cs.MultiMessageSeparator != "" {
|
||||||
sb.WriteString("- 如果想说的事情比较多,用空行分隔成多条短消息\n")
|
sb.WriteString("- 如果回复包含多个独立的话题或语句(比如道别+提醒),请用两个换行(即一个空行)隔开成独立段落,每条段落将作为单独消息发送\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.WriteString("- 像 LINE 聊天一样,随意、亲切、有温度\n")
|
sb.WriteString("- 像 LINE 聊天一样,随意、亲切、有温度\n")
|
||||||
|
|||||||
@@ -960,7 +960,27 @@ func filterActions(text string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSpace(text)
|
// 过滤 LLM 直接输出工具名的情况(DeepSeek 有时不调用函数而是直接输出函数名)
|
||||||
|
text = strings.TrimSpace(text)
|
||||||
|
toolNames := []string{"vision_analyze", "video_analyze", "web_search", "web_fetch",
|
||||||
|
"iot_control", "iot_query", "host_exec", "os_exec", "knowledge_search"}
|
||||||
|
for _, name := range toolNames {
|
||||||
|
if text == name || strings.HasPrefix(text, name+"\n") || strings.HasPrefix(text, name+":") || strings.HasPrefix(text, name+":") {
|
||||||
|
text = strings.TrimPrefix(text, name)
|
||||||
|
text = strings.TrimSpace(text)
|
||||||
|
if text == "" {
|
||||||
|
return "" // 纯工具名,完全去掉
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 也处理 "vision_analyze\n..." 这种内嵌在第一行的情况
|
||||||
|
for _, name := range toolNames {
|
||||||
|
if strings.HasPrefix(text, name+" ") {
|
||||||
|
text = strings.TrimSpace(text[len(name):])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildMemoryNamespace creates a memory-isolated user_id for a platform channel.
|
// buildMemoryNamespace creates a memory-isolated user_id for a platform channel.
|
||||||
|
|||||||
@@ -309,7 +309,16 @@ func filterActions(text string) string {
|
|||||||
text = text[:start] + text[start+end+len(closeTag):]
|
text = text[:start] + text[start+end+len(closeTag):]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(text)
|
// 过滤 LLM 直接输出工具名的情况(DeepSeek 有时不调用函数而是直接输出函数名)
|
||||||
|
text = strings.TrimSpace(text)
|
||||||
|
toolNames := []string{"vision_analyze", "video_analyze", "web_search", "web_fetch",
|
||||||
|
"iot_control", "iot_query", "host_exec", "os_exec", "knowledge_search"}
|
||||||
|
for _, name := range toolNames {
|
||||||
|
if text == name || strings.HasPrefix(text, name+"\n") || strings.HasPrefix(text, name+":") || strings.HasPrefix(text, name+":") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertMarkdownPlain strips basic markdown formatting.
|
// convertMarkdownPlain strips basic markdown formatting.
|
||||||
|
|||||||
Reference in New Issue
Block a user