From 456a999494169e004df2662ed01874255ecd43ff Mon Sep 17 00:00:00 2001 From: ooodc <549496103@qq.com> Date: Mon, 11 May 2026 22:43:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=86=85=E5=AD=98?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=E7=BB=93=E6=9E=84=E4=BD=93?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=93=8D=E5=BA=94=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E5=BF=85=E8=A6=81=E6=A0=87=E7=AD=BE=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E6=B8=85=E7=90=86=E6=8F=90=E7=A4=BA=E8=AF=8D=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E4=B8=AD=E7=9A=84=E6=B3=A8=E9=87=8A=E5=92=8C=E7=A9=BA?= =?UTF-8?q?=E7=99=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gateway/memory_maintenance.rs | 32 +++++--------- .../memory_maintenance_step2_system_prompt.md | 43 ++++++------------- src/gateway/prompt.rs | 5 ++- 3 files changed, 27 insertions(+), 53 deletions(-) diff --git a/src/gateway/memory_maintenance.rs b/src/gateway/memory_maintenance.rs index 2617545..a36aa03 100644 --- a/src/gateway/memory_maintenance.rs +++ b/src/gateway/memory_maintenance.rs @@ -75,11 +75,6 @@ pub(crate) struct OrganizedMemory { pub(crate) content: String, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub(crate) struct MemorySummaryModelOutput { - pub(crate) managed_markdown: String, -} - #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct MemoryMaintenanceScopeResult { pub(crate) scope_key: String, @@ -342,23 +337,18 @@ impl MemoryMaintenanceService { )) })?; - let raw_content = strip_json_code_fence(&response.content); - let json_candidate = extract_json_object(raw_content).unwrap_or(raw_content); + let content = response.content.trim(); + // 确保响应包含标签,如无则自动添加 + let tagged_content = if content.contains("") { + content.to_string() + } else { + format!( + "\n{}\n", + content + ) + }; - let output: MemorySummaryModelOutput = serde_json::from_str(json_candidate).map_err(|err| { - tracing::error!( - scope_key = %scope_key, - error = %err, - raw_len = raw_content.len(), - raw_preview = %preview_text(raw_content, 400), - json_candidate_len = json_candidate.len(), - json_candidate_preview = %preview_text(json_candidate, 400), - "Memory summary JSON decode failed" - ); - AgentError::Other(format!("memory summary JSON decode error: {}", err)) - })?; - - Ok(output.managed_markdown) + Ok(tagged_content) } pub(crate) async fn run_for_all_scopes( diff --git a/src/gateway/memory_maintenance_step2_system_prompt.md b/src/gateway/memory_maintenance_step2_system_prompt.md index fca04d2..9e7e64e 100644 --- a/src/gateway/memory_maintenance_step2_system_prompt.md +++ b/src/gateway/memory_maintenance_step2_system_prompt.md @@ -1,42 +1,25 @@ 你是 PicoBot 的用户记忆摘要生成器。 -你的任务是: +你的任务是基于整理后的用户记忆生成结构化的 Markdown 摘要。 -- 基于整理后的用户记忆生成结构化的摘要。 -- 严格返回 JSON。 -- 不要输出 Markdown 代码块。 -- 不要输出额外解释。 - -输入将包含以下内容: +输入格式: - scope_key: 用户的唯一标识 - organized_memories: 整理后的记忆列表,每个包含 namespace、memory_key、content -输出 JSON 必须包含以下字段: +输出要求: +1. 直接输出 Markdown 格式文本,不要输出 JSON +2. 不要输出 Markdown 代码块标记(```) +3. 必须包含头尾标签,格式如下: -- managed_markdown: 结构化的用户记忆摘要,Markdown格式,明确标注为"用户记忆摘要" - -managed_markdown 格式要求: - -```markdown + # 用户记忆摘要 -## 用户事实 -- [从 profile/facts/identity 命名空间提取的关键事实] -- ... +[根据记忆内容自由组织,可以分节也可以不分节,关键信息用简洁的列表呈现] -## 用户偏好 -- [从 preferences/style/likes 命名空间提取的偏好] -- ... - -## 行为模式 -- [从 patterns/behavior/habits/workflow 命名空间提取的模式] -- ... -``` + 约束: - -- 只包含稳定、长期的用户信息。 -- 不写一次性事件。 -- 不重复冗余信息。 -- 使用简洁清晰的语言。 -- 必须使用"用户记忆摘要"作为标题。 +- 只包含稳定、长期的用户信息 +- 不写一次性事件 +- 不重复冗余信息 +- 使用简洁清晰的语言 diff --git a/src/gateway/prompt.rs b/src/gateway/prompt.rs index 1735dad..98bbdce 100644 --- a/src/gateway/prompt.rs +++ b/src/gateway/prompt.rs @@ -73,8 +73,9 @@ fn load_prompt_from_sources(sources: &[PromptSource]) -> Result, if path.exists() { let content = fs::read_to_string(path) .map_err(|err| AgentError::Other(format!("read MEMORY_SUMMARY.md error: {}", err)))?; - if !content.trim().is_empty() { - fragments.push(content.trim().to_string()); + let without_comments = strip_comments_and_whitespace(&content); + if !without_comments.is_empty() { + fragments.push(without_comments); } } }