qwen_agent/agent/mem0_config.py
朱潮 fea6b35779 feat: 添加 PreMemoryPrompt hook 支持自定义记忆提取提示词
通过插件 hook 机制允许自定义 Mem0 的 FACT_RETRIEVAL_PROMPT,
包含联系人关系追踪和同姓消歧等增强能力。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:36:35 +08:00

150 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Mem0 配置数据类
用于管理 Mem0 长期记忆系统的配置参数
"""
from datetime import datetime
from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING, Optional
# 避免循环导入
if TYPE_CHECKING:
from langchain_core.language_models import BaseChatModel
# 缓存已加载的提示词模板
_fact_extraction_prompt_template: Optional[str] = None
def _load_fact_extraction_prompt() -> str:
"""从 prompt/FACT_RETRIEVAL_PROMPT.md 加载提示词模板
Returns:
str: 提示词模板内容
"""
global _fact_extraction_prompt_template
if _fact_extraction_prompt_template is not None:
return _fact_extraction_prompt_template
# 获取项目根目录(假设 prompt/ 在项目根目录下)
project_root = Path(__file__).parent.parent
prompt_file = project_root / "prompt" / "FACT_RETRIEVAL_PROMPT.md"
try:
_fact_extraction_prompt_template = prompt_file.read_text(encoding="utf-8")
except FileNotFoundError:
# 如果文件不存在,返回默认提示词
_fact_extraction_prompt_template = (
"Extract relevant facts about the user from the conversation.\n"
"Today's date is {current_time}.\n"
"Return response in JSON format: {\"facts\": [\"fact1\", \"fact2\"]}"
)
return _fact_extraction_prompt_template
@dataclass
class Mem0Config:
"""Mem0 长期记忆配置类"""
# 功能开关
enabled: bool = False
# 语义搜索配置
semantic_search_top_k: int = 20
memory_prompt_template: str = (
"\n\n=== 相关记忆 ===\n"
"以下是从历史对话中检索到的相关信息,可以帮助你更好地回答用户问题:\n"
"{memories}\n"
"==================\n"
)
# 多租户配置
user_id: Optional[str] = None # 用户标识
agent_id: Optional[str] = None # Bot 标识
session_id: Optional[str] = None # 会话标识
@property
def bot_id(self) -> str:
"""兼容 execute_hooks 所需的 bot_id 属性"""
return self.agent_id or ""
# LLM 实例(用于 Mem0 的记忆提取和增强)
llm_instance: Optional["BaseChatModel"] = None # LangChain LLM 实例
def get_attribution_tuple(self) -> tuple[str, str]:
"""获取 attribution 所需的元组 (user_id, agent_id)
Returns:
(user_id, agent_id) 元组
"""
if not self.user_id or not self.agent_id:
raise ValueError("user_id and agent_id are required for attribution")
return (self.user_id, self.agent_id)
def is_enabled(self) -> bool:
"""检查 Mem0 功能是否启用
Returns:
bool: 是否启用
"""
return self.enabled
def get_memory_prompt(self, memories: list[str]) -> str:
"""根据记忆列表生成注入提示词
Args:
memories: 记忆内容列表
Returns:
str: 格式化的记忆提示词
"""
if not memories:
return ""
memory_text = "\n".join(f"- {m}" for m in memories)
return self.memory_prompt_template.format(memories=memory_text)
def get_custom_fact_extraction_prompt(self) -> str:
"""获取自定义记忆提取提示词
从 prompt/FACT_RETRIEVAL_PROMPT.md 读取模板并替换 {current_time} 为当前日期
Returns:
str: 自定义记忆提取提示词
"""
template = _load_fact_extraction_prompt()
current_date = datetime.now().strftime("%Y-%m-%d")
return template.format(current_time=current_date)
async def get_custom_fact_extraction_prompt_async(self) -> str:
"""异步获取自定义记忆提取提示词(支持 PreMemoryPrompt hook 注入)
从 prompt/FACT_RETRIEVAL_PROMPT.md 读取默认模板,
然后执行 PreMemoryPrompt hooks如果 hook 返回内容则替换整个模板,
最后替换 {current_time} 为当前日期。
Returns:
str: 自定义记忆提取提示词
"""
from agent.plugin_hook_loader import execute_hooks
template = await execute_hooks('PreMemoryPrompt', self) or _load_fact_extraction_prompt()
return template.format(current_time=datetime.now().strftime("%Y-%m-%d"))
def with_session(self, session_id: str) -> "Mem0Config":
"""创建带有新 session_id 的配置副本
Args:
session_id: 新的会话 ID
Returns:
新的 Mem0Config 实例
"""
new_config = Mem0Config(**self.__dict__)
new_config.session_id = session_id
return new_config