tune xiaoniu reply brevity and flow thresholds

This commit is contained in:
liuwei
2026-04-07 11:36:02 +08:00
parent d616846098
commit 8476149a2d
5 changed files with 58 additions and 21 deletions
+37 -4
View File
@@ -248,6 +248,8 @@ class AIAutoResponsePlugin(MessagePluginInterface):
)
return False, "empty_response"
response = self._finalize_reply(response, reply_mode)
await bot.send_text_message(room_id, response, sender)
self.last_reply_at[room_id] = time.time()
self.flow_manager.note_bot_reply(room_id)
@@ -314,7 +316,7 @@ class AIAutoResponsePlugin(MessagePluginInterface):
return (current_ts - last_room_reply) >= room_cd
def _build_user_prompt(self, context: Dict, memory_hints: Dict) -> str:
recent_text = "\n".join(context.get("recent_messages", [])[-20:]) or "暂无"
recent_text = "\n".join(context.get("recent_messages", [])[-8:]) or "暂无"
reply_mode = context.get("reply_mode", "social_short")
length_rule = self._build_length_rule(reply_mode)
return (
@@ -333,6 +335,11 @@ class AIAutoResponsePlugin(MessagePluginInterface):
f"4. 如果信息不足,不要硬编。\n"
f"5. 输出最终可直接发到群里的内容,不要解释你的思路。\n"
f"6. {length_rule}\n"
f"7. 优先直接回应“当前发言”本身,不要被较早上下文带跑。\n"
f"8. 成员记忆和向量召回只有在与当前问题直接相关时才允许使用,否则忽略。\n"
f"9. 如果你不确定自己是否理解对了,就宁可不展开,只回很短。\n"
f"10. 把这次回复当作真人聊天里的第一反应,先只给第一层结论,不要主动补第二层解释。\n"
f"11. 如果一句话已经够了,就立刻停,不要为了完整而补充。\n"
)
@staticmethod
@@ -343,16 +350,42 @@ class AIAutoResponsePlugin(MessagePluginInterface):
response = re.sub(r"\n{3,}", "\n\n", response)
return response[:500].strip()
def _finalize_reply(self, response: str, reply_mode: str) -> str:
text = (response or "").strip()
if not text:
return ""
text = re.sub(r"\s+", " ", text)
text = text.replace("\n", " ").strip()
if reply_mode == "social_short":
text = self._take_first_sentence(text, 12)
elif reply_mode == "qa_fast":
text = self._take_first_sentence(text, 28)
elif reply_mode == "qa_with_context":
text = self._take_first_sentence(text, 36)
else:
text = self._take_first_sentence(text, 24)
return text.strip()
@staticmethod
def _build_length_rule(reply_mode: str) -> str:
if reply_mode == "social_short":
return "默认只回一句短话,最好控制在2到12个字,除非非常不自然。"
return "默认只回一句短话,最好控制在2到8个字,除非非常不自然。"
if reply_mode == "qa_fast":
return "尽量只回1句话,必要时最多2句,先给结论,不要展开成长教程"
return "尽量只回1句话,总长度优先控制在28字内,先给结论,不要主动补解释"
if reply_mode == "qa_with_context":
return "优先控制在1到2句,除非对方明显在等详细步骤"
return "优先控制在1句话,必要时最多2句,总长度优先控制在36字内,只给第一层答案"
return "尽量短,像群友临时接一句,不要长篇大论。"
@staticmethod
def _take_first_sentence(text: str, limit: int) -> str:
parts = re.split(r"(?<=[。!?!?;])", text)
first = parts[0].strip() if parts and parts[0].strip() else text.strip()
if len(first) <= limit:
return first
clipped = first[:limit].rstrip(",、;;:")
return clipped
def _sync_member_memory(self, room_id: str, sender: str, sender_name: str, member_context: Dict) -> None:
if not member_context: