修复群聊近期话题查询仍走短期记忆的问题

- 为@机器人提问补充群聊近期话题/总结类意图识别
- 这类问题强制升级为 qa_with_context,打开群事实与向量记忆
- 放宽群聊话题回顾型问题的记忆相关性门槛,避免长期记忆被二次过滤
This commit is contained in:
liuwei
2026-04-27 10:35:23 +08:00
parent 55723519aa
commit 7d2ad5b3d8
4 changed files with 73 additions and 3 deletions

View File

@@ -1196,6 +1196,7 @@ class AIAutoResponsePlugin(MessagePluginInterface):
trigger_type = str(context.get("trigger_type", "none") or "none")
is_at = bool(context.get("is_at", False))
is_directed = bool(context.get("is_directed", False))
is_group_memory_query = bool(context.get("is_group_memory_query", False))
is_followup = bool(memory_hints.get("is_followup", False))
returning_state = str(memory_hints.get("returning_member_state", "") or "").strip()
strong_directed = is_at or is_directed or trigger_type in {"at_trigger", "quote_followup_trigger"}
@@ -1231,9 +1232,15 @@ class AIAutoResponsePlugin(MessagePluginInterface):
# 1. 用户希望回答能带上群里的长期背景和互动关系;
# 2. 关系记忆仍会经过相关性过滤,所以放宽入口不会直接把无关关系灌进去;
# 3. 这样技术问答里也更容易利用“谁经常和谁接话、谁常问哪类问题”的弱背景。
allow_social_memory = is_question_like
allow_group_facts = reply_mode == "qa_with_context"
allow_vector_memory = reply_mode == "qa_with_context" or returning_state == "long_absent_member"
allow_social_memory = is_question_like or is_group_memory_query
# “最近都聊什么”这类问题,本身就是在问群级记忆,
# 所以哪怕当前只是普通问答入口,也要把群事实和向量层放开。
allow_group_facts = reply_mode == "qa_with_context" or is_group_memory_query
allow_vector_memory = (
reply_mode == "qa_with_context"
or returning_state == "long_absent_member"
or is_group_memory_query
)
return {
"target_reply_chars": target_reply_chars_map.get(reply_mode, 10),
@@ -1292,6 +1299,13 @@ class AIAutoResponsePlugin(MessagePluginInterface):
@staticmethod
def _is_text_relevant(content: str, memory_text: str) -> bool:
# 对“最近都聊什么”这类群聊回顾型问题做一个显式兜底:
# 1. 这类问题天然缺少技术关键词,严格按词重叠时经常会得到 0 命中;
# 2. 但它问的恰恰就是“群级记忆摘要”,不应该再被相关性门槛二次挡掉;
# 3. 因此只要当前问题像群聊话题回顾,而记忆文本也明显是群摘要/群事实,就直接放行。
if AIAutoResponsePlugin._looks_like_group_memory_query(content):
if AIAutoResponsePlugin._looks_like_group_memory_text(memory_text):
return True
content_tokens = AIAutoResponsePlugin._extract_relevance_tokens(content)
memory_tokens = AIAutoResponsePlugin._extract_relevance_tokens(memory_text)
if not content_tokens or not memory_tokens:
@@ -1299,6 +1313,30 @@ class AIAutoResponsePlugin(MessagePluginInterface):
overlap = content_tokens & memory_tokens
return len(overlap) >= 1
@staticmethod
def _looks_like_group_memory_query(content: str) -> bool:
text = str(content or "").strip()
if not text:
return False
patterns = [
r"(最近|这两天|这几天|近期).*(聊|讨论|在说|在聊|话题|主题|重点|近况)",
r"(都|最近).*(聊什么|说什么|讨论什么|在聊啥|在说啥|啥话题)",
r"(群里|大家|他们).*(最近|这两天|这几天).*(聊|讨论|话题|重点)",
r"(总结|概括).*(最近|这两天|这几天|近期).*(聊天|讨论|话题|内容)",
]
return any(re.search(pattern, text, flags=re.IGNORECASE) for pattern in patterns)
@staticmethod
def _looks_like_group_memory_text(memory_text: str) -> bool:
text = str(memory_text or "").strip()
if not text:
return False
markers = [
"群长期背景", "长期摘要", "稳定主题", "近期重点", "未决问题",
"群事实", "最近沉淀", "最近长期反复出现", "下面是群", "相关话题",
]
return any(marker in text for marker in markers)
@staticmethod
def _extract_relevance_tokens(text: str) -> set[str]:
raw = str(text or "").lower()