From 1dd81f9c250393b58b49463ebbc5aa30cc8f9d19 Mon Sep 17 00:00:00 2001 From: "jinli.yl" Date: Fri, 6 Feb 2026 15:02:41 +0800 Subject: [PATCH] refactor(core): update config parsing and memory management system --- .gitignore | 3 +- benchmark/halumem/eval_reme.py | 2 +- .../personal/personal_v1_retriever.yaml | 8 +-- .../personal/personal_v1_summarizer.yaml | 60 ++++++------------- reme/config/default.yaml | 2 +- reme/core/context/service_context.py | 4 +- reme/core/utils/pydantic_config_parser.py | 18 ++---- reme/reme.py | 4 +- reme/reme_fs.py | 41 +++++++++++++ 9 files changed, 73 insertions(+), 69 deletions(-) create mode 100644 reme/reme_fs.py diff --git a/.gitignore b/.gitignore index 07fbdaca..b20570b5 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ meta_memory/* *.sqlite3 **/data/*.json *.db -memories/* \ No newline at end of file +memories/* +.reme/* \ No newline at end of file diff --git a/benchmark/halumem/eval_reme.py b/benchmark/halumem/eval_reme.py index b4fc42de..89ee32ad 100644 --- a/benchmark/halumem/eval_reme.py +++ b/benchmark/halumem/eval_reme.py @@ -220,7 +220,7 @@ async def answer_question_with_memories( result = await reme.llm.simple_request_for_json( prompt=prompt, - model_name="qwen-flash" + model_name=model_name, ) return result diff --git a/reme/agent/memory/personal/personal_v1_retriever.yaml b/reme/agent/memory/personal/personal_v1_retriever.yaml index 54ece8d0..99df1374 100644 --- a/reme/agent/memory/personal/personal_v1_retriever.yaml +++ b/reme/agent/memory/personal/personal_v1_retriever.yaml @@ -20,7 +20,6 @@ user_message: | * Entity-focused queries (extract and search specific names, places, events) * Keyword-based searches (core concepts, topics) * Related context queries (broader themes) - - Review all results before proceeding to next phase ### Phase 2(Optional): Temporal Search **Tool**: `retrieve_memory` (with time filter) @@ -32,8 +31,7 @@ user_message: | - After date: `20200101,99999999` (from 20200101 onwards) **Approach**: - Identify temporal constraints from the user question - - Refine Phase 1 queries with appropriate time filters - - Try multiple time ranges if initial searches yield no results + - Refine Phase 1 queries with 3-5 diverse appropriate different time filters ### Phase 3: Deep Dive into History **Tool**: `read_history` @@ -57,6 +55,4 @@ user_message: | - If you find sufficient information to answer the user's question, you may output directly without exhausting all search phases - Exhaust all search strategies before concluding information doesn't exist - ### Output any tangentially related findings, Format: - [timestamp] [memory/profile/history] [relevant content1] - [timestamp] [memory/profile/history] [relevant content2] + Output a summary of all retrieved memories, user profile, and history data. diff --git a/reme/agent/memory/personal/personal_v1_summarizer.yaml b/reme/agent/memory/personal/personal_v1_summarizer.yaml index 5721e64f..83befa96 100644 --- a/reme/agent/memory/personal/personal_v1_summarizer.yaml +++ b/reme/agent/memory/personal/personal_v1_summarizer.yaml @@ -15,65 +15,41 @@ user_message_s1: | - Extract all important information comprehensively—do not miss critical details, but avoid any fabrications or unfounded assumptions - The tool will retrieve similar historical memories via vector search to help you in Step 2 - ### Step 2: Update and Add Memories - Review each memory draft from Step 1 and compare it with the retrieved historical memories, then use `update_memory` to manage all memories in one call: + ### Step 2: Add New Memories + Review each memory draft from Step 1 and compare it with the retrieved historical memories, then use `add_memory` to add new memories: - **For memories_to_update** (updating existing memories): - - For each memory to update, fill in the required parameters: - * `memory_id`: ID of the historical memory to update (from retrieved memories in Step 1) - * `message_time`: timestamp from the conversation (e.g., '2020-01-01 00:00:00') - * `memory_content`: updated or consolidated memory content - - Update memories when: - * The draft contains additional information that should be merged with existing memories - * Historical memories need to be corrected or refined based on new information - - **For memories_to_add** (adding new memories): - - For each new memory, fill in the required parameters: - * `message_time`: timestamp from the conversation (e.g., '2020-01-01 00:00:00') - * `memory_content`: memory content - - Add memories when: - * The draft contains completely new information not present in historical memories - * The information cannot be merged into any existing memory - - **General Guidelines:** + **Parameters for each memory:** + - `message_time`: timestamp from the conversation (e.g., '2020-01-01 00:00:00') + - `memory_content`: memory content + **When to skip:** - **Skip** drafts if their content is already fully covered by historical memories (avoid redundancy) - - You can update and add memories in a single `update_memory` tool call user_message_s2: | - You are a Profile Agent responsible for managing profiles about {memory_target}. + You are a User Profile Agent responsible for managing user profiles about {memory_target}. ## Latest Conversation Format: round [] : {context} - ## Current Profiles + ## Current User Profiles {profiles} ## Task - Analyze the Latest Conversation and use `update_profiles` to manage profiles (both updates and additions in one call): + Analyze the Latest Conversation and use `update_profiles` to manage user profiles (both updates and additions in one call): - **For profiles_to_update** (updating existing profiles): + **For profiles_to_update** (updating existing user profiles): - For each profile to update, fill in the required parameters: - * `profile_id`: ID of the profile to update (from Current Profiles) + * `profile_id`: ID of the profile to update (from Current User Profiles) * `message_time`: timestamp from the conversation (e.g., '2020-01-01 00:00:00') - * `profile_key`: profile key or category (e.g., 'name', 'age', 'occupation') - * `profile_value`: updated profile value (e.g., 'John Smith') - - Update profiles when: - * Information in the conversation conflicts with or supersedes existing profiles - * Profiles need to be consolidated or merged with new information - * Existing profile values need to be corrected or refined + * `profile_key`: key (e.g., 'name', 'age', 'occupation') + * `profile_value`: value (e.g., 'John Smith') - **For profiles_to_add** (adding new profiles): + **For profiles_to_add** (adding new user profiles): - For each new profile, fill in the required parameters: * `message_time`: timestamp from the conversation (e.g., '2020-01-01 00:00:00') - * `profile_key`: profile key or category (e.g., 'name', 'age', 'occupation') - * `profile_value`: profile value (e.g., 'John Smith') - - Add profiles when: - * The information represents a new distinct profile not present in Current Profiles - * The profile key doesn't exist in Current Profiles - * The information cannot be merged into existing profiles + * `profile_key`: key (e.g., 'name', 'age', 'occupation') + * `profile_value`: value (e.g., 'John Smith') **General Guidelines:** - - Use actual names from the conversation (e.g., "Bob") instead of generic references (e.g., "user") - - Extract all important information comprehensively—do not miss critical details, but avoid any fabrications or unfounded assumptions - - You can update and add profiles in a single tool call + - Avoid any fabrications or unfounded assumptions + - You can update and add user profiles in a single tool call diff --git a/reme/config/default.yaml b/reme/config/default.yaml index b7ed53d4..561f931a 100644 --- a/reme/config/default.yaml +++ b/reme/config/default.yaml @@ -22,7 +22,7 @@ llm: backend: openai model_name: qwen3-30b-a3b-instruct-2507 request_interval: 1 - temperature: 0.0001 +# temperature: 0.0001 qwen3_max_instruct: backend: openai diff --git a/reme/core/context/service_context.py b/reme/core/context/service_context.py index 05a45355..045858f7 100644 --- a/reme/core/context/service_context.py +++ b/reme/core/context/service_context.py @@ -118,9 +118,7 @@ class ServiceContext(BaseContext): input_args.append(f"config={config_path}") if args: input_args.extend(args) - if kwargs: - input_args.extend([f"{k}={v}" for k, v in kwargs.items()]) - service_config = parser.parse_args(*input_args) + service_config = parser.parse_args(*input_args, **kwargs) service_config.enable_logo = enable_logo if llm: diff --git a/reme/core/utils/pydantic_config_parser.py b/reme/core/utils/pydantic_config_parser.py index 2f4f2ae0..1fd0ab56 100644 --- a/reme/core/utils/pydantic_config_parser.py +++ b/reme/core/utils/pydantic_config_parser.py @@ -145,19 +145,8 @@ class PydanticConfigParser: raise FileNotFoundError(f"config={config_path} not found") return config_path - def parse_args(self, *args: str) -> T: - """Parse CLI arguments and load configs from YAML files. - - Args: - *args: CLI arguments in format "key=value" or "config=file.yaml". - - Returns: - Validated Pydantic config instance. - - Raises: - ValueError: If no config file is specified. - FileNotFoundError: If specified config file does not exist. - """ + def parse_args(self, *args: str, **kwargs) -> T: + """Parse CLI arguments and load configs from YAML files.""" configs_to_merge = [self.config_class().model_dump()] # Separate config file path from other arguments @@ -184,6 +173,9 @@ class PydanticConfigParser: if filter_args: configs_to_merge.append(self.parse_dot_notation(filter_args)) + if kwargs: + configs_to_merge.append(kwargs) + # Merge all configs and validate self.config_dict = self.merge_configs(*configs_to_merge) return self.config_class.model_validate(self.config_dict) diff --git a/reme/reme.py b/reme/reme.py index bd3e2c64..94a9b196 100644 --- a/reme/reme.py +++ b/reme/reme.py @@ -36,7 +36,7 @@ from .tool.memory import ( AddHistory, ReadAllProfiles, UpdateProfilesV1, - UpdateMemoryV1, + AddMemory, ) @@ -222,7 +222,7 @@ class ReMe(Application): enable_when_to_use=False, enable_multiple=True, ), - UpdateMemoryV1( + AddMemory( enable_thinking_params=enable_thinking_params, enable_memory_target=False, enable_when_to_use=False, diff --git a/reme/reme_fs.py b/reme/reme_fs.py new file mode 100644 index 00000000..f5ef42d2 --- /dev/null +++ b/reme/reme_fs.py @@ -0,0 +1,41 @@ +"""ReMe File System""" + +from .config import ReMeConfigParser +from .core import Application + + +class ReMeFs(Application): + """ReMe File System""" + + def __init__( + self, + *args, + llm_api_key: str | None = None, + llm_api_base: str | None = None, + embedding_api_key: str | None = None, + embedding_api_base: str | None = None, + enable_logo: bool = True, + llm: dict | None = None, + embedding_model: dict | None = None, + vector_store: dict | None = None, + token_counter: dict | None = None, + working_dir: str = "./agent", + **kwargs, + ): + """Initialize ReMe with config.""" + super().__init__( + *args, + llm_api_key=llm_api_key, + llm_api_base=llm_api_base, + embedding_api_key=embedding_api_key, + embedding_api_base=embedding_api_base, + enable_logo=enable_logo, + parser=ReMeConfigParser, + llm=llm, + embedding_model=embedding_model, + vector_store=vector_store, + token_counter=token_counter, + **kwargs, + ) + + self.working_dir: str = working_dir