11import os
22import json
3- from utils import OpenAIClient , get_timestamp , generate_id , gpt_user_profile_analysis , gpt_knowledge_extraction , gpt_update_profile , ensure_directory_exists
4-
5- import prompts
6- from short_term import ShortTermMemory
7- from mid_term import MidTermMemory , compute_segment_heat # For H_THRESHOLD logic
8- from long_term import LongTermMemory
9- from updater import Updater
10- from retriever import Retriever
3+ from concurrent .futures import ThreadPoolExecutor , as_completed
4+
5+ # 修改为绝对导入
6+ try :
7+ # 尝试相对导入(当作为包使用时)
8+ from .utils import OpenAIClient , get_timestamp , generate_id , gpt_user_profile_analysis , gpt_knowledge_extraction , ensure_directory_exists
9+ from . import prompts
10+ from .short_term import ShortTermMemory
11+ from .mid_term import MidTermMemory , compute_segment_heat # For H_THRESHOLD logic
12+ from .long_term import LongTermMemory
13+ from .updater import Updater
14+ from .retriever import Retriever
15+ except ImportError :
16+ # 回退到绝对导入(当作为独立模块使用时)
17+ from utils import OpenAIClient , get_timestamp , generate_id , gpt_user_profile_analysis , gpt_knowledge_extraction , ensure_directory_exists
18+ import prompts
19+ from short_term import ShortTermMemory
20+ from mid_term import MidTermMemory , compute_segment_heat # For H_THRESHOLD logic
21+ from long_term import LongTermMemory
22+ from updater import Updater
23+ from retriever import Retriever
1124
1225# Heat threshold for triggering profile/knowledge update from mid-term memory
1326H_PROFILE_UPDATE_THRESHOLD = 5.0
@@ -24,15 +37,32 @@ def __init__(self, user_id: str,
2437 long_term_knowledge_capacity = 100 ,
2538 retrieval_queue_capacity = 7 ,
2639 mid_term_heat_threshold = H_PROFILE_UPDATE_THRESHOLD ,
27- llm_model = "gpt-4o-mini" # Unified model for all LLM operations
40+ mid_term_similarity_threshold = 0.6 ,
41+ llm_model = "gpt-4o-mini" ,
42+ embedding_model_name : str = "all-MiniLM-L6-v2" ,
43+ embedding_model_kwargs : dict = None
2844 ):
2945 self .user_id = user_id
3046 self .assistant_id = assistant_id
3147 self .data_storage_path = os .path .abspath (data_storage_path )
3248 self .llm_model = llm_model
49+ self .mid_term_similarity_threshold = mid_term_similarity_threshold
50+ self .embedding_model_name = embedding_model_name
51+
52+ # Smart defaults for embedding_model_kwargs
53+ if embedding_model_kwargs is None :
54+ if 'bge-m3' in self .embedding_model_name .lower ():
55+ print ("INFO: Detected bge-m3 model, defaulting embedding_model_kwargs to {'use_fp16': True}" )
56+ self .embedding_model_kwargs = {'use_fp16' : True }
57+ else :
58+ self .embedding_model_kwargs = {}
59+ else :
60+ self .embedding_model_kwargs = embedding_model_kwargs
61+
3362
3463 print (f"Initializing Memoryos for user '{ self .user_id } ' and assistant '{ self .assistant_id } '. Data path: { self .data_storage_path } " )
3564 print (f"Using unified LLM model: { self .llm_model } " )
65+ print (f"Using embedding model: { self .embedding_model_name } with kwargs: { self .embedding_model_kwargs } " )
3666
3767 # Initialize OpenAI Client
3868 self .client = OpenAIClient (api_key = openai_api_key , base_url = openai_base_url )
@@ -55,17 +85,34 @@ def __init__(self, user_id: str,
5585
5686 # Initialize Memory Modules for User
5787 self .short_term_memory = ShortTermMemory (file_path = user_short_term_path , max_capacity = short_term_capacity )
58- self .mid_term_memory = MidTermMemory (file_path = user_mid_term_path , client = self .client , max_capacity = mid_term_capacity )
59- self .user_long_term_memory = LongTermMemory (file_path = user_long_term_path , knowledge_capacity = long_term_knowledge_capacity )
88+ self .mid_term_memory = MidTermMemory (
89+ file_path = user_mid_term_path ,
90+ client = self .client ,
91+ max_capacity = mid_term_capacity ,
92+ embedding_model_name = self .embedding_model_name ,
93+ embedding_model_kwargs = self .embedding_model_kwargs
94+ )
95+ self .user_long_term_memory = LongTermMemory (
96+ file_path = user_long_term_path ,
97+ knowledge_capacity = long_term_knowledge_capacity ,
98+ embedding_model_name = self .embedding_model_name ,
99+ embedding_model_kwargs = self .embedding_model_kwargs
100+ )
60101
61102 # Initialize Memory Module for Assistant Knowledge
62- self .assistant_long_term_memory = LongTermMemory (file_path = assistant_long_term_path , knowledge_capacity = long_term_knowledge_capacity )
103+ self .assistant_long_term_memory = LongTermMemory (
104+ file_path = assistant_long_term_path ,
105+ knowledge_capacity = long_term_knowledge_capacity ,
106+ embedding_model_name = self .embedding_model_name ,
107+ embedding_model_kwargs = self .embedding_model_kwargs
108+ )
63109
64110 # Initialize Orchestration Modules
65111 self .updater = Updater (short_term_memory = self .short_term_memory ,
66112 mid_term_memory = self .mid_term_memory ,
67113 long_term_memory = self .user_long_term_memory , # Updater primarily updates user's LTM profile/knowledge
68114 client = self .client ,
115+ topic_similarity_threshold = mid_term_similarity_threshold , # 传递中期记忆相似度阈值
69116 llm_model = self .llm_model )
70117 self .retriever = Retriever (
71118 mid_term_memory = self .mid_term_memory ,
@@ -80,6 +127,7 @@ def _trigger_profile_and_knowledge_update_if_needed(self):
80127 """
81128 Checks mid-term memory for hot segments and triggers profile/knowledge update if threshold is met.
82129 Adapted from main_memoybank.py's update_user_profile_from_top_segment.
130+ Enhanced with parallel LLM processing for better performance.
83131 """
84132 if not self .mid_term_memory .heap :
85133 return
@@ -102,23 +150,42 @@ def _trigger_profile_and_knowledge_update_if_needed(self):
102150 if unanalyzed_pages :
103151 print (f"Memoryos: Mid-term session { sid } heat ({ current_heat :.2f} ) exceeded threshold. Analyzing { len (unanalyzed_pages )} pages for profile/knowledge update." )
104152
105- # Perform user profile analysis and knowledge extraction separately
106- # First call: User profile analysis
107- new_user_profile_text = gpt_user_profile_analysis (unanalyzed_pages , self .client , model = self .llm_model )
153+ # 并行执行两个LLM任务:用户画像分析(已包含更新)、知识提取
154+ def task_user_profile_analysis ():
155+ print ("Memoryos: Starting parallel user profile analysis and update..." )
156+ # 获取现有用户画像
157+ existing_profile = self .user_long_term_memory .get_raw_user_profile (self .user_id )
158+ if not existing_profile or existing_profile .lower () == "none" :
159+ existing_profile = "No existing profile data."
160+
161+ # 直接输出更新后的完整画像
162+ return gpt_user_profile_analysis (unanalyzed_pages , self .client , model = self .llm_model , existing_user_profile = existing_profile )
163+
164+ def task_knowledge_extraction ():
165+ print ("Memoryos: Starting parallel knowledge extraction..." )
166+ return gpt_knowledge_extraction (unanalyzed_pages , self .client , model = self .llm_model )
167+
168+ # 使用并行任务执行
169+ with ThreadPoolExecutor (max_workers = 2 ) as executor :
170+ # 提交两个主要任务
171+ future_profile = executor .submit (task_user_profile_analysis )
172+ future_knowledge = executor .submit (task_knowledge_extraction )
173+
174+ # 等待结果
175+ try :
176+ updated_user_profile = future_profile .result () # 直接是更新后的完整画像
177+ knowledge_result = future_knowledge .result ()
178+ except Exception as e :
179+ print (f"Error in parallel LLM processing: { e } " )
180+ return
108181
109- # Second call: Knowledge extraction (user private data and assistant knowledge)
110- knowledge_result = gpt_knowledge_extraction (unanalyzed_pages , self .client , model = self .llm_model )
111182 new_user_private_knowledge = knowledge_result .get ("private" )
112183 new_assistant_knowledge = knowledge_result .get ("assistant_knowledge" )
113184
114- # Update User Profile in user's LTM
115- if new_user_profile_text and new_user_profile_text .lower () != "none" :
116- old_profile = self .user_long_term_memory .get_raw_user_profile (self .user_id )
117- if old_profile and old_profile .lower () != "none" :
118- updated_profile = gpt_update_profile (old_profile , new_user_profile_text , self .client , model = self .llm_model )
119- else :
120- updated_profile = new_user_profile_text
121- self .user_long_term_memory .update_user_profile (self .user_id , updated_profile , merge = False ) # Don't merge, replace with latest
185+ # 直接使用更新后的完整用户画像
186+ if updated_user_profile and updated_user_profile .lower () != "none" :
187+ print ("Memoryos: Updating user profile with integrated analysis..." )
188+ self .user_long_term_memory .update_user_profile (self .user_id , updated_user_profile , merge = False ) # 直接替换为新的完整画像
122189
123190 # Add User Private Knowledge to user's LTM
124191 if new_user_private_knowledge and new_user_private_knowledge .lower () != "none" :
0 commit comments