refactor(memory): reorganize imports and move MemoryClientFactory to utils

- Move MemoryClientFactory from app.core.memory.client_factory to app.core.memory.utils.llm.llm_utils
- Update all evaluation modules to import MemoryClientFactory from new location (locomo, longmemeval, memsciqa)
- Move GenerateCacheRequest from memory_storage_service to memory_storage_schema
- Update memory_storage_controller imports to reflect schema reorganization
- Add analytics_user_summary import to memory_storage_controller from user_memory_service
- Consolidate utility imports across evaluation test files for consistency
- Improve code organization by centralizing LLM utilities in dedicated utils module
This commit is contained in:
Ke Sun
2025-12-23 18:27:15 +08:00
parent 48f6fe04a1
commit b515e76efb
11 changed files with 23 additions and 19 deletions

View File

@@ -23,11 +23,11 @@ from app.schemas.memory_storage_schema import (
ConfigUpdate, ConfigUpdate,
ConfigUpdateExtracted, ConfigUpdateExtracted,
ConfigUpdateForget, ConfigUpdateForget,
GenerateCacheRequest,
) )
from app.schemas.response_schema import ApiResponse from app.schemas.response_schema import ApiResponse
from app.services.memory_storage_service import ( from app.services.memory_storage_service import (
DataConfigService, DataConfigService,
GenerateCacheRequest,
MemoryStorageService, MemoryStorageService,
analytics_hot_memory_tags, analytics_hot_memory_tags,
analytics_recent_activity_stats, analytics_recent_activity_stats,
@@ -41,6 +41,7 @@ from app.services.memory_storage_service import (
search_entity_graph, search_entity_graph,
search_statement, search_statement,
) )
from app.services.user_memory_service import analytics_user_summary
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session from sqlalchemy.orm import Session

View File

@@ -23,7 +23,6 @@ except ImportError:
def load_dotenv(): def load_dotenv():
pass pass
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.evaluation.common.metrics import ( from app.core.memory.evaluation.common.metrics import (
avg_context_tokens, avg_context_tokens,
bleu1, bleu1,
@@ -51,6 +50,7 @@ from app.core.memory.utils.definitions import (
SELECTED_GROUP_ID, SELECTED_GROUP_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.core.models.base import RedBearModelConfig from app.core.models.base import RedBearModelConfig
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.neo4j_connector import Neo4jConnector from app.repositories.neo4j.neo4j_connector import Neo4jConnector

View File

@@ -435,12 +435,12 @@ async def run_enhanced_evaluation():
return None return None
# 修正导入路径:使用 app.core.memory.src 前缀 # 修正导入路径:使用 app.core.memory.src 前缀
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.llm_tools.openai_embedder import OpenAIEmbedderClient from app.core.memory.llm_tools.openai_embedder import OpenAIEmbedderClient
from app.core.memory.utils.config.definitions import ( from app.core.memory.utils.config.definitions import (
SELECTED_EMBEDDING_ID, SELECTED_EMBEDDING_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.core.models.base import RedBearModelConfig from app.core.models.base import RedBearModelConfig
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.graph_search import search_graph_by_embedding from app.repositories.neo4j.graph_search import search_graph_by_embedding

View File

@@ -15,7 +15,6 @@ except Exception:
import re import re
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.evaluation.common.metrics import ( from app.core.memory.evaluation.common.metrics import (
avg_context_tokens, avg_context_tokens,
bleu1, bleu1,
@@ -34,6 +33,7 @@ from app.core.memory.utils.config.definitions import (
SELECTED_GROUP_ID, SELECTED_GROUP_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.core.models.base import RedBearModelConfig from app.core.models.base import RedBearModelConfig
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding

View File

@@ -34,7 +34,6 @@ try:
) )
except Exception: except Exception:
ingest_contexts_via_full_pipeline = None # 在运行时做兜底检查 ingest_contexts_via_full_pipeline = None # 在运行时做兜底检查
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.evaluation.common.metrics import ( from app.core.memory.evaluation.common.metrics import (
avg_context_tokens, avg_context_tokens,
jaccard, jaccard,
@@ -48,6 +47,7 @@ from app.core.memory.utils.config.definitions import (
SELECTED_EMBEDDING_ID, SELECTED_EMBEDDING_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.core.models.base import RedBearModelConfig from app.core.models.base import RedBearModelConfig
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding

View File

@@ -15,7 +15,6 @@ except Exception:
return None return None
# 与现有评估脚本保持一致的导入方式 # 与现有评估脚本保持一致的导入方式
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.evaluation.common.metrics import ( from app.core.memory.evaluation.common.metrics import (
avg_context_tokens, avg_context_tokens,
jaccard, jaccard,
@@ -29,6 +28,7 @@ from app.core.memory.utils.config.definitions import (
SELECTED_EMBEDDING_ID, SELECTED_EMBEDDING_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.core.models.base import RedBearModelConfig from app.core.models.base import RedBearModelConfig
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding

View File

@@ -15,7 +15,6 @@ except Exception:
def load_dotenv(): def load_dotenv():
return None return None
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.evaluation.common.metrics import ( from app.core.memory.evaluation.common.metrics import (
avg_context_tokens, avg_context_tokens,
exact_match, exact_match,
@@ -31,6 +30,7 @@ from app.core.memory.utils.config.definitions import (
SELECTED_GROUP_ID, SELECTED_GROUP_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.neo4j_connector import Neo4jConnector from app.repositories.neo4j.neo4j_connector import Neo4jConnector

View File

@@ -24,7 +24,6 @@ for _p in (_SRC_DIR, _PROJECT_ROOT):
sys.path.insert(0, _p) sys.path.insert(0, _p)
# 对齐 locomo_test 的检索逻辑:直接使用 graph_search 与 Neo4jConnector/Embedder1 # 对齐 locomo_test 的检索逻辑:直接使用 graph_search 与 Neo4jConnector/Embedder1
from app.core.memory.client_factory import MemoryClientFactory
from app.core.memory.evaluation.common.metrics import ( from app.core.memory.evaluation.common.metrics import (
avg_context_tokens, avg_context_tokens,
exact_match, exact_match,
@@ -37,6 +36,7 @@ from app.core.memory.utils.config.definitions import (
SELECTED_GROUP_ID, SELECTED_GROUP_ID,
SELECTED_LLM_ID, SELECTED_LLM_ID,
) )
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.core.models.base import RedBearModelConfig from app.core.models.base import RedBearModelConfig
from app.db import get_db_context from app.db import get_db_context
from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding from app.repositories.neo4j.graph_search import search_graph, search_graph_by_embedding

View File

@@ -19,7 +19,6 @@ from typing import Any, Dict, List, Optional
from app.core.memory.llm_tools.openai_client import OpenAIClient from app.core.memory.llm_tools.openai_client import OpenAIClient
from app.core.memory.utils.config import definitions as config_defs from app.core.memory.utils.config import definitions as config_defs
from app.core.memory.utils.config import get_model_config
from app.core.memory.utils.config.get_data import ( from app.core.memory.utils.config.get_data import (
extract_and_process_changes, extract_and_process_changes,
get_data, get_data,
@@ -169,12 +168,18 @@ class ReflectionEngine:
self.llm_client = factory.get_llm_client(config_defs.SELECTED_LLM_ID) self.llm_client = factory.get_llm_client(config_defs.SELECTED_LLM_ID)
elif isinstance(self.llm_client, str): elif isinstance(self.llm_client, str):
# 如果 llm_client 是字符串model_id则用它初始化客户端 # 如果 llm_client 是字符串model_id则用它初始化客户端
# from app.core.memory.utils.llm.llm_utils import MemoryClientFactory from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
from app.db import get_db_context from app.db import get_db_context
# model_id = self.llm_client from app.services.memory_config_service import MemoryConfigService
model_id = self.llm_client
with get_db_context() as db: with get_db_context() as db:
factory = MemoryClientFactory(db) factory = MemoryClientFactory(db)
# self.llm_client = factory.get_llm_client(model_id) # self.llm_client = factory.get_llm_client(model_id)
# Use MemoryConfigService to get model config
config_service = MemoryConfigService(db)
model_config = config_service.get_model_config(model_id)
extra_params={ extra_params={
"temperature": 0.2, # 降低温度提高响应速度和一致性 "temperature": 0.2, # 降低温度提高响应速度和一致性
"max_tokens": 600, # 限制最大token数 "max_tokens": 600, # 限制最大token数
@@ -182,7 +187,6 @@ class ReflectionEngine:
"stream": False, # 确保非流式输出以获得最快响应 "stream": False, # 确保非流式输出以获得最快响应
} }
model_config = get_model_config(self.llm_client)
self.llm_client = OpenAIClient(RedBearModelConfig( self.llm_client = OpenAIClient(RedBearModelConfig(
model_name=model_config.get("model_name"), model_name=model_config.get("model_name"),
provider=model_config.get("provider"), provider=model_config.get("provider"),

View File

@@ -492,7 +492,7 @@ class EmotionAnalyticsService:
config_id=int(config_id), config_id=int(config_id),
service_name="EmotionAnalyticsService.generate_emotion_suggestions" service_name="EmotionAnalyticsService.generate_emotion_suggestions"
) )
from app.core.memory.client_factory import MemoryClientFactory from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
factory = MemoryClientFactory(db) factory = MemoryClientFactory(db)
llm_client = factory.get_llm_client(str(memory_config.llm_model_id)) llm_client = factory.get_llm_client(str(memory_config.llm_model_id))
except Exception as e: except Exception as e:

View File

@@ -4,15 +4,15 @@ User Memory Service
处理用户记忆相关的业务逻辑,包括记忆洞察、用户摘要、节点统计和图数据等。 处理用户记忆相关的业务逻辑,包括记忆洞察、用户摘要、节点统计和图数据等。
""" """
from typing import Dict, List, Optional, Any
import uuid import uuid
from sqlalchemy.orm import Session from typing import Any, Dict, List, Optional
from app.core.logging_config import get_logger from app.core.logging_config import get_logger
from app.repositories.end_user_repository import EndUserRepository
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
from app.core.memory.analytics.memory_insight import MemoryInsight from app.core.memory.analytics.memory_insight import MemoryInsight
from app.core.memory.analytics.user_summary import generate_user_summary from app.core.memory.analytics.user_summary import generate_user_summary
from app.repositories.end_user_repository import EndUserRepository
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
from sqlalchemy.orm import Session
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -284,8 +284,7 @@ class UserMemoryService:
# 使用 end_user_id 调用分析函数 # 使用 end_user_id 调用分析函数
try: try:
logger.info(f"使用 end_user_id={end_user_id} 生成用户摘要") logger.info(f"使用 end_user_id={end_user_id} 生成用户摘要")
result = await analytics_user_summary(end_user_id) summary = await generate_user_summary(end_user_id)
summary = result.get("summary", "")
if not summary: if not summary:
logger.warning(f"end_user_id {end_user_id} 的用户摘要生成结果为空") logger.warning(f"end_user_id {end_user_id} 的用户摘要生成结果为空")