增加常驻群长期记忆与成员轻画像输入
This commit is contained in:
@@ -72,8 +72,14 @@ default_char_limit = 30
|
||||
default_total_limit = 30
|
||||
|
||||
[prompt_compact]
|
||||
group_profile_max_chars = 220
|
||||
group_profile_max_lines = 6
|
||||
# 这里改成“常驻轻背景 + 相关增强”后,群长期摘要和成员轻画像都会稳定带给模型:
|
||||
# 1. group_profile 放宽,让群长期摘要不会总被前面的模式/知识域说明挤掉;
|
||||
# 2. member_profile_brief_* 新增为常驻轻画像额度,每次都给当前发言人一小段稳定画像;
|
||||
# 3. 更重的成员记忆、群事实、向量记忆仍然保留独立额度,并继续走按需增强。
|
||||
group_profile_max_chars = 420
|
||||
group_profile_max_lines = 10
|
||||
member_profile_brief_max_chars = 260
|
||||
member_profile_brief_max_lines = 6
|
||||
# 最近上下文现在要真实交给模型 30 条,因此这里同步放宽整体上下文裁剪阈值:
|
||||
# 1. recent_message_max_lines 提到 30,避免“窗口明明有 30,提示词里只留下 4 条”;
|
||||
# 2. context_max_lines/context_max_chars 一起抬高,避免最近消息刚拼进去又被整体截断;
|
||||
@@ -86,8 +92,8 @@ at_member_profile_max_chars = 160
|
||||
at_member_profile_max_lines = 5
|
||||
member_memory_max_chars = 180
|
||||
member_memory_max_lines = 6
|
||||
memory_max_chars = 240
|
||||
memory_max_lines = 8
|
||||
memory_max_chars = 520
|
||||
memory_max_lines = 14
|
||||
strict_memory_relevance = true
|
||||
|
||||
[image]
|
||||
|
||||
@@ -59,6 +59,7 @@ class ContextBuilder:
|
||||
"trigger_type": trigger.get("trigger_type", "none"),
|
||||
"reply_mode": reply_mode,
|
||||
"flow_state": flow_state,
|
||||
"member_profile_brief_prompt": self._build_member_profile_brief_prompt(member_context or {}),
|
||||
"memory_prompt": self._build_member_memory_prompt(member_context, member_memory_focus or []),
|
||||
"at_member_profile_prompt": self._build_at_member_profile_prompt(
|
||||
member_context=member_context or {},
|
||||
@@ -69,6 +70,7 @@ class ContextBuilder:
|
||||
"vector_memory_prompt": self._build_vector_memory_prompt(vector_memories),
|
||||
"social_memory_prompt": self._build_social_memory_prompt(social_memory or {}),
|
||||
"group_facts_prompt": self._build_group_facts_prompt(group_facts or {}),
|
||||
"group_long_memory_prompt": self._build_group_long_memory_prompt(group_profile or {}),
|
||||
"group_profile_prompt": self._build_group_profile_prompt(group_profile or {}),
|
||||
"quote_prompt": self._build_quote_prompt(quote_context or {}),
|
||||
"image_prompt": self._build_image_prompt(image_context or {}),
|
||||
@@ -207,6 +209,35 @@ class ContextBuilder:
|
||||
text = re.sub(r"[^\u4e00-\u9fffA-Za-z0-9_]", "", text)
|
||||
return text[:8]
|
||||
|
||||
@staticmethod
|
||||
def _build_member_profile_brief_prompt(member_context: Dict) -> str:
|
||||
# 这份摘要是“常驻给模型看的轻画像”:
|
||||
# 1. 不要求当前一定是 @ 或强定向,因为用户希望每次回答都能带上对这个人的基本认识;
|
||||
# 2. 这里只保留少量稳定信息,避免画像太重把当前问题压住;
|
||||
# 3. 更细的成员记忆、近期相关记忆,仍走后面的按需增强链路。
|
||||
if not member_context:
|
||||
return ""
|
||||
meta = member_context.get("meta", {}) or {}
|
||||
summary = str(member_context.get("summary_text", "") or "").strip()
|
||||
interaction_style = str(member_context.get("interaction_style", "") or "").strip()
|
||||
response_hint = str(member_context.get("response_style_hint", "") or "").strip()
|
||||
topics = ContextBuilder._stringify_items(member_context.get("topics_of_interest", []) or [], 3)
|
||||
recent_focus = ContextBuilder._stringify_items(member_context.get("recent_focus", []) or [], 2)
|
||||
skills = ContextBuilder._stringify_items(meta.get("skill_profile", []) or [], 2)
|
||||
reply_prefs = ContextBuilder._stringify_items(meta.get("long_term_reply_preferences", []) or [], 2)
|
||||
lines = [
|
||||
"当前发言人轻画像:",
|
||||
f"成员摘要:{summary}" if summary else "",
|
||||
f"互动风格:{interaction_style}" if interaction_style else "",
|
||||
f"偏好回复方式:{response_hint}" if response_hint else "",
|
||||
f"长期兴趣:{topics}" if topics else "",
|
||||
f"近期关注:{recent_focus}" if recent_focus else "",
|
||||
f"技能侧重点:{skills}" if skills else "",
|
||||
f"回复偏好:{reply_prefs}" if reply_prefs else "",
|
||||
"这些信息只用于帮助理解提问方式和回答切口,不要像在背档案。",
|
||||
]
|
||||
return "\n".join([line for line in lines if line])
|
||||
|
||||
@staticmethod
|
||||
def _build_member_memory_prompt(member_context: Dict, focus_lines: List[str] | None = None) -> str:
|
||||
if not member_context:
|
||||
@@ -320,6 +351,25 @@ class ContextBuilder:
|
||||
def _build_group_facts_prompt(group_facts: Dict) -> str:
|
||||
return str((group_facts or {}).get("prompt", "") or "").strip()
|
||||
|
||||
@staticmethod
|
||||
def _build_group_long_memory_prompt(group_profile: Dict) -> str:
|
||||
# 这份摘要是“群长期背景常驻层”:
|
||||
# 1. 每次都给一小段,帮助模型知道这个群长期在聊什么、什么风格更合适;
|
||||
# 2. 不把完整群画像整段塞进去,避免大量通用风格描述把 token 吃满;
|
||||
# 3. 更细的群事实、群关系仍走相关性增强链路。
|
||||
if not group_profile:
|
||||
return ""
|
||||
summary = ContextBuilder._compact_group_summary(str(group_profile.get("group_memory_summary", "") or ""), max_chars=220, max_sentences=4)
|
||||
focus = ", ".join(group_profile.get("knowledge_focus", [])[:4])
|
||||
memory_style = ContextBuilder._build_style_summary(group_profile.get("group_memory_style", {}))
|
||||
lines = [
|
||||
"群长期背景:",
|
||||
f"长期摘要:{summary}" if summary else "",
|
||||
f"常聊方向:{focus}" if focus else "",
|
||||
f"历史社交风格:{memory_style}" if memory_style else "",
|
||||
]
|
||||
return "\n".join([line for line in lines if line])
|
||||
|
||||
@staticmethod
|
||||
def _build_group_profile_prompt(group_profile: Dict) -> str:
|
||||
if not group_profile:
|
||||
|
||||
@@ -911,8 +911,12 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
||||
memory_hints=memory_hints,
|
||||
)
|
||||
persona = self._compose_dify_persona_text(group_profile, context)
|
||||
group_profile_parts = [
|
||||
self._string_block("群长期记忆(常驻)", context.get("group_long_memory_prompt", "")),
|
||||
self._string_block("群当前画像", context.get("group_profile_prompt", "")),
|
||||
]
|
||||
group_profile_text = self._compact_text(
|
||||
str(context.get("group_profile_prompt", "") or "").strip() or "当前群没有特殊画像。",
|
||||
"\n\n".join([part for part in group_profile_parts if part]).strip() or "当前群没有特殊画像。",
|
||||
max_chars=int(self.prompt_compact_config.get("group_profile_max_chars", 220) or 220),
|
||||
max_lines=int(self.prompt_compact_config.get("group_profile_max_lines", 6) or 6),
|
||||
)
|
||||
@@ -945,6 +949,14 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
||||
max_lines=int(self.prompt_compact_config.get("context_max_lines", 10) or 10),
|
||||
)
|
||||
|
||||
# 成员画像拆成两层:
|
||||
# 1. 常驻轻画像:每次都带,帮助模型理解这个人的提问方式、风格和切口;
|
||||
# 2. 定向增强画像:只有明确 @ / 强定向 / followup 时再额外补,避免平时过度套人设。
|
||||
member_profile_brief_text = self._compact_text(
|
||||
str(context.get("member_profile_brief_prompt", "") or ""),
|
||||
max_chars=int(self.prompt_compact_config.get("member_profile_brief_max_chars", 260) or 260),
|
||||
max_lines=int(self.prompt_compact_config.get("member_profile_brief_max_lines", 6) or 6),
|
||||
)
|
||||
at_member_profile_text = ""
|
||||
if bool(prompt_strategy.get("allow_member_memory")):
|
||||
at_member_profile_text = self._compact_text(
|
||||
@@ -962,6 +974,7 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
||||
member_memory_text = self._remove_overlap_lines(member_memory_text, at_member_profile_text)
|
||||
|
||||
memory_parts = [
|
||||
self._string_block("当前发言人画像(常驻)", member_profile_brief_text),
|
||||
self._string_block("本次@发起者画像(优先)", at_member_profile_text),
|
||||
self._string_block("成员记忆", member_memory_text),
|
||||
self._string_block(
|
||||
@@ -1214,7 +1227,11 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
||||
}
|
||||
|
||||
allow_member_memory = strong_directed or is_followup or returning_state in {"returning_member", "long_absent_member"}
|
||||
allow_social_memory = is_question_like and strong_directed
|
||||
# 群关系记忆继续按需开放,但问答模式下不再必须“强定向”才允许:
|
||||
# 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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user