feat: Optimize the first dialogue and memory

This commit is contained in:
saboteur7
2026-01-30 19:10:37 +08:00
parent dd6a9c26bd
commit 8a69d4354e
6 changed files with 156 additions and 335 deletions

View File

@@ -248,8 +248,8 @@ class MemoryManager:
memory_dir = self.config.get_memory_dir() memory_dir = self.config.get_memory_dir()
workspace_dir = self.config.get_workspace() workspace_dir = self.config.get_workspace()
# Scan memory/MEMORY.md # Scan MEMORY.md (workspace root)
memory_file = memory_dir / "MEMORY.md" memory_file = Path(workspace_dir) / "MEMORY.md"
if memory_file.exists(): if memory_file.exists():
await self._sync_file(memory_file, "memory", "shared", None) await self._sync_file(memory_file, "memory", "shared", None)
@@ -452,7 +452,7 @@ class MemoryManager:
**背景知识**: 下方包含核心长期记忆,可直接使用。需要查找历史时,用 memory_search 搜索(搜索一次即可,不要重复)。 **背景知识**: 下方包含核心长期记忆,可直接使用。需要查找历史时,用 memory_search 搜索(搜索一次即可,不要重复)。
**存储记忆**: 当用户分享重要信息时(偏好、决策、事实等),主动用 write 工具存储: **存储记忆**: 当用户分享重要信息时(偏好、决策、事实等),主动用 write 工具存储:
- 长期信息 → memory/MEMORY.md - 长期信息 → MEMORY.md
- 当天笔记 → memory/{today_file} - 当天笔记 → memory/{today_file}
- 静默存储,仅在明确要求时确认 - 静默存储,仅在明确要求时确认
@@ -463,7 +463,7 @@ class MemoryManager:
**Background Knowledge**: Core long-term memories below - use directly. For history, use memory_search once (don't repeat). **Background Knowledge**: Core long-term memories below - use directly. For history, use memory_search once (don't repeat).
**Store Memories**: When user shares important info (preferences, decisions, facts), proactively write: **Store Memories**: When user shares important info (preferences, decisions, facts), proactively write:
- Durable info → memory/MEMORY.md - Durable info → MEMORY.md
- Daily notes → memory/{today_file} - Daily notes → memory/{today_file}
- Store silently; confirm only when explicitly requested - Store silently; confirm only when explicitly requested
@@ -482,8 +482,8 @@ class MemoryManager:
Load bootstrap memory files for session start Load bootstrap memory files for session start
Following clawdbot's design: Following clawdbot's design:
- Only loads memory/MEMORY.md (long-term curated memory) - Only loads MEMORY.md from workspace root (long-term curated memory)
- Daily files (YYYY-MM-DD.md) are accessed via memory_search tool, not bootstrap - Daily files (memory/YYYY-MM-DD.md) are accessed via memory_search tool, not bootstrap
- User-specific MEMORY.md is also loaded if user_id provided - User-specific MEMORY.md is also loaded if user_id provided
Returns memory content WITHOUT obvious headers so it blends naturally Returns memory content WITHOUT obvious headers so it blends naturally
@@ -500,16 +500,16 @@ class MemoryManager:
sections = [] sections = []
# 1. Load memory/MEMORY.md ONLY (long-term curated memory) # 1. Load MEMORY.md from workspace root (long-term curated memory)
# Following clawdbot: only MEMORY.md is bootstrap, daily files use memory_search # Following clawdbot: only MEMORY.md is bootstrap, daily files use memory_search
memory_file = memory_dir / "MEMORY.md" memory_file = Path(workspace_dir) / "MEMORY.md"
if memory_file.exists(): if memory_file.exists():
try: try:
content = memory_file.read_text(encoding='utf-8').strip() content = memory_file.read_text(encoding='utf-8').strip()
if content: if content:
sections.append(content) sections.append(content)
except Exception as e: except Exception as e:
print(f"Warning: Failed to read memory/MEMORY.md: {e}") print(f"Warning: Failed to read MEMORY.md: {e}")
# 2. Load user-specific MEMORY.md if user_id provided # 2. Load user-specific MEMORY.md if user_id provided
if user_id: if user_id:

