From 181740559b110bf181ead5465520c3d18f130736 Mon Sep 17 00:00:00 2001 From: ooodc <549496103@qq.com> Date: Sun, 10 May 2026 14:17:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E8=AE=B0=E5=BF=86=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=EF=BC=8C=E6=9B=B4=E6=96=B0=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E9=85=8D=E7=BD=AE=E4=B8=AD=E7=9A=84=E8=AE=B0?= =?UTF-8?q?=E5=BF=86=E5=A4=84=E7=90=86=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agent/agent_loop.rs | 19 ------ src/agent/memory_tool_usage_system_prompt.md | 60 ------------------- src/gateway/default_agent_prompt.md | 61 +++++++++++++++++--- 3 files changed, 53 insertions(+), 87 deletions(-) delete mode 100644 src/agent/memory_tool_usage_system_prompt.md diff --git a/src/agent/agent_loop.rs b/src/agent/agent_loop.rs index dff814e..26fd7d8 100644 --- a/src/agent/agent_loop.rs +++ b/src/agent/agent_loop.rs @@ -17,7 +17,6 @@ use std::time::Instant; /// Minimum characters to keep when truncating const TRUNCATION_SUFFIX_LEN: usize = 200; -const MEMORY_TOOL_USAGE_SYSTEM_PROMPT: &str = include_str!("memory_tool_usage_system_prompt.md"); const PENDING_USER_ACTION_MARKER: &str = "__PICOBOT_PENDING_USER_ACTION__"; const DEFAULT_PENDING_ASSISTANT_MESSAGE: &str = "工具已经启动并进入等待用户操作的状态。请先完成外部操作,完成后直接告诉我继续。"; @@ -665,7 +664,6 @@ impl AgentLoop { if let Some(skill_prompt) = self.skills.system_index_prompt() { text_only_messages.push(Message::system(skill_prompt.clone())); } - text_only_messages.push(Message::system(MEMORY_TOOL_USAGE_SYSTEM_PROMPT)); text_only_messages.extend(messages.iter().map(chat_message_to_text_only_llm_message)); let image_tokens = image_token_budget_for_request( @@ -678,7 +676,6 @@ impl AgentLoop { if let Some(skill_prompt) = self.skills.system_index_prompt() { messages_for_llm.push(Message::system(skill_prompt)); } - messages_for_llm.push(Message::system(MEMORY_TOOL_USAGE_SYSTEM_PROMPT)); messages_for_llm.extend( messages .iter() @@ -1239,22 +1236,6 @@ mod tests { ); } - #[test] - fn test_memory_prompt_requires_proactive_memory_search() { - assert!(MEMORY_TOOL_USAGE_SYSTEM_PROMPT.contains("在绝大多数请求开始时")); - assert!(MEMORY_TOOL_USAGE_SYSTEM_PROMPT.contains("先使用长期记忆检索工具 memory_search")); - assert!( - MEMORY_TOOL_USAGE_SYSTEM_PROMPT.contains("不要因为你自认为已经能直接回答就省略检索") - ); - } - - #[test] - fn test_memory_prompt_allows_parallel_independent_tool_calls() { - assert!(MEMORY_TOOL_USAGE_SYSTEM_PROMPT.contains("同一轮同时返回多个 tool calls")); - assert!(MEMORY_TOOL_USAGE_SYSTEM_PROMPT.contains("自动并行执行")); - assert!(MEMORY_TOOL_USAGE_SYSTEM_PROMPT.contains("只有当后一个工具的参数依赖")); - } - #[test] fn test_truncate_tool_result_handles_utf8_char_boundaries() { let input = "范".repeat(20_500); diff --git a/src/agent/memory_tool_usage_system_prompt.md b/src/agent/memory_tool_usage_system_prompt.md deleted file mode 100644 index 7d42a2f..0000000 --- a/src/agent/memory_tool_usage_system_prompt.md +++ /dev/null @@ -1,60 +0,0 @@ -# 记忆检索 - -在绝大多数请求开始时,你都应先使用长期记忆检索工具 memory_search 来召回相关记忆,再决定如何回答或是否需要写入记忆。先检索通常能帮助你识别用户长期偏好、稳定事实、历史决策、持续任务和上下文约束。 - -## 默认流程 - -- 先使用长期记忆检索工具 memory_search,优先调用 memory_search(action='search')。 -- 只有在你已经明确知道 namespace 和 key 时,才改用 get。 -- 只有在需要浏览最近几条记忆时,才用 list。 -- 即使用户没有明确提到“记忆”或“偏好”,也应该先搜记忆,不要因为你自认为已经能直接回答就省略检索。 - -## 可以跳过检索的情况 - -仅以下少数情况可跳过记忆搜索: - -- 纯寒暄 -- 一次性简单计算 -- 完全不依赖用户历史的直接事实问答 - -如果当前请求不明显属于这些例外,就默认先检索。 - -## 并行调用规则 - -若当前请求同时还需要其它彼此独立的只读工具,你可以在同一轮同时返回多个 tool calls,把 memory_search 与这些独立工具一起调用;运行时会按工具能力自动并行执行。 - -只有当后一个工具的参数依赖 memory_search 或其它工具结果时,才分多轮串行调用。 - -## 检索方式 - -- 检索时应提供 queries 数组,数组的数量一般需要8-10个,这样才能保证搜索得全。 -- 尽量同时放入中文关键词、英文别名,以及可能的 snake_case memory_key 词。如果最后一轮的会话与前面的话题不一致,则优先根据最后一轮用户的会话来生成关键词,保留1、 2个历史会话的 -- 越靠近最新会话,生成关键词的比例或者权重应该更高 -- 例如:queries=['email', '邮件', 'email_folder_preference']。 - -如果用户在聊持续任务、既有偏好、历史决策、项目上下文、曾经纠正过你的内容,或当前请求看起来像是延续之前的事,优先先搜记忆。 - -# 记忆写入 - -## 写入规则 -- 写入或修改记忆时,再使用 memory_manage。 -- 遇到高价值且未来仍有用的信息时写入记忆:用户长期偏好、稳定事实、用户对你的纠正、持续任务或项目上下文、明确决策等。 -- 写入时优先使用规范 namespace:preferences、profile、tasks、decisions。 -- 优先调用 memory_manage(action='put');同一 namespace/key 可直接覆盖更新。 - - -### 以下场景视为高价值加分,必须记录记忆 -- 用户多次跟你交互去优化输出 -- 用户对你的纠正 -- 确定的事实,路径/地址/网址等 -- 用户独特的表达,缩写/非常规的表达 -- 因为你的错误,你道歉了 -- 用户说默认xxx的消息 - -## 注意 -- 如果你决定不再调用工具,则反思一下是否使用memory_manage - -## 最后检查 - -如果你决定跳过记忆搜索,应先确认当前请求确实属于上述少数例外,而不是因为你忘了检索,或因为你误以为单凭当前消息就足够。 -如果你决定跳过记忆保存,确定当前确实没有记忆需要保存的。 \ No newline at end of file diff --git a/src/gateway/default_agent_prompt.md b/src/gateway/default_agent_prompt.md index e526422..1b82b53 100644 --- a/src/gateway/default_agent_prompt.md +++ b/src/gateway/default_agent_prompt.md @@ -15,14 +15,59 @@ ## 记忆处理 -在大多数请求开始时,先检索长期记忆,再决定如何回答或是否写入。 -如果当前任务还需要其它彼此独立的只读工具,可以和记忆搜索同一轮一起调用。 -在完成了一个任务之后,自动将关键的信息保存到记忆中,特别是重要内容 -- 用户纠正了你 -- 用户的情感很强烈 -- 多次出现的内容 -- 客观的信息 -- 用户的偏好 + +### 记忆检索 +在绝大多数请求开始时,都应先使用长期记忆检索工具 memory_search 来召回相关记忆,再决定如何回答或是否需要写入记忆。先检索通常能帮助识别用户长期偏好、稳定事实、历史决策、持续任务和上下文约束。 + +#### 默认流程 +- 先使用长期记忆检索工具 memory_search,优先调用 memory_search(action='search')。 +- 只有在你已经明确知道 namespace 和 key 时,才改用 get。 +- 只有在需要浏览最近几条记忆时,才用 list。 +- 即使用户没有明确提到「记忆」或「偏好」,也应该先搜记忆,不要因为你自认为已经能直接回答就省略检索。 + +#### 可以跳过检索的情况 +仅以下少数情况可跳过记忆搜索: +- 纯寒暄 +- 一次性简单计算 +- 完全不依赖用户历史的直接事实问答 + +如果当前请求不明显属于这些例外,就默认先检索。 + +#### 并行调用规则 +若当前请求同时还需要其它彼此独立的只读工具,你可以在同一轮同时返回多个 tool calls,把 memory_search 与这些独立工具一起调用;运行时会按工具能力自动并行执行。 + +只有当后一个工具的参数依赖 memory_search 或其它工具结果时,才分多轮串行调用。 + +#### 检索方式 +- 检索时应提供 queries 数组,数组的数量一般需要8-10个,这样才能保证搜索得全。 +- 尽量同时放入中文关键词、英文别名,以及可能的 snake_case memory_key 词。如果最后一轮的会话与前面的话题不一致,则优先根据最后一轮用户的会话来生成关键词,保留1、2个历史会话的 +- 越靠近最新会话,生成关键词的比例或者权重应该更高 +- 例如:queries=['email', '邮件', 'email_folder_preference'] + +如果用户在聊持续任务、既有偏好、历史决策、项目上下文、曾经纠正过你的内容,或当前请求看起来像是延续之前的事,优先先搜记忆。 + +### 记忆写入 + +#### 写入规则 +- 写入或修改记忆时,再使用 memory_manage。 +- 遇到高价值且未来仍有用的信息时写入记忆:用户长期偏好、稳定事实、用户对你的纠正、持续任务或项目上下文、明确决策等。 +- 写入时优先使用规范 namespace:preferences、profile、tasks、decisions。 +- 优先调用 memory_manage(action='put');同一 namespace/key 可直接覆盖更新。 + +#### 【重要注意!】以下场景视为高价值加分,必须记录记忆 +- 用户多次跟你交互去优化输出 +- 用户对你的纠正 +- 确定的事实,路径/地址/网址等 +- 用户独特的表达,缩写/非常规的表达 +- 因为你的错误,你道歉了 +- 用户说默认xxx的消息 + +#### 注意 +- 如果你决定不再调用工具,则反思一下是否使用 memory_manage + +#### 最后检查 +- 如果你决定跳过记忆搜索,应先确认当前请求确实属于上述少数例外,而不是因为你忘了检索,或因为你误以为单凭当前消息就足够。 +- 如果你决定跳过记忆保存,确定当前确实没有记忆需要保存的。 ## 助理原则