From b471d56a86a8bbfffc3a9d353758a730ae6d71f3 Mon Sep 17 00:00:00 2001 From: Eternity <61316157+myhMARS@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:29:51 +0800 Subject: [PATCH] fix(prompt): remove hard-coded import of prompt file paths (#279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix/develop memory bug (#274) * 遗漏的历史映射 * 遗漏的历史映射 * fix_timeline_memories * fix(web): update retrieve_type key * Fix/develop memory bug (#276) * 遗漏的历史映射 * 遗漏的历史映射 * fix_timeline_memories * fix_timeline_memories * write_gragp/bug_fix * write_gragp/bug_fix * write_gragp/bug_fix * chore(celery): disable periodic task scheduling * fix(prompt): remove hard-coded import of prompt file paths --------- Co-authored-by: lixinyue11 <94037597+lixinyue11@users.noreply.github.com> Co-authored-by: zhaoying Co-authored-by: yingzhao Co-authored-by: Ke Sun --- api/app/celery_app.py | 67 ++++++++++--------- .../agent/langgraph_graph/write_graph.py | 14 +--- api/app/repositories/neo4j/cypher_queries.py | 9 ++- api/app/services/conversation_service.py | 7 +- api/app/services/memory_reflection_service.py | 17 +++-- api/app/services/prompt_optimizer_service.py | 6 +- .../Knowledge/KnowledgeListModal.tsx | 2 +- .../Knowledge/KnowledgeListModal.tsx | 2 +- .../views/Workflow/hooks/useWorkflowGraph.ts | 2 +- 9 files changed, 62 insertions(+), 64 deletions(-) diff --git a/api/app/celery_app.py b/api/app/celery_app.py index e880e7d0..3e7db8cb 100644 --- a/api/app/celery_app.py +++ b/api/app/celery_app.py @@ -3,9 +3,10 @@ import platform from datetime import timedelta from urllib.parse import quote -from app.core.config import settings from celery import Celery +from app.core.config import settings + # 创建 Celery 应用实例 # broker: 任务队列(使用 Redis DB 0) # backend: 结果存储(使用 Redis DB 10) @@ -79,40 +80,40 @@ celery_app.conf.update( celery_app.autodiscover_tasks(['app']) # Celery Beat schedule for periodic tasks -memory_increment_schedule = timedelta(hours=settings.MEMORY_INCREMENT_INTERVAL_HOURS) -memory_cache_regeneration_schedule = timedelta(hours=settings.MEMORY_CACHE_REGENERATION_HOURS) -workspace_reflection_schedule = timedelta(seconds=30) # 每30秒运行一次settings.REFLECTION_INTERVAL_TIME -forgetting_cycle_schedule = timedelta(hours=24) # 每24小时运行一次遗忘周期 +# memory_increment_schedule = timedelta(hours=settings.MEMORY_INCREMENT_INTERVAL_HOURS) +# memory_cache_regeneration_schedule = timedelta(hours=settings.MEMORY_CACHE_REGENERATION_HOURS) +# workspace_reflection_schedule = timedelta(seconds=30) # 每30秒运行一次settings.REFLECTION_INTERVAL_TIME +# forgetting_cycle_schedule = timedelta(hours=24) # 每24小时运行一次遗忘周期 # 构建定时任务配置 -beat_schedule_config = { - "run-workspace-reflection": { - "task": "app.tasks.workspace_reflection_task", - "schedule": workspace_reflection_schedule, - "args": (), - }, - "regenerate-memory-cache": { - "task": "app.tasks.regenerate_memory_cache", - "schedule": memory_cache_regeneration_schedule, - "args": (), - }, - "run-forgetting-cycle": { - "task": "app.tasks.run_forgetting_cycle_task", - "schedule": forgetting_cycle_schedule, - "kwargs": { - "config_id": None, # 使用默认配置,可以通过环境变量配置 - }, - }, -} +# beat_schedule_config = { +# "run-workspace-reflection": { +# "task": "app.tasks.workspace_reflection_task", +# "schedule": workspace_reflection_schedule, +# "args": (), +# }, +# "regenerate-memory-cache": { +# "task": "app.tasks.regenerate_memory_cache", +# "schedule": memory_cache_regeneration_schedule, +# "args": (), +# }, +# "run-forgetting-cycle": { +# "task": "app.tasks.run_forgetting_cycle_task", +# "schedule": forgetting_cycle_schedule, +# "kwargs": { +# "config_id": None, # 使用默认配置,可以通过环境变量配置 +# }, +# }, +# } # 如果配置了默认工作空间ID,则添加记忆总量统计任务 -if settings.DEFAULT_WORKSPACE_ID: - beat_schedule_config["write-total-memory"] = { - "task": "app.controllers.memory_storage_controller.search_all", - "schedule": memory_increment_schedule, - "kwargs": { - "workspace_id": settings.DEFAULT_WORKSPACE_ID, - }, - } +# if settings.DEFAULT_WORKSPACE_ID: +# beat_schedule_config["write-total-memory"] = { +# "task": "app.controllers.memory_storage_controller.search_all", +# "schedule": memory_increment_schedule, +# "kwargs": { +# "workspace_id": settings.DEFAULT_WORKSPACE_ID, +# }, +# } -celery_app.conf.beat_schedule = beat_schedule_config +# celery_app.conf.beat_schedule = beat_schedule_config diff --git a/api/app/core/memory/agent/langgraph_graph/write_graph.py b/api/app/core/memory/agent/langgraph_graph/write_graph.py index 5101fa29..d0e8a45d 100644 --- a/api/app/core/memory/agent/langgraph_graph/write_graph.py +++ b/api/app/core/memory/agent/langgraph_graph/write_graph.py @@ -39,7 +39,6 @@ async def make_write_graph(): graph = workflow.compile() yield graph - async def long_term_storage(long_term_type:str="chunk",langchain_messages:list=[],memory_config:str='',end_user_id:str='',scope:int=6): from app.core.memory.agent.langgraph_graph.routing.write_router import memory_long_term_storage, window_dialogue,aggregate_judgment from app.core.memory.agent.langgraph_graph.tools.write_tool import chat_data_format @@ -49,7 +48,7 @@ async def long_term_storage(long_term_type:str="chunk",langchain_messages:list=[ db_session = next(get_db()) config_service = MemoryConfigService(db_session) memory_config = config_service.load_memory_config( - config_id="08ed205c-0f05-49c3-8e0c-a580d28f5fd4", # 改为整数 + config_id=memory_config, # 改为整数 service_name="MemoryAgentService" ) if long_term_type=='chunk': @@ -63,7 +62,7 @@ async def long_term_storage(long_term_type:str="chunk",langchain_messages:list=[ """方案三:聚合判断""" await aggregate_judgment(end_user_id, langchain_messages, memory_config) -# + # async def main(): # """主函数 - 运行工作流""" # langchain_messages = [ @@ -80,14 +79,7 @@ async def long_term_storage(long_term_type:str="chunk",langchain_messages:list=[ # end_user_id = '837fee1b-04a2-48ee-94d7-211488908940' # 组ID # memory_config="08ed205c-0f05-49c3-8e0c-a580d28f5fd4" # # await long_term_storage(long_term_type="chunk",langchain_messages=langchain_messages,memory_config=memory_config,end_user_id=end_user_id,scope=2) -# from app.core.memory.agent.utils.redis_tool import write_store -# result=write_store.get_session_by_userid(end_user_id) -# data=await format_parsing(result,"dict") -# chunk_data=data[:6] -# -# long_time_data = write_store.find_user_recent_sessions(end_user_id, 240) -# long_=await messages_parse(long_time_data) -# print(long_) +# result=await long_term_storage(long_term_type="chunk",langchain_messages=langchain_messages,memory_config=memory_config,end_user_id=end_user_id,scope=2) # # # if __name__ == "__main__": diff --git a/api/app/repositories/neo4j/cypher_queries.py b/api/app/repositories/neo4j/cypher_queries.py index c93e75b3..cf1732fd 100644 --- a/api/app/repositories/neo4j/cypher_queries.py +++ b/api/app/repositories/neo4j/cypher_queries.py @@ -877,7 +877,8 @@ RETURN CASE WHEN ms:ExtractedEntity THEN { text: ms.name, - created_at: ms.created_at + created_at: ms.created_at, + type: "情景记忆" } END ) AS ExtractedEntity, @@ -887,7 +888,8 @@ RETURN CASE WHEN n:MemorySummary THEN { text: n.content, - created_at: n.created_at + created_at: n.created_at, + type: "长期沉淀" } END ) AS MemorySummary, @@ -895,7 +897,8 @@ RETURN collect( DISTINCT { text: e.statement, - created_at: e.created_at + created_at: e.created_at, + type: "情绪记忆" } ) AS statement; """ diff --git a/api/app/services/conversation_service.py b/api/app/services/conversation_service.py index 526e0fe2..553aefc4 100644 --- a/api/app/services/conversation_service.py +++ b/api/app/services/conversation_service.py @@ -1,4 +1,5 @@ """会话服务""" +import os import uuid from datetime import datetime, timedelta from typing import Annotated @@ -529,12 +530,12 @@ class ConversationService: takeaways=[], info_score=0, ) - - with open('app/services/prompt/conversation_summary_system.jinja2', 'r', encoding='utf-8') as f: + prompt_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'prompt') + with open(os.path.join(prompt_path, 'conversation_summary_system.jinja2'), 'r', encoding='utf-8') as f: system_prompt = f.read() rendered_system_message = Template(system_prompt).render() - with open('app/services/prompt/conversation_summary_user.jinja2', 'r', encoding='utf-8') as f: + with open(os.path.join(prompt_path, 'conversation_summary_user.jinja2'), 'r', encoding='utf-8') as f: user_prompt = f.read() rendered_user_message = Template(user_prompt).render( language=language, diff --git a/api/app/services/memory_reflection_service.py b/api/app/services/memory_reflection_service.py index 3287366e..e025c1b3 100644 --- a/api/app/services/memory_reflection_service.py +++ b/api/app/services/memory_reflection_service.py @@ -286,7 +286,7 @@ class MemoryReflectionService: # 检查是否需要执行反思 should_execute = False hours_diff = 0 - + if current_reflection_time is None: # 首次执行反思 should_execute = True @@ -298,11 +298,11 @@ class MemoryReflectionService: reflection_time = datetime.fromisoformat(current_reflection_time) else: reflection_time = current_reflection_time - + current_time = datetime.now() time_diff = current_time - reflection_time hours_diff = int(time_diff.total_seconds() / 3600) - + # 检查是否达到反思周期 if hours_diff >= iteration_period: should_execute = True @@ -312,7 +312,7 @@ class MemoryReflectionService: except (ValueError, TypeError) as e: api_logger.warning(f"解析反思时间失败: {e},将执行反思") should_execute = True - + if should_execute: api_logger.info(f"与上次的反思时间间隔为: {hours_diff} 小时") # 3. 执行反思引擎 @@ -345,7 +345,7 @@ class MemoryReflectionService: "next_reflection_in_hours": iteration_period - hours_diff } - + except Exception as e: config_id = config_data.get("config_id", "unknown") api_logger.error(f"启动反思失败,config_id: {config_id}, end_user_id: {end_user_id}, 错误: {str(e)}") @@ -356,7 +356,7 @@ class MemoryReflectionService: "end_user_id": end_user_id, "config_data": config_data } - + def _create_reflection_config_from_data(self, config_data: Dict[str, Any]) -> ReflectionConfig: """Create reflective configuration objects from configuration data""" @@ -364,12 +364,12 @@ class MemoryReflectionService: if reflexion_range_value is None or reflexion_range_value == "": reflexion_range_value = "partial" reflexion_range = ReflectionRange(reflexion_range_value) - + baseline_value = config_data.get("baseline") if baseline_value is None or baseline_value == "": baseline_value = "TIME" baseline = ReflectionBaseline(baseline_value) - + # iteration_period = iteration_period = config_data.get("iteration_period", 24) if isinstance(iteration_period, str): @@ -377,7 +377,6 @@ class MemoryReflectionService: iteration_period = int(iteration_period) except (ValueError, TypeError): iteration_period = 24 # 默认24小时 - return ReflectionConfig( enabled=config_data.get("enable_self_reflexion", False), iteration_period=str(iteration_period), # ReflectionConfig期望字符串 diff --git a/api/app/services/prompt_optimizer_service.py b/api/app/services/prompt_optimizer_service.py index 81bf899d..2c0b57ac 100644 --- a/api/app/services/prompt_optimizer_service.py +++ b/api/app/services/prompt_optimizer_service.py @@ -1,3 +1,4 @@ +import os import re import uuid from typing import Any, AsyncGenerator @@ -182,11 +183,12 @@ class PromptOptimizerService: base_url=api_config.api_base ), type=ModelType(model_config.type)) try: - with open('app/services/prompt/prompt_optimizer_system.jinja2', 'r', encoding='utf-8') as f: + prompt_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'prompt') + with open(os.path.join(prompt_path, 'prompt_optimizer_system.jinja2'), 'r', encoding='utf-8') as f: opt_system_prompt = f.read() rendered_system_message = Template(opt_system_prompt).render() - with open('app/services/prompt/prompt_optimizer_user.jinja2', 'r', encoding='utf-8') as f: + with open(os.path.join(prompt_path, 'prompt_optimizer_user.jinja2'), 'r', encoding='utf-8') as f: opt_user_prompt = f.read() except FileNotFoundError: raise BusinessException(message="System prompt template not found", code=BizCode.NOT_FOUND) diff --git a/web/src/views/ApplicationConfig/components/Knowledge/KnowledgeListModal.tsx b/web/src/views/ApplicationConfig/components/Knowledge/KnowledgeListModal.tsx index f1ebd516..13084701 100644 --- a/web/src/views/ApplicationConfig/components/Knowledge/KnowledgeListModal.tsx +++ b/web/src/views/ApplicationConfig/components/Knowledge/KnowledgeListModal.tsx @@ -64,7 +64,7 @@ const KnowledgeListModal = forwardRef(({ ...item, config: { similarity_threshold: 0.7, - strategy: "hybrid", + retrieve_type: "hybrid", top_k: 3, weight: 1, } diff --git a/web/src/views/Workflow/components/Properties/Knowledge/KnowledgeListModal.tsx b/web/src/views/Workflow/components/Properties/Knowledge/KnowledgeListModal.tsx index 6bd3bbf4..c74db398 100644 --- a/web/src/views/Workflow/components/Properties/Knowledge/KnowledgeListModal.tsx +++ b/web/src/views/Workflow/components/Properties/Knowledge/KnowledgeListModal.tsx @@ -64,7 +64,7 @@ const KnowledgeListModal = forwardRef(({ ...item, config: { similarity_threshold: 0.7, - strategy: "hybrid", + retrieve_type: "hybrid", top_k: 3, weight: 1, } diff --git a/web/src/views/Workflow/hooks/useWorkflowGraph.ts b/web/src/views/Workflow/hooks/useWorkflowGraph.ts index 4c010de0..774b3f7b 100644 --- a/web/src/views/Workflow/hooks/useWorkflowGraph.ts +++ b/web/src/views/Workflow/hooks/useWorkflowGraph.ts @@ -885,7 +885,7 @@ export const useWorkflowGraph = ({ ...itemConfig, ...(data.config[key].defaultValue || {}), knowledge_bases: knowledge_bases?.map((vo: any) => { - const kb_config = vo.config || { similarity_threshold: vo.similarity_threshold, strategy: vo.strategy, top_k: vo.top_k, weight: vo.weight } + const kb_config = vo.config || { similarity_threshold: vo.similarity_threshold, retrieve_type: vo.retrieve_type, top_k: vo.top_k, weight: vo.weight } return { kb_id: vo.kb_id || vo.id, ...kb_config, } }) }