View File

@@ -17,7 +17,7 @@ class MemoryFlushManager:
- Triggers when context approaches token limit - Triggers when context approaches token limit
- Runs a silent agent turn to write memories to disk - Runs a silent agent turn to write memories to disk
- Uses memory/YYYY-MM-DD.md for daily notes - Uses memory/YYYY-MM-DD.md for daily notes
- Uses MEMORY.md for long-term curated memories - Uses MEMORY.md (workspace root) for long-term curated memories
""" """
def __init__( def __init__(
@@ -103,7 +103,7 @@ class MemoryFlushManager:
def get_main_memory_file(self, user_id: Optional[str] = None) -> Path: def get_main_memory_file(self, user_id: Optional[str] = None) -> Path:
""" """
Get main memory file path: memory/MEMORY.md Get main memory file path: MEMORY.md (workspace root)
Args: Args:
user_id: Optional user ID for user-specific memory user_id: Optional user ID for user-specific memory
@@ -116,7 +116,8 @@ class MemoryFlushManager:
user_dir.mkdir(parents=True, exist_ok=True) user_dir.mkdir(parents=True, exist_ok=True)
return user_dir / "MEMORY.md" return user_dir / "MEMORY.md"
else: else:
return self.memory_dir / "MEMORY.md" # Return workspace root MEMORY.md
return Path(self.workspace_root) / "MEMORY.md"
def create_flush_prompt(self) -> str: def create_flush_prompt(self) -> str:
""" """
@@ -207,13 +208,13 @@ def create_memory_files_if_needed(workspace_dir: Path, user_id: Optional[str] =
memory_dir = workspace_dir / "memory" memory_dir = workspace_dir / "memory"
memory_dir.mkdir(parents=True, exist_ok=True) memory_dir.mkdir(parents=True, exist_ok=True)
# Create main MEMORY.md in memory directory # Create main MEMORY.md in workspace root
if user_id: if user_id:
user_dir = memory_dir / "users" / user_id user_dir = memory_dir / "users" / user_id
user_dir.mkdir(parents=True, exist_ok=True) user_dir.mkdir(parents=True, exist_ok=True)
main_memory = user_dir / "MEMORY.md" main_memory = user_dir / "MEMORY.md"
else: else:
main_memory = memory_dir / "MEMORY.md" main_memory = Path(workspace_root) / "MEMORY.md"
if not main_memory.exists(): if not main_memory.exists():
# Create empty file or with minimal structure (no obvious "Memory" header) # Create empty file or with minimal structure (no obvious "Memory" header)

View File

@@ -156,7 +156,6 @@ def _build_identity_section(base_persona: Optional[str], language: str) -> List[
def _build_tooling_section(tools: List[Any], language: str) -> List[str]: def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
"""构建工具说明section""" """构建工具说明section"""
if language == "zh":
lines = [ lines = [
"## 工具系统", "## 工具系统",
"", "",
@@ -165,15 +164,6 @@ def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
"### 可用工具", "### 可用工具",
"", "",
] ]
else:
lines = [
"## Tooling",
"",
"You have access to the following tools. Tool names are case-sensitive.",
"",
"### Available Tools",
"",
]
# 工具分类和排序 # 工具分类和排序
tool_categories = { tool_categories = {
@@ -213,9 +203,6 @@ def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
for category, tool_names in tool_categories.items(): for category, tool_names in tool_categories.items():
category_tools = [(name, tool_map.get(name, "")) for name in tool_names if name in tool_map] category_tools = [(name, tool_map.get(name, "")) for name in tool_names if name in tool_map]
if category_tools: if category_tools:
if language == "zh":
lines.append(f"**{category}**:")
else:
lines.append(f"**{category}**:") lines.append(f"**{category}**:")
for name, desc in category_tools: for name, desc in category_tools:
if desc: if desc:
@@ -227,10 +214,7 @@ def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
# 添加其他未分类的工具 # 添加其他未分类的工具
if tool_map: if tool_map:
if language == "zh":
lines.append("**其他工具**:") lines.append("**其他工具**:")
else:
lines.append("**Other Tools**:")
for name, desc in sorted(tool_map.items()): for name, desc in sorted(tool_map.items()):
if desc: if desc:
lines.append(f"- `{name}`: {desc}") lines.append(f"- `{name}`: {desc}")
@@ -239,7 +223,6 @@ def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
lines.append("") lines.append("")
# 工具使用指南 # 工具使用指南
if language == "zh":
lines.extend([ lines.extend([
"### 工具调用风格", "### 工具调用风格",
"", "",
@@ -250,21 +233,7 @@ def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
"- 敏感操作(如删除文件)", "- 敏感操作(如删除文件)",
"- 用户明确要求解释过程", "- 用户明确要求解释过程",
"", "",
"**叙述要求**: 保持简洁、有价值,避免重复显而易见的步骤。使用自然的人类语言", "**完成后**: 工具调用完成后,给用户一个简短、自然的确认或回复,不要直接结束对话",
"",
])
else:
lines.extend([
"### Tool Call Style",
"",
"**Default**: Do not narrate routine, low-risk tool calls (just call the tool).",
"",
"**Narrate when**:",
"- Multi-step, complex work",
"- Sensitive actions (e.g., deletions)",
"- User explicitly asks",
"",
"**Keep narration brief and value-dense**. Use plain human language.",
"", "",
]) ])
@@ -285,7 +254,6 @@ def _build_skills_section(skill_manager: Any, tools: Optional[List[Any]], langua
read_tool_name = tool_name read_tool_name = tool_name
break break
if language == "zh":
lines = [ lines = [
"## 技能系统", "## 技能系统",
"", "",
@@ -298,19 +266,6 @@ def _build_skills_section(skill_manager: Any, tools: Optional[List[Any]], langua
"**约束**: 永远不要一次性读取多个技能;只在选择后再读取。", "**约束**: 永远不要一次性读取多个技能;只在选择后再读取。",
"", "",
] ]
else:
lines = [
"## Skills",
"",
"Before replying: scan <available_skills> <description> entries.",
"",
f"- If exactly one skill clearly applies: read its SKILL.md at <location> with `{read_tool_name}`, then follow it.",
"- If multiple could apply: choose the most specific one, then read/follow it.",
"- If none clearly apply: do not read any SKILL.md.",
"",
"**Constraints**: never read more than one skill up front; only read after selecting.",
"",
]
# 添加技能列表通过skill_manager获取 # 添加技能列表通过skill_manager获取
try: try:
@@ -338,7 +293,6 @@ def _build_memory_section(memory_manager: Any, tools: Optional[List[Any]], langu
if not has_memory_tools: if not has_memory_tools:
return [] return []
if language == "zh":
lines = [ lines = [
"## 记忆系统", "## 记忆系统",
"", "",
@@ -349,45 +303,14 @@ def _build_memory_section(memory_manager: Any, tools: Optional[List[Any]], langu
"3. 如果搜索后仍然信心不足,告诉用户你已经检查过了", "3. 如果搜索后仍然信心不足,告诉用户你已经检查过了",
"", "",
"**记忆文件结构**:", "**记忆文件结构**:",
"- `memory/MEMORY.md`: 长期记忆,包含重要的背景信息", "- `MEMORY.md`: 长期记忆,包含重要的背景信息",
"- `memory/YYYY-MM-DD.md`: 每日记忆,记录当天的对话和事件", "- `memory/YYYY-MM-DD.md`: 每日记忆,记录当天的对话和事件",
"", "",
"**存储记忆**:",
"- 当用户分享重要信息时(偏好、爱好、决策、事实等),**主动用 write 工具存储**",
"- 长期信息 → memory/MEMORY.md",
"- 当天笔记 → memory/YYYY-MM-DD.md",
"- 静默存储,仅在明确要求时确认",
"",
"**使用原则**:", "**使用原则**:",
"- 自然使用记忆,就像你本来就知道", "- 自然使用记忆,就像你本来就知道",
"- 不要主动提起或列举记忆,除非用户明确询问", "- 不要主动提起或列举记忆,除非用户明确询问",
"", "",
] ]
else:
lines = [
"## Memory System",
"",
"Before answering anything about prior work, decisions, dates, people, preferences, or todos:",
"",
"1. Run `memory_search` on MEMORY.md + memory/*.md",
"2. Then use `memory_get` to pull only the needed lines",
"3. If low confidence after search, say you checked",
"",
"**Memory File Structure**:",
"- `memory/MEMORY.md`: Long-term memory with important context",
"- `memory/YYYY-MM-DD.md`: Daily memories for each day",
"",
"**Store Memories**:",
"- When user shares important info (preferences, hobbies, decisions, facts), **proactively write**",
"- Durable info → memory/MEMORY.md",
"- Daily notes → memory/YYYY-MM-DD.md",
"- Store silently; confirm only when explicitly requested",
"",
"**Usage Principles**:",
"- Use memories naturally as if you always knew",
"- Don't mention or list unless user explicitly asks",
"",
]
return lines return lines
@@ -397,7 +320,6 @@ def _build_user_identity_section(user_identity: Dict[str, str], language: str) -
if not user_identity: if not user_identity:
return [] return []
if language == "zh":
lines = [ lines = [
"## 用户身份", "## 用户身份",
"", "",
@@ -413,22 +335,6 @@ def _build_user_identity_section(user_identity: Dict[str, str], language: str) -
lines.append(f"**备注**: {user_identity['notes']}") lines.append(f"**备注**: {user_identity['notes']}")
lines.append("") lines.append("")
else:
lines = [
"## User Identity",
"",
]
if user_identity.get("name"):
lines.append(f"**Name**: {user_identity['name']}")
if user_identity.get("nickname"):
lines.append(f"**Call them**: {user_identity['nickname']}")
if user_identity.get("timezone"):
lines.append(f"**Timezone**: {user_identity['timezone']}")
if user_identity.get("notes"):
lines.append(f"**Notes**: {user_identity['notes']}")
lines.append("")
return lines return lines
@@ -441,7 +347,6 @@ def _build_docs_section(workspace_dir: str, language: str) -> List[str]:
def _build_workspace_section(workspace_dir: str, language: str) -> List[str]: def _build_workspace_section(workspace_dir: str, language: str) -> List[str]:
"""构建工作空间section""" """构建工作空间section"""
if language == "zh":
lines = [ lines = [
"## 工作空间", "## 工作空间",
"", "",
@@ -455,7 +360,7 @@ def _build_workspace_section(workspace_dir: str, language: str) -> List[str]:
"", "",
"- ✅ `SOUL.md`: 已加载 - Agent的人格设定", "- ✅ `SOUL.md`: 已加载 - Agent的人格设定",
"- ✅ `USER.md`: 已加载 - 用户的身份信息", "- ✅ `USER.md`: 已加载 - 用户的身份信息",
"- ✅ `AGENTS.md`: 已加载 - 工作空间使用指南" "- ✅ `AGENTS.md`: 已加载 - 工作空间使用指南",
"", "",
"**首次对话**:", "**首次对话**:",
"", "",
@@ -469,53 +374,6 @@ def _build_workspace_section(workspace_dir: str, language: str) -> List[str]:
"", "",
"**重要**: 在询问时保持自然对话风格,**不要提及文件名**(如 SOUL.md、USER.md 等技术细节),除非用户主动询问系统实现。用自然的表达如「了解你的信息」「设定我的性格」等。", "**重要**: 在询问时保持自然对话风格,**不要提及文件名**(如 SOUL.md、USER.md 等技术细节),除非用户主动询问系统实现。用自然的表达如「了解你的信息」「设定我的性格」等。",
"", "",
"**记忆管理**:",
"",
"- 当用户说「记住这个」时,判断应该写入哪个文件:",
" - 关于你自己的配置 → SOUL.md",
" - 关于用户的信息 → USER.md",
" - 重要的背景信息 → memory/MEMORY.md",
" - 日常对话记录 → memory/YYYY-MM-DD.md",
"",
]
else:
lines = [
"## Workspace",
"",
f"Your working directory is: `{workspace_dir}`",
"",
"Treat this directory as the single global workspace for file operations unless explicitly instructed otherwise.",
"",
"**Workspace Files (Auto-loaded)**:",
"",
"The following user-editable files are automatically loaded and included in the Project Context below:",
"",
"- `SOUL.md`: Agent persona (your personality, style, and principles)",
"- `USER.md`: User identity (name, preferences, important dates)",
"- `AGENTS.md`: Workspace guidelines (your rules and workflows)",
"- `TOOLS.md`: Custom tool usage notes (configurations and tips)",
"- `MEMORY.md`: Long-term memory (important context and decisions)",
"",
"**First Conversation**:",
"",
"If this is your first conversation with the user, and your persona and user information are empty or contain placeholders, you should:",
"",
"1. **Greet naturally and warmly**, expressing your interest in learning about them",
"2. Ask about the user (name, job, preferences, timezone, etc.)",
"3. Ask what kind of assistant they want you to be (personality, style, name, expertise)",
"4. Use `write` tool to save the information to appropriate files (USER.md and SOUL.md)",
"5. Later, use `edit` tool to update these configurations as needed",
"",
"**Important**: Keep the conversation natural. **Do NOT mention file names** (like SOUL.md, USER.md, etc.) unless the user specifically asks about implementation details. Use natural expressions like \"learn about you\", \"configure my personality\", etc.",
"",
"**Memory Management**:",
"",
"- When user says 'remember this', decide which file to write to:",
" - About your configuration → SOUL.md",
" - About the user → USER.md",
" - Important context → memory/MEMORY.md",
" - Daily chat logs → memory/YYYY-MM-DD.md",
"",
] ]
return lines return lines
@@ -532,7 +390,6 @@ def _build_context_files_section(context_files: List[ContextFile], language: str
for f in context_files for f in context_files
) )
if language == "zh":
lines = [ lines = [
"# 项目上下文", "# 项目上下文",
"", "",
@@ -543,17 +400,6 @@ def _build_context_files_section(context_files: List[ContextFile], language: str
if has_soul: if has_soul:
lines.append("如果存在 `SOUL.md`,请体现其中定义的人格和语气。避免僵硬、模板化的回复;遵循其指导,除非有更高优先级的指令覆盖它。") lines.append("如果存在 `SOUL.md`,请体现其中定义的人格和语气。避免僵硬、模板化的回复;遵循其指导,除非有更高优先级的指令覆盖它。")
lines.append("") lines.append("")
else:
lines = [
"# Project Context",
"",
"The following project context files have been loaded:",
"",
]
if has_soul:
lines.append("If `SOUL.md` is present, embody its persona and tone. Avoid stiff, generic replies; follow its guidance unless higher-priority instructions override it.")
lines.append("")
# 添加每个文件的内容 # 添加每个文件的内容
for file in context_files: for file in context_files:
@@ -573,29 +419,21 @@ def _build_runtime_section(runtime_info: Dict[str, Any], language: str) -> List[
# Only include if there's actual runtime info to display # Only include if there's actual runtime info to display
runtime_parts = [] runtime_parts = []
if runtime_info.get("model"): if runtime_info.get("model"):
runtime_parts.append(f"模型={runtime_info['model']}" if language == "zh" else f"model={runtime_info['model']}") runtime_parts.append(f"模型={runtime_info['model']}")
if runtime_info.get("workspace"): if runtime_info.get("workspace"):
runtime_parts.append(f"工作空间={runtime_info['workspace']}" if language == "zh" else f"workspace={runtime_info['workspace']}") runtime_parts.append(f"工作空间={runtime_info['workspace']}")
# Only add channel if it's not the default "web" # Only add channel if it's not the default "web"
if runtime_info.get("channel") and runtime_info.get("channel") != "web": if runtime_info.get("channel") and runtime_info.get("channel") != "web":
runtime_parts.append(f"渠道={runtime_info['channel']}" if language == "zh" else f"channel={runtime_info['channel']}") runtime_parts.append(f"渠道={runtime_info['channel']}")
if not runtime_parts: if not runtime_parts:
return [] return []
if language == "zh":
lines = [ lines = [
"## 运行时信息", "## 运行时信息",
"", "",
"运行时: " + " | ".join(runtime_parts), "运行时: " + " | ".join(runtime_parts),
"" ""
] ]
else:
lines = [
"## Runtime",
"",
"Runtime: " + " | ".join(runtime_parts),
""
]
return lines return lines

View File

@@ -47,8 +47,8 @@ def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> Works
soul_path = os.path.join(workspace_dir, DEFAULT_SOUL_FILENAME) soul_path = os.path.join(workspace_dir, DEFAULT_SOUL_FILENAME)
user_path = os.path.join(workspace_dir, DEFAULT_USER_FILENAME) user_path = os.path.join(workspace_dir, DEFAULT_USER_FILENAME)
agents_path = os.path.join(workspace_dir, DEFAULT_AGENTS_FILENAME) agents_path = os.path.join(workspace_dir, DEFAULT_AGENTS_FILENAME)
memory_path = os.path.join(workspace_dir, DEFAULT_MEMORY_FILENAME) memory_path = os.path.join(workspace_dir, DEFAULT_MEMORY_FILENAME) # MEMORY.md 在根目录
memory_dir = os.path.join(workspace_dir, "memory") memory_dir = os.path.join(workspace_dir, "memory") # 每日记忆子目录
# 创建memory子目录 # 创建memory子目录
os.makedirs(memory_dir, exist_ok=True) os.makedirs(memory_dir, exist_ok=True)
@@ -197,9 +197,9 @@ def _get_soul_template() -> str:
def _get_user_template() -> str: def _get_user_template() -> str:
"""用户身份信息模板""" """用户身份信息模板"""
return """# USER.md - 关于我的用户 return """# USER.md - 用户基本信息
*了解你正在帮助的人。随着了解的深入,更新此文件。* *这个文件只存放不会变的基本身份信息。爱好、偏好、计划等动态信息请写入 MEMORY.md。*
## 基本信息 ## 基本信息
@@ -214,24 +214,14 @@ def _get_user_template() -> str:
- **邮箱**: - **邮箱**:
- **其他**: - **其他**:
## 偏好设置
- **语言**: 中文
- **工作时间**: *(例如: 9:00-18:00)*
- **提醒方式**: *(用户偏好的提醒方式)*
## 重要日期 ## 重要日期
- **生日**: - **生日**:
- **其他重要日期**: - **纪念日**:
## 上下文
*(用户关心什么?正在做什么项目?有什么习惯?什么会让他们开心?随着时间积累这些信息。)*
--- ---
**记住**: 你了解得越多,就能帮助得越好。但要尊重隐私 - 这是在了解一个人,而不是建立档案。 **注意**: 这个文件存放静态的身份信息
""" """
@@ -270,18 +260,31 @@ def _get_agents_template() -> str:
- **仅在主会话中加载**(与用户的直接聊天) - **仅在主会话中加载**(与用户的直接聊天)
- **不要在共享上下文中加载**(群聊、与其他人的会话) - **不要在共享上下文中加载**(群聊、与其他人的会话)
- 这是为了**安全** - 包含不应泄露给陌生人的个人上下文 - 这是为了**安全** - 包含不应泄露给陌生人的个人上下文
- 你可以在主会话中自由**读取、编辑和更新** MEMORY.md
- 记录重要事件、想法、决定、观点、经验教训 - 记录重要事件、想法、决定、观点、经验教训
- 这是你精选的记忆 - 精华,而不是原始日志 - 这是你精选的记忆 - 精华,而不是原始日志
- 用 `edit` 工具追加新的记忆内容
### 📝 写下来 - 不要"记在心里" ### 📝 写下来 - 不要"记在心里"
- **记忆是有限的** - 如果你想记住某事,写入文件 - **记忆是有限的** - 如果你想记住某事,写入文件
- "记在心里"不会在会话重启后保留,文件才会 - "记在心里"不会在会话重启后保留,文件才会
- 当有人说"记住这个" → 更新 `memory/YYYY-MM-DD.md` 或相关文件 - 当有人说"记住这个" → 更新 `MEMORY.md` 或 `memory/YYYY-MM-DD.md`
- 当你学到教训 → 更新 AGENTS.md、TOOLS.md 或相关技能 - 当你学到教训 → 更新 AGENTS.md、TOOLS.md 或相关技能
- 当你犯错 → 记录下来,这样未来的你不会重复 - 当你犯错 → 记录下来,这样未来的你不会重复
- **文字 > 大脑** 📝 - **文字 > 大脑** 📝
### 存储规则
当用户分享信息时,根据类型选择存储位置:
1. **静态身份 → USER.md**(仅限:姓名、职业、时区、联系方式、生日)
2. **动态记忆 → MEMORY.md**(爱好、偏好、决策、目标、项目、教训、待办事项)
3. **当天对话 → memory/YYYY-MM-DD.md**(今天聊的内容)
**重要**:
- 爱好(唱歌、篮球等)→ MEMORY.md不是 USER.md
- 近期计划(下周要做什么)→ MEMORY.md不是 USER.md
- USER.md 只存放不会变的基本信息
## 安全 ## 安全
- 永远不要泄露私人数据 - 永远不要泄露私人数据
@@ -290,7 +293,7 @@ def _get_agents_template() -> str:
## 工具使用 ## 工具使用
技能提供你的工具。当你需要一个时,查看它的 `SKILL.md`。在 `TOOLS.md` 中保留本地笔记相机名称、SSH详情、语音偏好 技能提供你的工具。当你需要一个时,查看它的 `SKILL.md`。
## 让它成为你的 ## 让它成为你的
@@ -299,34 +302,13 @@ def _get_agents_template() -> str:
def _get_memory_template() -> str: def _get_memory_template() -> str:
"""长期记忆模板""" """长期记忆模板 - 创建一个空文件,由 Agent 自己填充"""
return """# MEMORY.md - 长期记忆 return """# MEMORY.md - 长期记忆
*这是你精选的长期记忆。重要的背景信息、决策和经验教训都记录在这里。* *这是你的长期记忆文件。记录重要的事件、决策、偏好、学到的教训。*
## 重要背景
*(记录与用户相关的重要背景信息)*
## 关键决策
*(记录做过的重要决定及其原因)*
## 经验教训
*(记录学到的教训和避免的陷阱)*
## 项目和目标
*(记录正在进行的项目和长期目标)*
--- ---
**使用指南**:
- 定期从每日记忆文件中提取重要内容更新到这里
- 保持内容精炼和有价值
- 移除过时或不再相关的信息
- 这应该是精华的总结,而不是流水账
""" """

View File

@@ -22,7 +22,7 @@ class MemoryGetTool(BaseTool):
"properties": { "properties": {
"path": { "path": {
"type": "string", "type": "string",
"description": "Relative path to the memory file (e.g., 'memory/MEMORY.md', 'memory/2024-01-29.md')" "description": "Relative path to the memory file (e.g., 'MEMORY.md', 'memory/2024-01-29.md')"
}, },
"start_line": { "start_line": {
"type": "integer", "type": "integer",

View File

@@ -85,7 +85,7 @@ class MemorySearchTool(BaseTool):
return ToolResult.success( return ToolResult.success(
f"No memories found for '{query}'. " f"No memories found for '{query}'. "
f"This is normal if no memories have been stored yet. " f"This is normal if no memories have been stored yet. "
f"You can store new memories by writing to memory/MEMORY.md or memory/YYYY-MM-DD.md files." f"You can store new memories by writing to MEMORY.md or memory/YYYY-MM-DD.md files."
) )
# Format results # Format results