From 29852ff0a5228fadc45ef7a4f088fc7bc11d8056 Mon Sep 17 00:00:00 2001 From: lixinyue <2569494688@qq.com> Date: Tue, 20 Jan 2026 20:12:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=AD=E7=BF=BB=E8=8B=B1?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=88=E8=AE=B0=E5=BF=86=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E7=BA=BF=EF=BC=89(=E7=94=A8=E6=88=B7=E6=91=98=E8=A6=81)(?= =?UTF-8?q?=E5=85=B4=E8=B6=A3=E5=88=86=E5=B8=83=E6=8E=A5=E5=8F=A3)(?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=A0=B8=E5=BF=83=E6=A1=A3=E6=A1=88)(?= =?UTF-8?q?=E8=AE=B0=E5=BF=86=E6=B4=9E=E5=AF=9F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/memory_agent_controller.py | 18 +- .../controllers/user_memory_controllers.py | 59 ++++++- api/app/schemas/end_user_schema.py | 1 + api/app/services/memory_agent_service.py | 14 +- api/app/services/memory_base_service.py | 161 +++++++++++++++++- .../memory_entity_relationship_service.py | 94 ++++++++-- api/app/services/user_memory_service.py | 63 ++++--- 7 files changed, 352 insertions(+), 58 deletions(-) diff --git a/api/app/controllers/memory_agent_controller.py b/api/app/controllers/memory_agent_controller.py index b7da943c..46fe3043 100644 --- a/api/app/controllers/memory_agent_controller.py +++ b/api/app/controllers/memory_agent_controller.py @@ -9,7 +9,7 @@ from app.db import get_db from app.dependencies import cur_workspace_access_guard, get_current_user from app.models import ModelApiKey from app.models.user_model import User -from app.repositories import knowledge_repository +from app.repositories import knowledge_repository, WorkspaceRepository from app.schemas.memory_agent_schema import UserInput, Write_UserInput from app.schemas.response_schema import ApiResponse from app.services import task_service, workspace_service @@ -616,8 +616,10 @@ async def get_knowledge_type_stats_api( @router.get("/analytics/hot_memory_tags/by_user", response_model=ApiResponse) async def get_hot_memory_tags_by_user_api( end_user_id: Optional[str] = Query(None, description="用户ID(可选)"), + language_type: Optional[str] ="zh", limit: int = Query(20, description="返回标签数量限制"), - current_user: User = Depends(get_current_user) + current_user: User = Depends(get_current_user), + db: Session=Depends(get_db), ): """ 获取指定用户的热门记忆标签 @@ -628,10 +630,22 @@ async def get_hot_memory_tags_by_user_api( ... ] """ + + workspace_id=current_user.current_workspace_id + workspace_repo = WorkspaceRepository(db) + workspace_models = workspace_repo.get_workspace_models_configs(workspace_id) + + if workspace_models: + model_id = workspace_models.get("llm", None) + else: + model_id = None + api_logger.info(f"Hot memory tags by user requested: end_user_id={end_user_id}") try: result = await memory_agent_service.get_hot_memory_tags_by_user( end_user_id=end_user_id, + language_type=language_type, + model_id=model_id, limit=limit ) return success(data=result, msg="获取热门记忆标签成功") diff --git a/api/app/controllers/user_memory_controllers.py b/api/app/controllers/user_memory_controllers.py index a96c7a52..560d6c0d 100644 --- a/api/app/controllers/user_memory_controllers.py +++ b/api/app/controllers/user_memory_controllers.py @@ -12,6 +12,7 @@ from app.core.logging_config import get_api_logger from app.core.response_utils import success, fail from app.core.error_codes import BizCode from app.core.api_key_utils import timestamp_to_datetime +from app.services.memory_base_service import Translation_English from app.services.user_memory_service import ( UserMemoryService, analytics_memory_types, @@ -20,7 +21,7 @@ from app.services.user_memory_service import ( from app.services.memory_entity_relationship_service import MemoryEntityService,MemoryEmotion,MemoryInteraction from app.schemas.response_schema import ApiResponse from app.schemas.memory_storage_schema import GenerateCacheRequest - +from app.repositories.workspace_repository import WorkspaceRepository from app.schemas.end_user_schema import ( EndUserProfileResponse, EndUserProfileUpdate, @@ -44,6 +45,7 @@ router = APIRouter( @router.get("/analytics/memory_insight/report", response_model=ApiResponse) async def get_memory_insight_report_api( end_user_id: str, + language_type: str = "zh", current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ) -> dict: @@ -53,10 +55,18 @@ async def get_memory_insight_report_api( 此接口仅查询数据库中已缓存的记忆洞察数据,不执行生成操作。 如需生成新的洞察报告,请使用专门的生成接口。 """ + workspace_id = current_user.current_workspace_id + workspace_repo = WorkspaceRepository(db) + workspace_models = workspace_repo.get_workspace_models_configs(workspace_id) + + if workspace_models: + model_id = workspace_models.get("llm", None) + else: + model_id = None api_logger.info(f"记忆洞察报告查询请求: end_user_id={end_user_id}, user={current_user.username}") try: # 调用服务层获取缓存数据 - result = await user_memory_service.get_cached_memory_insight(db, end_user_id) + result = await user_memory_service.get_cached_memory_insight(db, end_user_id,model_id,language_type) if result["is_cached"]: api_logger.info(f"成功返回缓存的记忆洞察报告: end_user_id={end_user_id}") @@ -72,6 +82,7 @@ async def get_memory_insight_report_api( @router.get("/analytics/user_summary", response_model=ApiResponse) async def get_user_summary_api( end_user_id: str, + language_type: str="zh", current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ) -> dict: @@ -81,10 +92,18 @@ async def get_user_summary_api( 此接口仅查询数据库中已缓存的用户摘要数据,不执行生成操作。 如需生成新的用户摘要,请使用专门的生成接口。 """ + workspace_id = current_user.current_workspace_id + workspace_repo = WorkspaceRepository(db) + workspace_models = workspace_repo.get_workspace_models_configs(workspace_id) + + if workspace_models: + model_id = workspace_models.get("llm", None) + else: + model_id = None api_logger.info(f"用户摘要查询请求: end_user_id={end_user_id}, user={current_user.username}") try: # 调用服务层获取缓存数据 - result = await user_memory_service.get_cached_user_summary(db, end_user_id) + result = await user_memory_service.get_cached_user_summary(db, end_user_id,model_id,language_type) if result["is_cached"]: api_logger.info(f"成功返回缓存的用户摘要: end_user_id={end_user_id}") @@ -253,7 +272,6 @@ async def get_graph_data_api( depth=depth, center_node_id=center_node_id ) - # 检查是否有错误消息 if "message" in result and result["statistics"]["total_nodes"] == 0: api_logger.warning(f"图数据查询返回空结果: {result.get('message')}") @@ -274,11 +292,18 @@ async def get_graph_data_api( @router.get("/read_end_user/profile", response_model=ApiResponse) async def get_end_user_profile( end_user_id: str, + language_type: str = "zh", current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ) -> dict: workspace_id = current_user.current_workspace_id + workspace_repo = WorkspaceRepository(db) + workspace_models = workspace_repo.get_workspace_models_configs(workspace_id) + if workspace_models: + model_id = workspace_models.get("llm", None) + else: + model_id = None # 检查用户是否已选择工作空间 if workspace_id is None: api_logger.warning(f"用户 {current_user.username} 尝试查询用户信息但未选择工作空间") @@ -297,12 +322,19 @@ async def get_end_user_profile( api_logger.warning(f"终端用户不存在: end_user_id={end_user_id}") return fail(BizCode.INVALID_PARAMETER, "终端用户不存在", f"end_user_id={end_user_id}") + other_name=end_user.other_name + position=end_user.position + department=end_user.department + if language_type!="zh": + other_name=await Translation_English(model_id,other_name) + position = await Translation_English(model_id, position) + department = await Translation_English(model_id, department) # 构建响应数据 profile_data = EndUserProfileResponse( id=end_user.id, - other_name=end_user.other_name, - position=end_user.position, - department=end_user.department, + other_name=other_name, + position=position, + department=department, contact=end_user.contact, phone=end_user.phone, hire_date=end_user.hire_date, @@ -396,12 +428,21 @@ async def update_end_user_profile( return fail(BizCode.INTERNAL_ERROR, "用户信息更新失败", str(e)) @router.get("/memory_space/timeline_memories", response_model=ApiResponse) -async def memory_space_timeline_of_shared_memories(id: str, label: str, +async def memory_space_timeline_of_shared_memories(id: str, label: str,language_type: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): + workspace_id=current_user.current_workspace_id + workspace_repo = WorkspaceRepository(db) + workspace_models = workspace_repo.get_workspace_models_configs(workspace_id) + + if workspace_models: + model_id = workspace_models.get("llm", None) + else: + model_id = None MemoryEntity = MemoryEntityService(id, label) - timeline_memories_result = await MemoryEntity.get_timeline_memories_server() + timeline_memories_result = await MemoryEntity.get_timeline_memories_server(model_id, language_type) + return success(data=timeline_memories_result, msg="共同记忆时间线") @router.get("/memory_space/relationship_evolution", response_model=ApiResponse) async def memory_space_relationship_evolution(id: str, label: str, diff --git a/api/app/schemas/end_user_schema.py b/api/app/schemas/end_user_schema.py index c9f9146d..6f7498a0 100644 --- a/api/app/schemas/end_user_schema.py +++ b/api/app/schemas/end_user_schema.py @@ -44,6 +44,7 @@ class EndUserProfileResponse(BaseModel): updatetime_profile: Optional[datetime.datetime] = Field(description="核心档案信息最后更新时间", default=None) + class EndUserProfileUpdate(BaseModel): """终端用户基本信息更新请求模型""" end_user_id: str = Field(description="终端用户ID") diff --git a/api/app/services/memory_agent_service.py b/api/app/services/memory_agent_service.py index c9230a26..ddf04216 100644 --- a/api/app/services/memory_agent_service.py +++ b/api/app/services/memory_agent_service.py @@ -26,6 +26,7 @@ from app.db import get_db_context from app.models.knowledge_model import Knowledge, KnowledgeType from app.repositories.neo4j.neo4j_connector import Neo4jConnector from app.schemas.memory_config_schema import ConfigurationError +from app.services.memory_base_service import Translation_English from app.services.memory_config_service import MemoryConfigService from app.services.memory_konwledges_server import ( write_rag, @@ -692,7 +693,9 @@ class MemoryAgentService: async def get_hot_memory_tags_by_user( self, end_user_id: Optional[str] = None, - limit: int = 20 + limit: int = 20, + model_id: Optional[str] = None, + language_type: Optional[str] = "zh" ) -> List[Dict[str, Any]]: """ 获取指定用户的热门记忆标签 @@ -710,7 +713,14 @@ class MemoryAgentService: try: # by_user=False 表示按 group_id 查询(在Neo4j中,group_id就是用户维度) tags = await get_hot_memory_tags(end_user_id, limit=limit, by_user=False) - payload = [{"name": t, "frequency": f} for t, f in tags] + payload=[] + for tag, freq in tags: + print(tag, freq) + if language_type!="zh": + tag=await Translation_English(model_id, tag) + payload.append({"name": tag, "frequency": freq}) + else: + payload.append({"name": tag, "frequency": freq}) return payload except Exception as e: logger.error(f"热门记忆标签查询失败: {e}") diff --git a/api/app/services/memory_base_service.py b/api/app/services/memory_base_service.py index 6f844ae9..784dec7d 100644 --- a/api/app/services/memory_base_service.py +++ b/api/app/services/memory_base_service.py @@ -3,17 +3,164 @@ Memory Base Service 提供记忆服务的基础功能和共享辅助方法。 """ - +import asyncio +import re from datetime import datetime from typing import Optional - +from pydantic import BaseModel from app.core.logging_config import get_logger from app.repositories.neo4j.neo4j_connector import Neo4jConnector from app.services.emotion_analytics_service import EmotionAnalyticsService - +from app.core.memory.llm_tools.openai_client import OpenAIClient +from app.core.models.base import RedBearModelConfig +from app.services.memory_config_service import MemoryConfigService +from app.db import get_db_context logger = get_logger(__name__) +class TranslationResponse(BaseModel): + """翻译响应模型""" + data: str + +class MemoryTransService: + """记忆翻译服务,提供中英文翻译功能""" + + def __init__(self, llm_client=None, model_id: Optional[str] = None): + """ + 初始化翻译服务 + + Args: + llm_client: LLM客户端实例或模型ID字符串(可选) + model_id: 模型ID,用于初始化LLM客户端(可选) + + Note: + - 如果llm_client是字符串,会被当作model_id使用 + - 如果同时提供llm_client和model_id,优先使用llm_client + """ + # 处理llm_client参数:如果是字符串,当作model_id + if isinstance(llm_client, str): + self.model_id = llm_client + self.llm_client = None + else: + self.llm_client = llm_client + self.model_id = model_id + + self._initialized = False + + def _ensure_llm_client(self): + """确保LLM客户端已初始化""" + if self._initialized: + return + + if self.llm_client is None: + if self.model_id: + with get_db_context() as db: + config_service = MemoryConfigService(db) + model_config = config_service.get_model_config(self.model_id) + + extra_params = { + "temperature": 0.2, + "max_tokens": 400, + "top_p": 0.8, + "stream": False, + } + + self.llm_client = OpenAIClient( + RedBearModelConfig( + model_name=model_config.get("model_name"), + provider=model_config.get("provider"), + api_key=model_config.get("api_key"), + base_url=model_config.get("base_url"), + timeout=model_config.get("timeout", 30), + max_retries=model_config.get("max_retries", 3), + extra_params=extra_params + ), + type_=model_config.get("type") + ) + else: + raise ValueError("必须提供 llm_client 或 model_id 之一") + + self._initialized = True + + async def translate_to_english(self, text: str) -> str: + """ + 将中文翻译为英文 + + Args: + text: 要翻译的中文文本 + + Returns: + 翻译后的英文文本 + """ + self._ensure_llm_client() + + translation_messages = [ + { + "role": "user", + "content": f"{text}\n\n中文翻译为英文,输出格式为{{\"data\":\"翻译后的内容\"}}" + } + ] + + try: + response = await self.llm_client.response_structured( + messages=translation_messages, + response_model=TranslationResponse + ) + return response.data + except Exception as e: + logger.error(f"翻译失败: {str(e)}") + return text # 翻译失败时返回原文 + + async def is_english(self,text: str) -> bool: + return bool(re.fullmatch(r"[A-Za-z\s]+", text)) + async def Translate(self, text: str, target_language: str = "en") -> str: + """ + 通用翻译方法(保持向后兼容) + + Args: + text: 要翻译的文本 + target_language: 目标语言,"en"表示英文,"zh"表示中文 + + Returns: + 翻译后的文本 + """ + if target_language == "en": + return await self.translate_to_english(text) + else: + logger.warning(f"不支持的目标语言: {target_language},返回原文") + return text + + # 测试翻译服务 +async def Translation_English(modid, text, fields=None): + """ + 将数据翻译为英文(支持字段级翻译) + + Args: + modid: 模型ID + text: 要翻译的数据(可以是字符串、字典或列表) + fields: 需要翻译的字段列表(可选) + 如果为None,默认翻译: ['content', 'summary', 'statement', 'description', + 'name', 'aliases', 'caption', 'emotion_keywords'] + + Returns: + 翻译后的数据,保持原有结构 + """ + trans_service = MemoryTransService(modid) + # 执行翻译 + if isinstance(text, list): + english_result=[] + for i in text: + is_eng=await trans_service.is_english(i) + if not is_eng: + english = await trans_service.Translate(i) + english_result.append(english) + return english_result + if isinstance(text, str): + is_eng = await trans_service.is_english(text) + if not is_eng: + english_result = await trans_service.Translate(text) + return english_result + return text class MemoryBaseService: """记忆服务基类,提供共享的辅助方法""" @@ -295,3 +442,11 @@ class MemoryBaseService: except Exception as e: logger.error(f"获取遗忘记忆数量时出错: {str(e)}", exc_info=True) return 0 + +if __name__ == '__main__': + import asyncio + a=[{"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:33925", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u4f60\u597d", "created_at": "2026-01-06T14:50:08.381230", "associative_memory": 0}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:33926", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u53d1\u8d77\u4e86\u5bf9\u8bdd\uff0c\u53d1\u9001\u4e86\u95ee\u5019\u8bed\"\u4f60\u597d\"\u3002", "created_at": "2026-01-06T14:50:11.363879", "associative_memory": 0}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76903", "label": "ExtractedEntity", "properties": {"description": "\u5728\u673a\u5668\u5b66\u4e60\u4e2d\u901a\u8fc7\u4e0d\u540c\u6570\u636e\u6837\u672c\u6765\u8861\u91cf\u6a21\u578b\u9884\u6d4b\u8bef\u5dee\u7684\u65b9\u6cd5", "name": "\u5f88\u591a\u91cd\u8981\u7684\u4eba\u751f\u9009\u62e9", "entity_type": "\u6982\u5ff5\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-06T19:24:55.805367", "aliases": ["\u505a\u7279\u5f81\u63d0\u53d6", "\u56de\u6eaf\u5386\u53f2\u6570\u636e", "\u5728\u4e0d\u540c\u65f6\u95f4\u7a97\u53e3\u4e0b\u505a\u957f\u671f\u4e0e\u77ed\u671f\u6536\u76ca\u7684\u6743\u8861", "\u5728\u4e0d\u540c\u6837\u672c\u4e0a\u8bc4\u4f30\u635f\u5931\u51fd\u6570", "\u5bf9\u6bd4\u90a3\u4e9b\u8ba9\u4eba\u8e0f\u5b9e\u6216\u540e\u6094\u7684\u51b3\u5b9a", "\u628a\u65f6\u95f4\u62c9\u957f\u53bb\u60f3\u4e00\u5e74\u3001\u4e09\u5e74\u3001\u4e94\u5e74\u540e\u7684\u7ed3\u679c", "\u6a21\u578b\u53d1\u73b0\u4e86\u5f02\u5e38\u4fe1\u53f7", "\u6a21\u578b\u5728\u591a\u6b21\u62c6\u89e3\u4e0e\u8fed\u4ee3\u4e2d\u9010\u6e10\u6536\u655b\u5230\u7684\u7ed3\u679c", "\u7b54\u6848", "\u4eba\u6027", "\u6545\u4e8b\u4e2d\u7684\u4eba\u7269\u5173\u7cfb"], "connect_strength": "strong", "associative_memory": 11}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76904", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u6d89\u53ca\u591a\u56e0\u7d20\u5206\u6790\u548c\u672a\u6765\u63a8\u65ad\u7684\u590d\u6742\u4efb\u52a1\u7c7b\u578b", "name": "\u4e00\u6b21\u590d\u6742\u7684\u9884\u6d4b\u4efb\u52a1", "entity_type": "", "created_at": "2026-01-06T19:24:55.805367", "connect_strength": "Strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76905", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u5728\u91cd\u8981\u4eba\u751f\u9009\u62e9\u521d\u671f\u51fa\u73b0\u7684\u8f7b\u5fae\u4e0d\u5b89\u60c5\u7eea", "name": "\u6700\u5f00\u59cb\u51fa\u73b0\u7684\u90a3\u70b9\u4e0d\u5b89", "entity_type": "", "created_at": "2026-01-06T19:24:55.805367", "connect_strength": "Strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76906", "label": "ExtractedEntity", "properties": {"description": "\u5bf9\u4ee5\u5f80\u7ecf\u9a8c\u8fdb\u884c\u53cd\u601d\u548c\u5206\u6790\u7684\u884c\u4e3a", "name": "\u56de\u987e\u8fc7\u53bb\u7684\u7ecf\u5386", "entity_type": "\u6982\u5ff5\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-06T19:24:55.805367", "connect_strength": "Strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76907", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u5c06\u91cd\u8981\u4eba\u751f\u9009\u62e9\u7c7b\u6bd4\u4e3a\u590d\u6742\u7684\u9884\u6d4b\u4efb\u52a1\uff1a\u521d\u59cb\u4e0d\u5b89\u5982\u540c\u6a21\u578b\u68c0\u6d4b\u5230\u5f02\u5e38\u4fe1\u53f7\uff1b\u56de\u987e\u8fc7\u5f80\u7ecf\u5386\u662f\u8fdb\u884c\u5386\u53f2\u6570\u636e\u56de\u6eaf\u4e0e\u7279\u5f81\u63d0\u53d6\uff1b\u5bf9\u6bd4\u4ee4\u4eba\u5b89\u5fc3\u6216\u540e\u6094\u7684\u51b3\u7b56\u76f8\u5f53\u4e8e\u5728\u4e0d\u540c\u6837\u672c\u4e0a\u8bc4\u4f30\u635f\u5931\u51fd\u6570\uff1b\u957f\u671f\u601d\u8003\u4e00\u5e74\u3001\u4e09\u5e74\u3001\u4e94\u5e74\u540e\u7684\u7ed3\u679c\uff0c\u662f\u5728\u6743\u8861\u4e0d\u540c\u65f6\u95f4\u7a97\u53e3\u4e0b\u7684\u77ed\u671f\u4e0e\u957f\u671f\u6536\u76ca\u3002\u6700\u7ec8\u7684\u201c\u7b54\u6848\u201d\u5e76\u975e\u76f4\u63a5\u8ba1\u7b97\u5f97\u51fa\uff0c\u800c\u662f\u5728\u591a\u6b21\u62c6\u89e3\u4e0e\u8fed\u4ee3\u8fc7\u7a0b\u4e2d\uff0c\u7531\u6a21\u578b\u9010\u6b65\u6536\u655b\u5f62\u6210\u3002", "created_at": "2026-01-06T19:25:18.822414", "associative_memory": 6}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76908", "label": "Dialogue", "properties": {"content": "\u7528\u6237: 1778 \u97f3\u4e50 ## \u4e8b\u4ef6 - 1 \u6708 1 \u65e5 \u2013 \u5a01\u5ec9\u00b7\u535a\u4f0a\u65af\u7684\u201c\u5f53\u654c\u5bf9\u56fd\u5bb6\u6b66\u88c5\u8d77\u6765\u65f6\u201d\u5728\u4f26\u6566\u5723\u8a79\u59c6\u65af\u5bab\u9996\u6620\u3002[1] - 1 \u6708 14 \u65e5 \u2013 \u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u5728\u8bbf\u95ee\u66fc\u6d77\u59c6\u65f6\u4f1a\u89c1\u4e86\u5f53\u5730\u4f5c\u66f2\u5bb6\u683c\u5965\u5c14\u683c\u00b7\u7ea6\u745f\u592b\u00b7\u6c83\u683c\u52d2\u3002[1] - 1 \u6708 27 \u65e5 \u2013 \u5c3c\u79d1\u6d1b\u00b7\u76ae\u94a6\u5c3c\u7684\u7b2c\u4e00\u90e8\u6cd5\u56fd\u6b4c\u5267\u201c\u7f57\u5170\u201d\u5728\u5df4\u9ece\u6b4c\u5267\u9662\u9996\u6f14\u3002[1] - 2 \u6708 14 \u65e5 \u2013 \u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u5199\u4fe1\u7ed9\u4ed6\u7684\u7236\u4eb2\u5229\u5965\u6ce2\u5fb7\u00b7\u83ab\u624e\u7279\uff0c\u544a\u8bc9\u4ed6\u4ed6\u591a\u4e48\u8ba8\u538c\u4e3a\u957f\u7b1b\u4f5c\u66f2\u3002[1] - 2 \u6708 17 \u65e5 \u2013 \u4f0a\u683c\u7eb3\u5179\u00b7\u4e4c\u59c6\u52b3\u592b\u7684\u201cDie Bergknappen\u201d\u6210\u4e3a\u7b2c\u4e00\u90e8\u5728\u7ef4\u4e5f\u7eb3\u4e0a\u6f14\u7684\u5f53\u5730\u4f5c\u66f2\u5bb6\u521b\u4f5c\u7684\u6b4c\u5531\u5267\u3002[1] - 3 \u6708 1 \u65e5 \u2013 \u514b\u91cc\u65af\u6258\u592b\u00b7\u5a01\u5229\u5df4\u5c14\u5fb7\u00b7\u683c\u9c81\u514b\u5728\u5df4\u9ece\u5c45\u4f4f\u5341\u5e74\u540e\u8fd4\u56de\u7ef4\u4e5f\u7eb3\u3002[1] - 3 \u6708 2 \u65e5 \u2013 \u7ef4\u4e5f\u7eb3\u56fd\u5bb6\u5267\u9662\u559c\u6b4c\u5267\u516c\u53f8\u4e3e\u884c\u6700\u540e\u4e00\u6b21\u6f14\u51fa", "created_at": "2026-01-06T19:31:26.129718", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76909", "label": "Chunk", "properties": {"content": "\u7528\u6237: 1778 \u97f3\u4e50 ## \u4e8b\u4ef6 - 1 \u6708 1 \u65e5 \u2013 \u5a01\u5ec9\u00b7\u535a\u4f0a\u65af\u7684\u201c\u5f53\u654c\u5bf9\u56fd\u5bb6\u6b66\u88c5\u8d77\u6765\u65f6\u201d\u5728\u4f26\u6566\u5723\u8a79\u59c6\u65af\u5bab\u9996\u6620\u3002[1] - 1 \u6708 14 \u65e5 \u2013 \u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u5728\u8bbf\u95ee\u66fc\u6d77\u59c6\u65f6\u4f1a\u89c1\u4e86\u5f53\u5730\u4f5c\u66f2\u5bb6\u683c\u5965\u5c14\u683c\u00b7\u7ea6\u745f\u592b\u00b7\u6c83\u683c\u52d2\u3002[1] - 1 \u6708 27 \u65e5 \u2013 \u5c3c\u79d1\u6d1b\u00b7\u76ae\u94a6\u5c3c\u7684\u7b2c\u4e00\u90e8\u6cd5\u56fd\u6b4c\u5267\u201c\u7f57\u5170\u201d\u5728\u5df4\u9ece\u6b4c\u5267\u9662\u9996\u6f14\u3002[1] - 2 \u6708 14 \u65e5 \u2013 \u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u5199\u4fe1\u7ed9\u4ed6\u7684\u7236\u4eb2\u5229\u5965\u6ce2\u5fb7\u00b7\u83ab\u624e\u7279\uff0c\u544a\u8bc9\u4ed6\u4ed6\u591a\u4e48\u8ba8\u538c\u4e3a\u957f\u7b1b\u4f5c\u66f2\u3002[1] - 2 \u6708 17 \u65e5 \u2013 \u4f0a\u683c\u7eb3\u5179\u00b7\u4e4c\u59c6\u52b3\u592b\u7684\u201cDie Bergknappen\u201d\u6210\u4e3a\u7b2c\u4e00\u90e8\u5728\u7ef4\u4e5f\u7eb3\u4e0a\u6f14\u7684\u5f53\u5730\u4f5c\u66f2\u5bb6\u521b\u4f5c\u7684\u6b4c\u5531\u5267\u3002[1] - 3 \u6708 1 \u65e5 \u2013 \u514b\u91cc\u65af\u6258\u592b\u00b7\u5a01\u5229\u5df4\u5c14\u5fb7\u00b7\u683c\u9c81\u514b\u5728\u5df4\u9ece\u5c45\u4f4f\u5341\u5e74\u540e\u8fd4\u56de\u7ef4\u4e5f\u7eb3\u3002[1] - 3 \u6708 2 \u65e5 \u2013 \u7ef4\u4e5f\u7eb3\u56fd\u5bb6\u5267\u9662\u559c\u6b4c\u5267\u516c\u53f8\u4e3e\u884c\u6700\u540e\u4e00\u6b21\u6f14\u51fa", "created_at": "2026-01-06T19:31:26.129718", "associative_memory": 7}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76910", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e741\u67081\u65e5\uff0c\u5a01\u5ec9\u00b7\u535a\u4f0a\u65af\u7684\u201c\u5f53\u654c\u5bf9\u56fd\u5bb6\u6b66\u88c5\u8d77\u6765\u65f6\u201d\u5728\u4f26\u6566\u5723\u8a79\u59c6\u65af\u5bab\u9996\u6620\u3002", "valid_at": "1778-01-01T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76911", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e741\u670814\u65e5\uff0c\u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u5728\u8bbf\u95ee\u66fc\u6d77\u59c6\u65f6\u4f1a\u89c1\u4e86\u5f53\u5730\u4f5c\u66f2\u5bb6\u683c\u5965\u5c14\u683c\u00b7\u7ea6\u745f\u592b\u00b7\u6c83\u683c\u52d2\u3002", "valid_at": "1778-01-14T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76912", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e741\u670827\u65e5\uff0c\u5c3c\u79d1\u6d1b\u00b7\u76ae\u94a6\u5c3c\u7684\u7b2c\u4e00\u90e8\u6cd5\u56fd\u6b4c\u5267\u201c\u7f57\u5170\u201d\u5728\u5df4\u9ece\u6b4c\u5267\u9662\u9996\u6f14\u3002", "valid_at": "1778-01-27T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76913", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e742\u670814\u65e5\uff0c\u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u5199\u4fe1\u7ed9\u4ed6\u7684\u7236\u4eb2\u5229\u5965\u6ce2\u5fb7\u00b7\u83ab\u624e\u7279\uff0c\u544a\u8bc9\u4ed6\u4ed6\u591a\u4e48\u8ba8\u538c\u4e3a\u957f\u7b1b\u4f5c\u66f2\u3002", "valid_at": "1778-02-14T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76914", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e742\u670817\u65e5\uff0c\u4f0a\u683c\u7eb3\u5179\u00b7\u4e4c\u59c6\u52b3\u592b\u7684\u201cDie Bergknappen\u201d\u6210\u4e3a\u7b2c\u4e00\u90e8\u5728\u7ef4\u4e5f\u7eb3\u4e0a\u6f14\u7684\u5f53\u5730\u4f5c\u66f2\u5bb6\u521b\u4f5c\u7684\u6b4c\u5531\u5267\u3002", "valid_at": "1778-02-17T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 6}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76915", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e743\u67081\u65e5\uff0c\u514b\u91cc\u65af\u6258\u592b\u00b7\u5a01\u5229\u5df4\u5c14\u5fb7\u00b7\u683c\u9c81\u514b\u5728\u5df4\u9ece\u5c45\u4f4f\u5341\u5e74\u540e\u8fd4\u56de\u7ef4\u4e5f\u7eb3\u3002", "valid_at": "1778-03-01T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76916", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "1778\u5e743\u67082\u65e5\uff0c\u7ef4\u4e5f\u7eb3\u56fd\u5bb6\u5267\u9662\u559c\u6b4c\u5267\u516c\u53f8\u4e3e\u884c\u6700\u540e\u4e00\u6b21\u6f14\u51fa\u3002", "valid_at": "1778-03-02T00:00:00+00:00", "created_at": "2026-01-06T19:31:26.129718", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76917", "label": "ExtractedEntity", "properties": {"description": "\u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279\u7684\u7236\u4eb2\uff0c\u97f3\u4e50\u5bb6\u548c\u4f5c\u66f2\u5bb6", "name": "\u5a01\u5ec9\u00b7\u535a\u4f0a\u65af", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-06T19:31:26.129718", "aliases": ["\u4f0a\u683c\u7eb3\u5179\u00b7\u4e4c\u59c6\u52b3\u592b", "\u514b\u91cc\u65af\u6258\u592b\u00b7\u5a01\u5229\u5df4\u5c14\u5fb7\u00b7\u683c\u9c81\u514b", "\u5229\u5965\u6ce2\u5fb7\u00b7\u83ab\u624e\u7279", "\u5c3c\u79d1\u6d1b\u00b7\u76ae\u94a6\u5c3c", "\u683c\u5965\u5c14\u683c\u00b7\u7ea6\u745f\u592b\u00b7\u6c83\u683c\u52d2", "\u6c83\u5c14\u592b\u5188\u00b7\u963f\u9a6c\u5fb7\u4e4c\u65af\u00b7\u83ab\u624e\u7279", "\u83ab\u624e\u7279"], "connect_strength": "strong", "associative_memory": 11}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76918", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u90e8\u7531\u4f0a\u683c\u7eb3\u5179\u00b7\u4e4c\u59c6\u52b3\u592b\u521b\u4f5c\u7684\u6b4c\u5531\u5267", "name": "\u5f53\u654c\u5bf9\u56fd\u5bb6\u6b66\u88c5\u8d77\u6765\u65f6", "entity_type": "", "created_at": "2026-01-06T19:31:26.129718", "aliases": ["Die Bergknappen"], "connect_strength": "strong", "associative_memory": 6}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76919", "label": "ExtractedEntity", "properties": {"description": "\u4f4d\u4e8e\u4f26\u6566\u7684\u7687\u5bb6\u5bab\u6bbf\uff0c\u66fe\u7528\u4e8e\u4e3e\u529e\u97f3\u4e50\u9996\u6f14", "name": "\u4f26\u6566\u5723\u8a79\u59c6\u65af\u5bab", "entity_type": "\u5730\u70b9\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-06T19:31:26.129718", "aliases": ["\u5723\u8a79\u59c6\u65af\u5bab", "\u7f57\u5170"], "connect_strength": "strong", "associative_memory": 5}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76920", "label": "ExtractedEntity", "properties": {"description": "\u4f4d\u4e8e\u5df4\u9ece\u7684\u8457\u540d\u6b4c\u5267\u9662\uff0c\u9996\u6f14\u591a\u90e8\u91cd\u8981\u6b4c\u5267\u4f5c\u54c1", "name": "\u5df4\u9ece\u6b4c\u5267\u9662", "entity_type": "\u5730\u70b9\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-06T19:31:26.129718", "aliases": ["\u5df4\u9ece\u56fd\u5bb6\u6b4c\u5267\u9662", "\u7ef4\u4e5f\u7eb3", "\u7ef4\u4e5f\u7eb3\u56fd\u5bb6\u5267\u9662\u559c\u6b4c\u5267\u516c\u53f8", "\u7ef4\u4e5f\u7eb3\u5e02"], "connect_strength": "strong", "associative_memory": 8}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76921", "label": "ExtractedEntity", "properties": {"description": "\u7ec4\u7ec7\u4e3e\u529e\u7684\u6700\u7ec8\u573a\u6b21\u7684\u8868\u6f14\u6d3b\u52a8", "name": "\u4e3a\u957f\u7b1b\u4f5c\u66f2", "entity_type": "", "created_at": "2026-01-06T19:31:26.129718", "aliases": ["\u6700\u540e\u4e00\u6b21\u6f14\u51fa"], "connect_strength": "strong", "associative_memory": 4}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76922", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u7ed3\u5408\u97f3\u4e50\u4e0e\u620f\u5267\u7684\u821e\u53f0\u827a\u672f\u5f62\u5f0f", "name": "\u6b4c\u5531\u5267", "entity_type": "", "created_at": "2026-01-06T19:31:26.129718", "aliases": ["Singspiel", "\u5fb7\u8bed\u6b4c\u5531\u5267"], "connect_strength": "Strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76923", "label": "MemorySummary", "properties": {"content": "1778\u5e74\u97f3\u4e50\u4e8b\u4ef6\uff1a1\u67081\u65e5\uff0c\u5a01\u5ec9\u00b7\u535a\u4f0a\u65af\u7684\u300a\u5f53\u654c\u5bf9\u56fd\u5bb6\u6b66\u88c5\u8d77\u6765\u65f6\u300b\u5728\u4f26\u6566\u5723\u8a79\u59c6\u65af\u5bab\u9996\u6f14\uff1b1\u670814\u65e5\uff0c\u83ab\u624e\u7279\u5728\u66fc\u6d77\u59c6\u4f1a\u89c1\u4f5c\u66f2\u5bb6\u683c\u5965\u5c14\u683c\u00b7\u7ea6\u745f\u592b\u00b7\u6c83\u683c\u52d2\uff1b1\u670827\u65e5\uff0c\u5c3c\u79d1\u6d1b\u00b7\u76ae\u94a6\u5c3c\u7684\u6b4c\u5267\u300a\u7f57\u5170\u300b\u5728\u5df4\u9ece\u6b4c\u5267\u9662\u9996\u6f14\uff1b2\u670814\u65e5\uff0c\u83ab\u624e\u7279\u5199\u4fe1\u7ed9\u7236\u4eb2\uff0c\u8868\u8fbe\u5bf9\u4e3a\u957f\u7b1b\u4f5c\u66f2\u7684\u538c\u6076\uff1b2\u670817\u65e5\uff0c\u4f0a\u683c\u7eb3\u5179\u00b7\u4e4c\u59c6\u52b3\u592b\u7684\u300aDie Bergknappen\u300b\u6210\u4e3a\u9996\u90e8\u5728\u7ef4\u4e5f\u7eb3\u4e0a\u6f14\u7684\u672c\u5730\u521b\u4f5c\u6b4c\u5531\u5267\uff1b3\u67081\u65e5\uff0c\u683c\u9c81\u514b\u5728\u5df4\u9ece\u5c45\u4f4f\u5341\u5e74\u540e\u8fd4\u56de\u7ef4\u4e5f\u7eb3\uff1b3\u67082\u65e5\uff0c\u7ef4\u4e5f\u7eb3\u56fd\u5bb6\u5267\u9662\u559c\u6b4c\u5267\u516c\u53f8\u4e3e\u884c\u6700\u540e\u4e00\u573a\u6f14\u51fa\u3002", "created_at": "2026-01-06T19:32:01.901346", "associative_memory": 7}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:76998", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u5f20\u66fc\u7389\u51fa\u6f14\u4e86\u5f90\u514b\u5bfc\u6f14\u7684\u9752\u86c7\u3002\u4ee5\u4eba\u6027\uff0c\u795e\u6027\u7b49\u65b9\u9762\u6765\u63cf\u8ff0\u4e86\u6545\u4e8b\u4e2d\u7684\u4eba\u7269\u5173\u7cfb", "created_at": "2026-01-07T13:40:33.679530", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77001", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u5f20\u66fc\u7389\u51fa\u6f14\u4e86\u5f90\u514b\u5bfc\u6f14\u7684\u9752\u86c7\u3002\u4ee5\u4eba\u6027\uff0c\u795e\u6027\u7b49\u65b9\u9762\u6765\u63cf\u8ff0\u4e86\u6545\u4e8b\u4e2d\u7684\u4eba\u7269\u5173\u7cfb", "created_at": "2026-01-07T13:40:33.679530", "associative_memory": 2}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77002", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "\u5f20\u66fc\u7389\u51fa\u6f14\u4e86\u5f90\u514b\u5bfc\u6f14\u7684\u9752\u86c7\u3002", "created_at": "2026-01-07T13:40:33.679530", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u81ea\u5df1", "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77003", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "FACT", "statement": "\u6545\u4e8b\u4e2d\u7684\u4eba\u7269\u5173\u7cfb\u4ece\u4eba\u6027\u3001\u795e\u6027\u7b49\u65b9\u9762\u88ab\u63cf\u8ff0\u3002", "created_at": "2026-01-07T13:40:33.679530", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u4e8b\u7269\u5bf9\u8c61", "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77015", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u5c0f\u7eff\u4e0d\u559c\u6b22\u770b\u6050\u6016\u7247", "created_at": "2026-01-12T10:38:44.913286", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77016", "label": "ExtractedEntity", "properties": {"description": "\u4e2d\u56fd\u8457\u540d\u5973\u6f14\u5458", "name": "\u5f20\u66fc\u7389", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T13:40:33.679530", "aliases": ["\u5f90\u514b"], "connect_strength": "strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77017", "label": "ExtractedEntity", "properties": {"description": "\u7531\u5f90\u514b\u5bfc\u6f14\u7684\u7535\u5f71\u4f5c\u54c1", "name": "\u9752\u86c7", "entity_type": "", "created_at": "2026-01-07T13:40:33.679530", "aliases": ["\u9752\u86c7\u7535\u5f71"], "connect_strength": "Strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77018", "label": "ExtractedEntity", "properties": {"description": "\u795e\u7684\u7279\u8d28\uff0c\u5982\u8d85\u51e1\u80fd\u529b\u3001\u4e0d\u673d\u3001\u795e\u5723\u6027", "name": "\u795e\u6027", "entity_type": "\u6982\u5ff5\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T13:40:33.679530", "connect_strength": "Strong", "associative_memory": 1}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77019", "label": "MemorySummary", "properties": {"content": "\u5f20\u66fc\u7389\u51fa\u6f14\u4e86\u5f90\u514b\u5bfc\u6f14\u7684\u7535\u5f71\u300a\u9752\u86c7\u300b\uff0c\u5f71\u7247\u901a\u8fc7\u4eba\u6027\u4e0e\u795e\u6027\u7684\u5bf9\u6bd4\u63a2\u8ba8\u4e86\u4eba\u7269\u5173\u7cfb\uff0c\u5c55\u73b0\u4e86\u89d2\u8272\u4e4b\u95f4\u590d\u6742\u7684\u60c5\u611f\u4e0e\u8eab\u4efd\u51b2\u7a81\u3002", "created_at": "2026-01-07T13:40:50.650486", "associative_memory": 2}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77020", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u4eca\u5929\u5468\u4e00\uff0c\u6211\u60f3\u53bb\u722c\u5c71", "created_at": "2026-01-07T16:44:09.602315", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77021", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u4eca\u5929\u5468\u4e00\uff0c\u6211\u60f3\u53bb\u722c\u5c71", "created_at": "2026-01-07T16:44:09.602315", "associative_memory": 2}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77022", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "\u4eca\u5929\u662f\u5468\u4e00\u3002", "valid_at": "2026-01-05T00:00:00+00:00", "created_at": "2026-01-07T16:44:09.602315", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u81ea\u5df1", "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77023", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "PREDICTION", "statement": "\u7528\u6237\u60f3\u53bb\u722c\u5c71\u3002", "valid_at": "2026-01-07T00:00:00+00:00", "created_at": "2026-01-07T16:44:09.602315", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77024", "label": "ExtractedEntity", "properties": {"description": "\u5f53\u524d\u65e5\u671f\uff0c\u6307\u8bf4\u8bdd\u65f6\u7684\u5f53\u5929", "name": "\u4eca\u5929", "entity_type": "\u65f6\u95f4\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T16:44:09.602315", "aliases": ["\u5468\u4e00", "\u661f\u671f\u4e00"], "connect_strength": "strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77025", "label": "ExtractedEntity", "properties": {"description": "\u8bf4\u8bdd\u7684\u672c\u4eba\uff0c\u8ba1\u5212\u53c2\u4e0e\u722c\u5c71\u6d3b\u52a8", "name": "\u7528\u6237", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T16:44:09.602315", "aliases": ["\u5c0f\u660e"], "connect_strength": "Strong", "associative_memory": 6}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77026", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u6237\u5916\u767b\u5c71\u8fd0\u52a8", "name": "\u722c\u5c71", "entity_type": "", "created_at": "2026-01-07T16:44:09.602315", "aliases": ["\u767b\u5c71"], "connect_strength": "Strong", "associative_memory": 1}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77027", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u5728\u5468\u4e00\u8868\u793a\u60f3\u53bb\u722c\u5c71\u3002", "created_at": "2026-01-07T16:44:54.146672", "associative_memory": 2}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77028", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u5c0f\u7eff\u4e0d\u559c\u6b22\u770b\u6050\u6016\u7247", "created_at": "2026-01-12T10:38:44.913286", "associative_memory": 1}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77029", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "OPINION", "statement": "\u5c0f\u7eff\u4e0d\u559c\u6b22\u770b\u6050\u6016\u7247\u3002", "created_at": "2026-01-12T10:38:44.913286", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77030", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u4e2a\u7528\u6237\u63d0\u5230\u7684\u4eba\u7269", "name": "\u5c0f\u7eff", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-12T10:38:44.913286", "connect_strength": "Strong", "associative_memory": 3}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77031", "label": "ExtractedEntity", "properties": {"description": "\u89c2\u770b\u6050\u6016\u7535\u5f71\u7684\u6d3b\u52a8", "name": "\u770b\u6050\u6016\u7247", "entity_type": "", "created_at": "2026-01-12T10:38:44.913286", "aliases": ["\u770b\u6050\u6016\u7535\u5f71", "\u89c2\u770b\u6050\u6016\u7247"], "connect_strength": "Strong", "associative_memory": 1}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77032", "label": "MemorySummary", "properties": {"content": "\u5c0f\u7eff\u4e0d\u559c\u6b22\u770b\u6050\u6016\u7247", "created_at": "2026-01-12T10:38:54.849079", "associative_memory": 1}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77033", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u5c0f\u7eff\u6253\u7b97\u548c\u5c0f\u660e\u53bb\u722c\u5c71", "created_at": "2026-01-12T10:40:16.459309", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77034", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u5c0f\u7eff\u6253\u7b97\u548c\u5c0f\u660e\u53bb\u722c\u5c71", "created_at": "2026-01-12T10:40:16.459309", "associative_memory": 1}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77035", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "PREDICTION", "statement": "\u5c0f\u7eff\u6253\u7b97\u548c\u5c0f\u660e\u53bb\u722c\u5c71\u3002", "valid_at": "2026-01-12T00:00:00+00:00", "created_at": "2026-01-12T10:40:16.459309", "emotion_keywords": [], "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77036", "label": "ExtractedEntity", "properties": {"description": "\u6237\u5916\u81ea\u7136\u5730\u5f62\uff0c\u7528\u4e8e\u722c\u5c71\u6d3b\u52a8", "name": "\u5c71", "entity_type": "\u5730\u70b9\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-12T10:40:16.459309", "aliases": ["\u5c71\u8109", "\u9ad8\u5c71"], "connect_strength": "Strong", "associative_memory": 2}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77037", "label": "MemorySummary", "properties": {"content": "\u5c0f\u7eff\u6253\u7b97\u548c\u5c0f\u660e\u53bb\u722c\u5c71\u3002", "created_at": "2026-01-12T10:40:36.429460", "associative_memory": 1}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77038", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u6211\u6253\u7b97\u548c\u5c0f\u660e\u4ee5\u53ca\u5c0f\u7ea2\u53bb\u722c\u5c71", "created_at": "2026-01-12T11:21:39.219607", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77039", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u6211\u6253\u7b97\u548c\u5c0f\u660e\u4ee5\u53ca\u5c0f\u7ea2\u53bb\u722c\u5c71", "created_at": "2026-01-12T11:21:39.219607", "associative_memory": 1}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77040", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "PREDICTION", "statement": "\u7528\u6237\u6253\u7b97\u548c\u5c0f\u660e\u4ee5\u53ca\u5c0f\u7ea2\u53bb\u722c\u5c71\u3002", "valid_at": "2026-01-12T00:00:00+00:00", "created_at": "2026-08-12T11:21:39.219607+00:00", "emotion_keywords": [], "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77041", "label": "ExtractedEntity", "properties": {"description": "\u88ab\u63d0\u53ca\u7684\u53e6\u4e00\u4e2a\u4eba\u7269\uff0c\u53ef\u80fd\u662f\u670b\u53cb\u6216\u540c\u4f34", "name": "\u5c0f\u7ea2", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-12T11:21:39.219607", "connect_strength": "Strong", "associative_memory": 4}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77042", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u8ba1\u5212\u4e0e\u5c0f\u660e\u548c\u5c0f\u7ea2\u4e00\u8d77\u53bb\u722c\u5c71\u3002", "created_at": "2026-01-12T11:21:56.346023", "associative_memory": 1}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77043", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u6211\u8fd8\u60f3\u548c\u5c0f\u7ea2\u53bb\u770b\u7535\u5f71", "created_at": "2026-01-12T11:23:35.894508", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77044", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u6211\u8fd8\u60f3\u548c\u5c0f\u7ea2\u53bb\u770b\u7535\u5f71", "created_at": "2026-01-12T11:23:35.894508", "associative_memory": 1}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77045", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "PREDICTION", "statement": "\u7528\u6237\u8fd8\u60f3\u548c\u5c0f\u7ea2\u53bb\u770b\u7535\u5f71\u3002", "valid_at": "2026-01-12T00:00:00+00:00", "created_at": "2026-01-12T11:23:35.894508", "emotion_keywords": ["\u60f3"], "emotion_type": "\u6109\u5feb", "emotion_subject": "\u81ea\u5df1", "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77046", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u5a31\u4e50\u6d3b\u52a8\uff0c\u6307\u89c2\u770b\u7535\u5f71\u7684\u884c\u4e3a", "name": "\u7535\u5f71", "entity_type": "\u4e8b\u4ef6\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-12T11:23:35.894508", "aliases": ["\u5f71\u7247", "\u7535\u5f71\u653e\u6620"], "connect_strength": "Strong", "associative_memory": 1}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77047", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u60f3\u548c\u5c0f\u7ea2\u4e00\u8d77\u53bb\u770b\u7535\u5f71\u3002", "created_at": "2026-01-12T11:23:47.907049", "associative_memory": 1}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77048", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u6211\u8fd8\u60f3\u548c\u5c0f\u7ea2\u53bb\u6e38\u6e56", "created_at": "2026-01-12T11:43:22.323255", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77049", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u6211\u8fd8\u60f3\u548c\u5c0f\u7ea2\u53bb\u6e38\u6e56", "created_at": "2026-01-12T11:43:22.323255", "associative_memory": 1}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77050", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "PREDICTION", "statement": "\u7528\u6237\u8fd8\u60f3\u548c\u5c0f\u7ea2\u53bb\u6e38\u6e56\u3002", "valid_at": "2026-01-12T00:00:00+00:00", "created_at": "2026-01-12T11:43:22.323255", "emotion_keywords": ["\u60f3"], "emotion_type": "\u6109\u5feb", "emotion_subject": "\u81ea\u5df1", "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77051", "label": "ExtractedEntity", "properties": {"description": "\u81ea\u7136\u6c34\u4f53\uff0c\u7528\u4e8e\u6e38\u61a9\u6d3b\u52a8\u7684\u6e56\u6cca", "name": "\u6e56", "entity_type": "\u5730\u70b9\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-12T11:43:22.323255", "aliases": ["\u6e56\u6cca"], "connect_strength": "Strong", "associative_memory": 1}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77052", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u60f3\u548c\u5c0f\u7ea2\u4e00\u8d77\u53bb\u6e38\u6e56\u3002", "created_at": "2026-01-12T11:43:37.367749", "associative_memory": 1}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77054", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u60a8\u597d\u6211\u53eb\u5c0f\u84dd\uff0c\u5c0f\u660e\u4eca\u5929\u7ea6\u6211\u51fa\u53bb\u91ce\u9910\uff0c\u4f46\u662f\u5c0f\u7eff\u7ea6\u6211\u51fa\u53bb\u770b\u7535\u5f71\uff0c\u6211\u5f88\u72b9\u8c6b\uff0c\u6240\u4ee5\u6211\u548c\u6211\u59d0\u59d0\u5c0f\u7ea2\u51fa\u53bb\u770b\u620f", "created_at": "2026-01-07T19:14:34.489524", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77055", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u60a8\u597d\u6211\u53eb\u5c0f\u84dd\uff0c\u5c0f\u660e\u4eca\u5929\u7ea6\u6211\u51fa\u53bb\u91ce\u9910\uff0c\u4f46\u662f\u5c0f\u7eff\u7ea6\u6211\u51fa\u53bb\u770b\u7535\u5f71\uff0c\u6211\u5f88\u72b9\u8c6b\uff0c\u6240\u4ee5\u6211\u548c\u6211\u59d0\u59d0\u5c0f\u7ea2\u51fa\u53bb\u770b\u620f", "created_at": "2026-01-07T19:14:34.489524", "associative_memory": 5}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77056", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "FACT", "statement": "\u5c0f\u84dd\u53eb\u5c0f\u84dd\u3002", "created_at": "2026-01-07T19:14:34.489524", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u81ea\u5df1", "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77057", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u4eca\u5929\u7ea6\u5c0f\u84dd\u51fa\u53bb\u91ce\u9910\u3002", "valid_at": "2026-01-07T00:00:00+00:00", "created_at": "2026-01-07T19:14:34.489524", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u522b\u4eba", "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77058", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "\u5c0f\u7eff\u7ea6\u5c0f\u84dd\u51fa\u53bb\u770b\u7535\u5f71\u3002", "created_at": "2026-01-07T19:14:34.489524", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u522b\u4eba", "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77059", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "OPINION", "statement": "\u5c0f\u84dd\u5bf9\u662f\u5426\u53bb\u91ce\u9910\u6216\u770b\u7535\u5f71\u611f\u5230\u72b9\u8c6b\u3002", "valid_at": "2026-01-07T00:00:00+00:00", "created_at": "2026-01-07T19:14:34.489524", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u522b\u4eba", "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77060", "label": "Statement", "properties": {"temporal_info": "STATIC", "stmt_type": "FACT", "statement": "\u5c0f\u84dd\u548c\u5979\u59d0\u59d0\u5c0f\u7ea2\u51fa\u53bb\u770b\u620f\u3002", "created_at": "2026-01-07T19:14:34.489524", "emotion_keywords": [], "emotion_type": "\u4e2d\u6027", "emotion_subject": "\u522b\u4eba", "associative_memory": 5}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77061", "label": "ExtractedEntity", "properties": {"description": "\u5bf9\u8bdd\u4e2d\u7684\u7528\u6237\uff0c\u6536\u5230\u91ce\u9910\u548c\u770b\u7535\u5f71\u9080\u7ea6\u7684\u4eba", "name": "\u5c0f\u84dd", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T19:14:34.489524", "aliases": ["\u5c0f\u7eff"], "connect_strength": "strong", "associative_memory": 9}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77062", "label": "ExtractedEntity", "properties": {"description": "\u5728\u5f71\u9662\u6216\u5bb6\u4e2d\u89c2\u770b\u7535\u5f71\u7684\u5a31\u4e50\u6d3b\u52a8", "name": "\u91ce\u9910", "entity_type": "\u4e8b\u4ef6\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T19:14:34.489524", "aliases": ["\u53bb\u91ce\u9910", "\u770b\u620f", "\u770b\u7535\u5f71"], "connect_strength": "strong", "associative_memory": 4}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77063", "label": "ExtractedEntity", "properties": {"description": "\u7528\u4e8e\u89c2\u770b\u7535\u5f71\u7684\u573a\u6240", "name": "\u7535\u5f71\u9662", "entity_type": "\u5730\u70b9\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-07T19:14:34.489524", "aliases": ["\u5f71\u9662"], "connect_strength": "Strong", "associative_memory": 1}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77064", "label": "MemorySummary", "properties": {"content": "\u5c0f\u84dd\u4eca\u5929\u539f\u8ba1\u5212\u4e0e\u5c0f\u660e\u91ce\u9910\u3001\u4e0e\u5c0f\u7eff\u770b\u7535\u5f71\uff0c\u4f46\u6700\u7ec8\u9009\u62e9\u4e0e\u59d0\u59d0\u5c0f\u7ea2\u4e00\u8d77\u770b\u620f\u3002", "created_at": "2026-01-07T19:14:58.086704", "associative_memory": 5}, "caption": "MemorySummary"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77133", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u5f88\u591a\u91cd\u8981\u7684\u4eba\u751f\u9009\u62e9\uff0c\u5176\u5b9e\u5c31\u50cf\u4e00\u6b21\u590d\u6742\u7684\u9884\u6d4b\u4efb\u52a1\u3002\u6700\u5f00\u59cb\u51fa\u73b0\u7684\u90a3\u70b9\u4e0d\u5b89\uff0c\u7c7b\u4f3c\u4e8e\u6a21\u578b\u53d1\u73b0\u4e86\u5f02\u5e38\u4fe1\u53f7\uff1b\u56de\u987e\u8fc7\u53bb\u7684\u7ecf\u5386\uff0c\u662f\u5728\u56de\u6eaf\u5386\u53f2\u6570\u636e\u3001\u505a\u7279\u5f81\u63d0\u53d6\uff1b\u5bf9\u6bd4\u90a3\u4e9b\u8ba9\u4eba\u8e0f\u5b9e\u6216\u540e\u6094\u7684\u51b3\u5b9a\uff0c\u76f8\u5f53\u4e8e\u5728\u4e0d\u540c\u6837\u672c\u4e0a\u8bc4\u4f30\u635f\u5931\u51fd\u6570\uff1b\u800c\u628a\u65f6\u95f4\u62c9\u957f\u53bb\u60f3\u4e00\u5e74\u3001\u4e09\u5e74\u3001\u4e94\u5e74\u540e\u7684\u7ed3\u679c\uff0c\u5219\u662f\u5728\u4e0d\u540c\u65f6\u95f4\u7a97\u53e3\u4e0b\u505a\u957f\u671f\u4e0e\u77ed\u671f\u6536\u76ca\u7684\u6743\u8861\u3002\u7b49\u8fd9\u4e9b\u6b65\u9aa4\u90fd\u8d70\u8fc7\u4e4b\u540e\uff0c\u6240\u8c13\u201c\u7b54\u6848\u201d\uff0c\u5e76\u4e0d\u662f\u88ab\u76f4\u63a5\u7b97\u51fa\u6765\u7684\uff0c\u800c\u662f\u6a21\u578b\u5728\u591a\u6b21\u62c6\u89e3\u4e0e\u8fed\u4ee3\u4e2d\u9010\u6e10\u6536\u655b\u5230\u7684\u7ed3\u679c\u3002", "created_at": "2026-01-06T19:24:55.805367", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77134", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u5f88\u591a\u91cd\u8981\u7684\u4eba\u751f\u9009\u62e9\uff0c\u5176\u5b9e\u5c31\u50cf\u4e00\u6b21\u590d\u6742\u7684\u9884\u6d4b\u4efb\u52a1\u3002\u6700\u5f00\u59cb\u51fa\u73b0\u7684\u90a3\u70b9\u4e0d\u5b89\uff0c\u7c7b\u4f3c\u4e8e\u6a21\u578b\u53d1\u73b0\u4e86\u5f02\u5e38\u4fe1\u53f7\uff1b\u56de\u987e\u8fc7\u53bb\u7684\u7ecf\u5386\uff0c\u662f\u5728\u56de\u6eaf\u5386\u53f2\u6570\u636e\u3001\u505a\u7279\u5f81\u63d0\u53d6\uff1b\u5bf9\u6bd4\u90a3\u4e9b\u8ba9\u4eba\u8e0f\u5b9e\u6216\u540e\u6094\u7684\u51b3\u5b9a\uff0c\u76f8\u5f53\u4e8e\u5728\u4e0d\u540c\u6837\u672c\u4e0a\u8bc4\u4f30\u635f\u5931\u51fd\u6570\uff1b\u800c\u628a\u65f6\u95f4\u62c9\u957f\u53bb\u60f3\u4e00\u5e74\u3001\u4e09\u5e74\u3001\u4e94\u5e74\u540e\u7684\u7ed3\u679c\uff0c\u5219\u662f\u5728\u4e0d\u540c\u65f6\u95f4\u7a97\u53e3\u4e0b\u505a\u957f\u671f\u4e0e\u77ed\u671f\u6536\u76ca\u7684\u6743\u8861\u3002\u7b49\u8fd9\u4e9b\u6b65\u9aa4\u90fd\u8d70\u8fc7\u4e4b\u540e\uff0c\u6240\u8c13\u201c\u7b54\u6848\u201d\uff0c\u5e76\u4e0d\u662f\u88ab\u76f4\u63a5\u7b97\u51fa\u6765\u7684\uff0c\u800c\u662f\u6a21\u578b\u5728\u591a\u6b21\u62c6\u89e3\u4e0e\u8fed\u4ee3\u4e2d\u9010\u6e10\u6536\u655b\u5230\u7684\u7ed3\u679c\u3002", "created_at": "2026-01-06T19:24:55.805367", "associative_memory": 6}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77135", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "OPINION", "statement": "\u5f88\u591a\u91cd\u8981\u7684\u4eba\u751f\u9009\u62e9\u5c31\u50cf\u4e00\u6b21\u590d\u6742\u7684\u9884\u6d4b\u4efb\u52a1\u3002", "created_at": "2026-01-06T19:24:55.805367", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77136", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "OPINION", "statement": "\u6700\u5f00\u59cb\u51fa\u73b0\u7684\u90a3\u70b9\u4e0d\u5b89\u7c7b\u4f3c\u4e8e\u6a21\u578b\u53d1\u73b0\u4e86\u5f02\u5e38\u4fe1\u53f7\u3002", "created_at": "2026-01-06T19:24:55.805367", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77137", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "OPINION", "statement": "\u56de\u987e\u8fc7\u53bb\u7684\u7ecf\u5386\u662f\u5728\u56de\u6eaf\u5386\u53f2\u6570\u636e\u5e76\u505a\u7279\u5f81\u63d0\u53d6\u3002", "created_at": "2026-01-06T19:24:55.805367", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77138", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "OPINION", "statement": "\u5bf9\u6bd4\u90a3\u4e9b\u8ba9\u4eba\u8e0f\u5b9e\u6216\u540e\u6094\u7684\u51b3\u5b9a\u76f8\u5f53\u4e8e\u5728\u4e0d\u540c\u6837\u672c\u4e0a\u8bc4\u4f30\u635f\u5931\u51fd\u6570\u3002", "created_at": "2026-01-06T19:24:55.805367", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77139", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "OPINION", "statement": "\u628a\u65f6\u95f4\u62c9\u957f\u53bb\u60f3\u4e00\u5e74\u3001\u4e09\u5e74\u3001\u4e94\u5e74\u540e\u7684\u7ed3\u679c\u662f\u5728\u4e0d\u540c\u65f6\u95f4\u7a97\u53e3\u4e0b\u505a\u957f\u671f\u4e0e\u77ed\u671f\u6536\u76ca\u7684\u6743\u8861\u3002", "created_at": "2026-01-06T19:24:55.805367", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77140", "label": "Statement", "properties": {"temporal_info": "ATEMPORAL", "stmt_type": "OPINION", "statement": "\u6240\u8c13\u201c\u7b54\u6848\u201d\u5e76\u4e0d\u662f\u88ab\u76f4\u63a5\u7b97\u51fa\u6765\u7684\uff0c\u800c\u662f\u6a21\u578b\u5728\u591a\u6b21\u62c6\u89e3\u4e0e\u8fed\u4ee3\u4e2d\u9010\u6e10\u6536\u655b\u5230\u7684\u7ed3\u679c\u3002", "created_at": "2026-01-06T19:24:55.805367", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77141", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:41:05.181477", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77142", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:41:05.181477", "associative_memory": 2}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77143", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\u3002", "created_at": "2026-01-06T14:41:05.181477", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77144", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "valid_at": "2026-01-06T00:00:00+00:00", "created_at": "2026-01-06T14:41:05.181477", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77145", "label": "ExtractedEntity", "properties": {"description": "\u53c2\u4e0e\u5bf9\u8bdd\u7684\u4e2a\u4eba\uff0c\u53d1\u51fa\u91ce\u9910\u9080\u7ea6\u7684\u4e00\u65b9", "name": "\u5c0f\u660e", "entity_type": "\u4eba\u7269\u5b9e\u4f53\u8282\u70b9", "created_at": "2026-01-06T14:41:05.181477", "aliases": ["\u5c0f\u7ea2"], "connect_strength": "strong", "associative_memory": 13}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77146", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u5e38\u89c1\u7684\u542b\u5496\u5561\u56e0\u996e\u54c1", "name": "\u5496\u5561", "entity_type": "", "created_at": "2026-01-06T14:41:05.181477", "aliases": ["\u5496\u5561\u996e\u6599"], "connect_strength": "Strong", "associative_memory": 3}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77147", "label": "ExtractedEntity", "properties": {"description": "\u4e00\u79cd\u5496\u5561\u996e\u54c1\uff0c\u7531\u6d53\u7f29\u5496\u5561\u548c\u725b\u5976\u5236\u6210", "name": "\u62ff\u94c1", "entity_type": "", "created_at": "2026-01-06T14:41:05.181477", "aliases": ["\u62ff\u94c1\u5496\u5561", "Latte"], "connect_strength": "Strong", "associative_memory": 3}, "caption": "ExtractedEntity"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77148", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:44:22.921668", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77149", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:44:22.921668", "associative_memory": 2}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77150", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\u3002", "valid_at": "2026-01-06T00:00:00+00:00", "created_at": "2026-01-06T14:44:22.921668", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77151", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "valid_at": "2026-01-06T00:00:00+00:00", "created_at": "2026-01-06T14:44:22.921668", "emotion_keywords": [], "associative_memory": 3}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77152", "label": "Dialogue", "properties": {"content": "\u7528\u6237: \u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:46:02.387455", "associative_memory": 0}, "caption": "Dialogue"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77153", "label": "Chunk", "properties": {"content": "\u7528\u6237: \u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:46:02.387455", "associative_memory": 2}, "caption": "Chunk"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77154", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\u3002", "valid_at": "2026-01-06T00:00:00+00:00", "created_at": "2026-01-06T14:46:02.387455", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77155", "label": "Statement", "properties": {"temporal_info": "DYNAMIC", "stmt_type": "FACT", "statement": "\u5c0f\u660e\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:46:02.387455", "emotion_keywords": [], "associative_memory": 4}, "caption": "Statement"}, {"id": "4:f6039a9b-d553-4ba2-9b1c-d9a18917801f:77156", "label": "MemorySummary", "properties": {"content": "\u7528\u6237\u5c0f\u660e\u559c\u6b22\u559d\u5496\u5561\uff0c\u6bcf\u5929\u90fd\u8981\u559d\u62ff\u94c1\u3002", "created_at": "2026-01-06T14:46:16.548556", "associative_memory": 2}, + "caption": "MemorySummary"}] + + result=asyncio.run(Translation_English("2699984d-23be-4817-b81c-c38682a08306",a)) + print(result) \ No newline at end of file diff --git a/api/app/services/memory_entity_relationship_service.py b/api/app/services/memory_entity_relationship_service.py index eedb7c29..f544cb75 100644 --- a/api/app/services/memory_entity_relationship_service.py +++ b/api/app/services/memory_entity_relationship_service.py @@ -16,6 +16,7 @@ import json from datetime import datetime from app.schemas.memory_episodic_schema import EmotionType +from app.services.memory_base_service import Translation_English logger = logging.getLogger(__name__) @@ -24,7 +25,7 @@ class MemoryEntityService: self.id = id self.table = table self.connector = Neo4jConnector() - async def get_timeline_memories_server(self): + async def get_timeline_memories_server(self,model_id, language_type): """ 获取时间线记忆数据 @@ -48,10 +49,10 @@ class MemoryEntityService: logger.info(f"获取时间线记忆数据 - ID: {self.id}, Table: {self.table}") # 根据表类型选择查询 - if self.table == 'Statement': + if self.table == 'Statement': # Statement只需要输入ID,使用简化查询 results = await self.connector.execute_query(Memory_Timeline_Statement, id=self.id) - elif self.table == 'ExtractedEntity': + elif self.table == 'ExtractedEntity': # ExtractedEntity类型查询 results = await self.connector.execute_query(Memory_Timeline_ExtractedEntity, id=self.id) else: @@ -62,7 +63,7 @@ class MemoryEntityService: logger.info(f"时间线查询结果类型: {type(results)}, 长度: {len(results) if isinstance(results, list) else 'N/A'}") # 处理查询结果 - timeline_data = self._process_timeline_results(results) + timeline_data =await self._process_timeline_results(results, model_id, language_type) logger.info(f"成功获取时间线记忆数据: 总计 {len(timeline_data.get('timelines_memory', []))} 条") @@ -71,12 +72,14 @@ class MemoryEntityService: except Exception as e: logger.error(f"获取时间线记忆数据失败: {str(e)}", exc_info=True) return str(e) - def _process_timeline_results(self, results: List[Dict[str, Any]]) -> Dict[str, Any]: + async def _process_timeline_results(self, results: List[Dict[str, Any]], model_id: str, language_type: str) -> Dict[str, Any]: """ 处理时间线查询结果 Args: results: Neo4j查询结果 + model_id: 模型ID用于翻译 + language_type: 语言类型 ('zh' 或其他) Returns: 处理后的时间线数据字典 @@ -104,19 +107,19 @@ class MemoryEntityService: # 处理MemorySummary summary = data.get('MemorySummary') if summary is not None: - processed_summary = self._process_field_value(summary, "MemorySummary") + processed_summary = await self._process_field_value(summary, "MemorySummary") memory_summary_list.extend(processed_summary) # 处理Statement statement = data.get('statement') if statement is not None: - processed_statement = self._process_field_value(statement, "Statement") + processed_statement = await self._process_field_value(statement, "Statement") statement_list.extend(processed_statement) # 处理ExtractedEntity extracted_entity = data.get('ExtractedEntity') if extracted_entity is not None: - processed_entity = self._process_field_value(extracted_entity, "ExtractedEntity") + processed_entity = await self._process_field_value(extracted_entity, "ExtractedEntity") extracted_entity_list.extend(processed_entity) # 去重 - 现在处理的是字典列表,需要更智能的去重 @@ -128,6 +131,21 @@ class MemoryEntityService: all_timeline_data = memory_summary_list + statement_list all_timeline_data = self._merge_same_text_items(all_timeline_data) + # 如果需要翻译(非中文),对整个结果进行翻译 + if language_type != 'zh': + # 定义需要翻译的字段 + fields_to_translate = ['text', 'type'] + + # 翻译各个列表 + if memory_summary_list: + memory_summary_list = await self._translate_list(memory_summary_list, model_id, fields_to_translate) + if statement_list: + statement_list = await self._translate_list(statement_list, model_id, fields_to_translate) + if extracted_entity_list: + extracted_entity_list = await self._translate_list(extracted_entity_list, model_id, fields_to_translate) + if all_timeline_data: + all_timeline_data = await self._translate_list(all_timeline_data, model_id, fields_to_translate) + result = { "MemorySummary": memory_summary_list, "Statement": statement_list, @@ -233,7 +251,7 @@ class MemoryEntityService: except Exception: return False - def _process_field_value(self, value: Any, field_name: str) -> List[Dict[str, Any]]: + async def _process_field_value(self, value: Any, field_name: str) -> List[Dict[str, Any]]: """ 处理字段值,支持字符串、列表等类型 @@ -251,13 +269,13 @@ class MemoryEntityService: # 如果是列表,处理每个元素 for item in value: if self._is_valid_item(item): - processed_item = self._process_single_item(item) + processed_item = await self._process_single_item(item) if processed_item: processed_values.append(processed_item) elif isinstance(value, dict): # 如果是字典,直接处理 if self._is_valid_item(value): - processed_item = self._process_single_item(value) + processed_item = await self._process_single_item(value) if processed_item: processed_values.append(processed_item) elif isinstance(value, str): @@ -304,7 +322,7 @@ class MemoryEntityService: return (str(item).strip() != '' and "MemorySummaryChunk" not in str(item)) - def _process_single_item(self, item: Dict[str, Any]) -> Optional[Dict[str, Any]]: + async def _process_single_item(self, item: Dict[str, Any]) -> Optional[Dict[str, Any]]: """ 处理单个项目 @@ -369,6 +387,42 @@ class MemoryEntityService: logger.warning(f"转换时间格式失败: {e}, 原始值: {dt}") return str(dt) if dt is not None else None + async def _translate_list(self, data_list: List[Dict[str, Any]], model_id: str, fields: List[str]) -> List[Dict[str, Any]]: + """ + 翻译列表中每个字典的指定字段 + + Args: + data_list: 要翻译的字典列表 + model_id: 模型ID + fields: 需要翻译的字段列表 + + Returns: + 翻译后的字典列表 + """ + if not data_list: + return data_list + + translated_list = [] + for item in data_list: + if not isinstance(item, dict): + translated_list.append(item) + continue + + translated_item = item.copy() + for field in fields: + if field in translated_item and translated_item[field]: + try: + # 调用Translation_English翻译单个字段 + translated_value = await Translation_English(model_id, translated_item[field]) + if translated_value: + translated_item[field] = translated_value + except Exception as e: + logger.warning(f"翻译字段 {field} 失败: {e}") + + translated_list.append(translated_item) + + return translated_list + @@ -426,15 +480,19 @@ class MemoryEmotion: # 如果解析失败,返回原始字符串 return iso_string - async def get_emotion(self) -> Dict[str, Any]: + async def get_emotion(self, model_id: str = None, language_type: str = 'zh') -> Dict[str, Any]: """ 获取情绪随时间变化数据 + Args: + model_id: 模型ID用于翻译 + language_type: 语言类型 ('zh' 或其他) + Returns: 包含情绪数据的字典 """ try: - logger.info(f"获取情绪数据 - ID: {self.id}, Table: {self.table}") + logger.info(f"获取情绪数据 - ID: {self.id}, Table: {self.table}, language_type={language_type}") if self.table == 'Statement': results = await self.connector.execute_query(Memory_Space_Emotion_Statement, id=self.id) @@ -450,6 +508,10 @@ class MemoryEmotion: # 转换Neo4j类型 final_data = self._convert_neo4j_types(emotion_data) + # 如果需要翻译(非中文) + if language_type != 'zh' and model_id and final_data: + final_data = await self._translate_emotion_data(final_data, model_id) + logger.info(f"成功获取 {len(final_data)} 条情绪数据") return final_data @@ -590,16 +652,14 @@ class MemoryInteraction: """ try: logger.info(f"获取交互数据 - ID: {self.id}, Table: {self.table}") - ori_data= await self.connector.execute_query(Memory_Space_Entity, id=self.id) if ori_data!=[]: # name = ori_data[0]['name'] - group_id = ori_data[0]['group_id'] + group_id = [i['group_id'] for i in ori_data][0] Space_User = await self.connector.execute_query(Memory_Space_User, group_id=group_id) if not Space_User: return [] user_id=Space_User[0]['id'] - results = await self.connector.execute_query(Memory_Space_Associative, id=self.id,user_id=user_id) diff --git a/api/app/services/user_memory_service.py b/api/app/services/user_memory_service.py index 9221ab06..ae07256a 100644 --- a/api/app/services/user_memory_service.py +++ b/api/app/services/user_memory_service.py @@ -18,7 +18,7 @@ from app.repositories.end_user_repository import EndUserRepository from app.repositories.neo4j.neo4j_connector import Neo4jConnector from app.schemas.memory_episodic_schema import EmotionSubject, EmotionType, type_mapping from app.services.implicit_memory_service import ImplicitMemoryService -from app.services.memory_base_service import MemoryBaseService +from app.services.memory_base_service import MemoryBaseService, MemoryTransService, Translation_English from app.services.memory_config_service import MemoryConfigService from app.services.memory_perceptual_service import MemoryPerceptualService from app.services.memory_short_service import ShortService @@ -360,7 +360,9 @@ class UserMemoryService: async def get_cached_memory_insight( self, db: Session, - end_user_id: str + end_user_id: str, + model_id: str, + language_type: str ) -> Dict[str, Any]: """ 从数据库获取缓存的记忆洞察(四个维度) @@ -419,11 +421,18 @@ class UserMemoryService: key_findings_array = [] logger.info(f"成功获取 end_user_id {end_user_id} 的缓存记忆洞察(四维度)") + memory_insight=end_user.memory_insight + behavior_pattern=end_user.behavior_pattern + growth_trajectory=end_user.growth_trajectory + if language_type!='zh': + memory_insight=await Translation_English(model_id,memory_insight) + behavior_pattern=await Translation_English(model_id,behavior_pattern) + growth_trajectory=await Translation_English(model_id,growth_trajectory) return { - "memory_insight": end_user.memory_insight, # 总体概述存储在 memory_insight - "behavior_pattern": end_user.behavior_pattern, + "memory_insight":memory_insight, # 总体概述存储在 memory_insight + "behavior_pattern":behavior_pattern, "key_findings": key_findings_array, # 返回数组 - "growth_trajectory": end_user.growth_trajectory, + "growth_trajectory": growth_trajectory, "updated_at": self._datetime_to_timestamp(end_user.memory_insight_updated_at), "is_cached": True } @@ -457,7 +466,9 @@ class UserMemoryService: async def get_cached_user_summary( self, db: Session, - end_user_id: str + end_user_id: str, + model_id:str, + language_type:str="zh" ) -> Dict[str, Any]: """ 从数据库获取缓存的用户摘要(四个部分) @@ -481,7 +492,6 @@ class UserMemoryService: user_uuid = uuid.UUID(end_user_id) repo = EndUserRepository(db) end_user = repo.get_by_id(user_uuid) - if not end_user: logger.warning(f"未找到 end_user_id 为 {end_user_id} 的用户") return { @@ -495,20 +505,29 @@ class UserMemoryService: } # 检查是否有缓存数据(至少有一个字段不为空) + user_summary=end_user.user_summary + personality_traits=end_user.personality_traits + core_values=end_user.core_values + one_sentence_summary=end_user.one_sentence_summary + if language_type!='zh': + user_summary=await Translation_English(model_id, user_summary) + personality_traits = await Translation_English(model_id, personality_traits) + core_values = await Translation_English(model_id, core_values) + one_sentence_summary = await Translation_English(model_id, one_sentence_summary) has_cache = any([ - end_user.user_summary, - end_user.personality_traits, - end_user.core_values, - end_user.one_sentence_summary + user_summary, + personality_traits, + core_values, + one_sentence_summary ]) if has_cache: logger.info(f"成功获取 end_user_id {end_user_id} 的缓存用户摘要") return { - "user_summary": end_user.user_summary, - "personality": end_user.personality_traits, - "core_values": end_user.core_values, - "one_sentence": end_user.one_sentence_summary, + "user_summary": user_summary, + "personality": personality_traits, + "core_values":core_values, + "one_sentence": one_sentence_summary, "updated_at": self._datetime_to_timestamp(end_user.user_summary_updated_at), "is_cached": True } @@ -1367,7 +1386,6 @@ async def analytics_memory_types( return memory_types - async def analytics_graph_data( db: Session, end_user_id: str, @@ -1557,7 +1575,7 @@ async def analytics_graph_data( f"成功获取图数据: end_user_id={end_user_id}, " f"nodes={len(nodes)}, edges={len(edges)}" ) - + return { "nodes": nodes, "edges": edges, @@ -1606,11 +1624,7 @@ async def _extract_node_properties(label: str, properties: Dict[str, Any],node_ # 获取该节点类型的白名单字段 allowed_fields = field_whitelist.get(label, []) - - # 如果没有定义白名单,返回空字典(或者可以返回所有字段) - # if not allowed_fields: - # # 对于未定义的节点类型,只返回基本字段 - # allowed_fields = ["name", "created_at", "caption"] + count_neo4j=f"""MATCH (n)-[r]-(m) WHERE elementId(n) ="{node_id}" RETURN count(r) AS rel_count;""" node_results = await (_neo4j_connector.execute_query(count_neo4j)) # 提取白名单中的字段 @@ -1618,13 +1632,12 @@ async def _extract_node_properties(label: str, properties: Dict[str, Any],node_ for field in allowed_fields: if field in properties: value = properties[field] - if str(field) == 'entity_type': + if str(field) == 'entity_type': value=type_mapping.get(value,'') if str(field)=="emotion_type": value=EmotionType.EMOTION_MAPPING.get(value) - if str(field)=="emotion_subject": + if str(field)=="emotion_subject": value=EmotionSubject.SUBJECT_MAPPING.get(value) - # 清理 Neo4j 特殊类型 filtered_props[field] = _clean_neo4j_value(value) filtered_props['associative_memory']=[i['rel_count'] for i in node_results][0] return filtered_props