refactor(memory): use MemorySummary node count for implicit memory metrics

- Replace Statement-based implicit memory count (count/3) with actual
  MemorySummary node count filtered by DERIVED_FROM_STATEMENT relationship
- Add minimum threshold of 5 MemorySummary nodes before reporting data
- Add _build_empty_profile() to return structured empty profile when
  insufficient data exists, skipping unnecessary LLM calls
This commit is contained in:
lanceyq
2026-04-13 18:32:43 +08:00
parent 05ea372776
commit ef8c7093b5
2 changed files with 72 additions and 11 deletions

View File

@@ -379,12 +379,59 @@ class ImplicitMemoryService:
raise
def _build_empty_profile(self) -> dict:
"""构建 MemorySummary 不足时返回的固定空白画像数据"""
now_ms = int(datetime.now().timestamp() * 1000)
insufficient = "Insufficient data for analysis"
def _empty_dimension(name: str) -> dict:
return {
"evidence": [insufficient],
"reasoning": f"No clear evidence found for {name} dimension",
"percentage": 0.0,
"dimension_name": name,
"confidence_level": 20,
}
def _empty_category(name: str) -> dict:
return {
"evidence": [insufficient],
"percentage": 25.0,
"category_name": name,
"trending_direction": None,
}
return {
"habits": [],
"portrait": {
"aesthetic": _empty_dimension("aesthetic"),
"creativity": _empty_dimension("creativity"),
"literature": _empty_dimension("literature"),
"technology": _empty_dimension("technology"),
"historical_trends": None,
"analysis_timestamp": now_ms,
"total_summaries_analyzed": 0,
},
"preferences": [],
"interest_areas": {
"art": _empty_category("art"),
"tech": _empty_category("tech"),
"music": _empty_category("music"),
"lifestyle": _empty_category("lifestyle"),
"analysis_timestamp": now_ms,
"total_summaries_analyzed": 0,
},
}
async def generate_complete_profile(
self,
user_id: str
) -> dict:
"""生成完整的用户画像包含所有4个模块
需要该用户的 MemorySummary 节点数量 >= 5 才会真正调用 LLM 生成画像,
否则返回固定的空白画像数据。
Args:
user_id: 用户ID
@@ -394,6 +441,20 @@ class ImplicitMemoryService:
logger.info(f"生成完整用户画像: user={user_id}")
try:
# 前置检查:查询该用户有效的 MemorySummary 节点数量(排除孤立节点)
query = """
MATCH (n:MemorySummary)-[:DERIVED_FROM_STATEMENT]->(:Statement)
WHERE n.end_user_id = $end_user_id
RETURN count(DISTINCT n) as count
"""
result = await self.neo4j_connector.execute_query(query, end_user_id=user_id)
memory_summary_count = result[0]["count"] if result and len(result) > 0 else 0
logger.info(f"用户 MemorySummary 节点数量: {memory_summary_count} (user={user_id})")
if memory_summary_count < 5:
logger.info(f"MemorySummary 数量不足 5当前 {memory_summary_count}),返回空白画像: user={user_id}")
return self._build_empty_profile()
# 并行调用4个分析方法
preferences, portrait, interest_areas, habits = await asyncio.gather(
self.get_preference_tags(user_id=user_id),