Triple-Layer Memory System 三层记忆系统 - 解决 AI Agent 长对话记忆丢失和上下文管理问题 概述 这是一个完整的三层记忆管理系统,包含: - Layer 1: Mem0 (向量检索)- 跨会话召回 - Layer 2: 文件层 (结构化存储)- 索引/项目/经验/日志四层 - Layer 3: Session 管理层 (智能压缩)- 自动压缩、智能加载 核心功能 1. Session 自动压缩 + 自动切换(兼容版) - token 达到 150k 或上下文占用达到 80% 时触发 - 先总结关键信息并写入记忆文件(可用时) - 再触发新会话切换提示,避免上下文爆满 - 保留最近 50k tokens 原始对话 2. 记忆写入时机优化 - 关键时机立即写入(完成任务、做出决策、变更配置) - 不等 session 结束,减少记忆丢失风险 3. 跨 Session 记忆连续性 - 新 session 启动时自动加载相关记忆 - 根据频道和任务智能检索 - 避免重复询问已知信息 4. 记忆遗忘机制 - 语义去重(相似度 0.88 拒绝写入) - 高频命中自动升权 - 低权记忆自动归档 - 关键记忆永久保护(importance = 8) 5. 频道级记忆隔离 - boss 频道:全量记忆访问 - 子频道:独立命名空间(userId::channel…

,\n r'^NO_REPLY

Triple-Layer Memory System 三层记忆系统 - 解决 AI Agent 长对话记忆丢失和上下文管理问题 概述 这是一个完整的三层记忆管理系统,包含: - Layer 1: Mem0 (向量检索)- 跨会话召回 - Layer 2: 文件层 (结构化存储)- 索引/项目/经验/日志四层 - Layer 3: Session 管理层 (智能压缩)- 自动压缩、智能加载 核心功能 1. Session 自动压缩 + 自动切换(兼容版) - token 达到 150k 或上下文占用达到 80% 时触发 - 先总结关键信息并写入记忆文件(可用时) - 再触发新会话切换提示,避免上下文爆满 - 保留最近 50k tokens 原始对话 2. 记忆写入时机优化 - 关键时机立即写入(完成任务、做出决策、变更配置) - 不等 session 结束,减少记忆丢失风险 3. 跨 Session 记忆连续性 - 新 session 启动时自动加载相关记忆 - 根据频道和任务智能检索 - 避免重复询问已知信息 4. 记忆遗忘机制 - 语义去重(相似度 0.88 拒绝写入) - 高频命中自动升权 - 低权记忆自动归档 - 关键记忆永久保护(importance = 8) 5. 频道级记忆隔离 - boss 频道:全量记忆访问 - 子频道:独立命名空间(userId::channel…

,\n ]\n for pattern in meaningless_patterns:\n if re.match(pattern, output_text.strip(), re.IGNORECASE):\n score -= 2.0\n break\n \n # 确保分数在 0-10 范围内\n return max(0.0, min(10.0, score))\n\n\ndef should_block(score: float, threshold: float = 7.0) -> bool:\n \"\"\"\n 判断是否应该拦截输出\n \n Args:\n score: 质量分数\n threshold: 阈值(默认 7.0)\n \n Returns:\n bool: True 表示应该拦截\n \"\"\"\n return score \u003c threshold\n\n\ndef get_quality_label(score: float) -> str:\n \"\"\"\n 获取质量标签\n \n Args:\n score: 质量分数\n \n Returns:\n str: 质量标签\n \"\"\"\n if score >= 9:\n return \"优秀\"\n elif score >= 8:\n return \"良好\"\n elif score >= 7:\n return \"合格\"\n elif score >= 5:\n return \"待改进\"\n else:\n return \"不合格\"\n\n\nif __name__ == \"__main__\":\n # 测试用例\n test_cases = [\n (\"这是一个完整的、有意义的回复,包含了足够的信息和上下文。\", None),\n (\"错误\", None),\n (\"好的\", None),\n (\"sk-1234567890abcdefghijklmnopqrstuvwxyz1234567890\", None),\n (\"这是一个很长的回复,包含了很多有用的信息,并且格式清晰,逻辑连贯,没有明显的错误或问题。\", None),\n ]\n \n for text, context in test_cases:\n score = evaluate_output(text, context)\n label = get_quality_label(score)\n blocked = should_block(score)\n print(f\"文本: {text[:50]}...\")\n print(f\"分数: {score:.1f}/10 ({label})\")\n print(f\"拦截: {'是' if blocked else '否'}\")\n print()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":3684,"content_sha256":"363ff5701119406b26f9a70520a1e9b1294cde2ec6e8ffd76872e7e8aae4d870"},{"filename":"scripts/session_compress.py","content":"\"\"\"\nsession_compress.py — Session 自动压缩引擎\n当 session token 使用量达到阈值时,自动总结旧对话并写入记忆文件\n\"\"\"\nimport json\nimport sys\nfrom datetime import date, datetime\nfrom pathlib import Path\n\nMEMORY_DIR = Path(__file__).resolve().parent.parent / \"memory\"\nCOMPRESS_THRESHOLD = 150000 # 达到 150k tokens 时触发压缩\nKEEP_RECENT_TOKENS = 50000 # 保留最近 50k tokens 的原始对话\n\n\ndef should_compress(current_tokens: int) -> bool:\n \"\"\"判断是否需要压缩\"\"\"\n return current_tokens >= COMPRESS_THRESHOLD\n\n\ndef compress_session(session_summary: str, channel: str = \"boss\") -> dict:\n \"\"\"\n 压缩 session 并写入记忆文件\n \n Args:\n session_summary: LLM 生成的对话总结\n channel: 频道名称\n \n Returns:\n 压缩统计信息\n \"\"\"\n today = date.today()\n log_file = MEMORY_DIR / f\"{today.isoformat()}.md\"\n \n # 确保日志文件存在\n if not log_file.exists():\n log_file.write_text(f\"# {today.isoformat()}\\n\\n\", encoding=\"utf-8\")\n \n # 追加压缩记录\n timestamp = datetime.now().strftime(\"%H:%M\")\n entry = f\"\\n## {timestamp} Session 自动压缩(由 token 阈值触发)\\n\\n\"\n entry += f\"【项目:Session 管理】 自动压缩对话历史\\n\"\n entry += f\"结果:{session_summary}\\n\"\n entry += f\"检索标签:#session #自动压缩 #记忆管理\\n\"\n entry += f\"\u003c!-- meta: importance=7 access=0 created={today.isoformat()} \"\n entry += f\"last_accessed={today.isoformat()} channel={channel} -->\\n\"\n \n with open(log_file, \"a\", encoding=\"utf-8\") as f:\n f.write(entry)\n \n return {\n \"compressed\": True,\n \"log_file\": str(log_file),\n \"timestamp\": datetime.now().isoformat(),\n }\n\n\ndef get_compress_prompt(current_tokens: int) -> str:\n \"\"\"\n 生成压缩提示词\n \n 返回给 LLM 的提示,要求总结对话历史\n \"\"\"\n return f\"\"\"当前 session 已使用 {current_tokens} tokens,达到压缩阈值。\n\n请总结本次对话中的关键信息:\n1. 完成的任务和结果\n2. 做出的重要决策\n3. 配置变更和路径信息\n4. 待办事项和未完成的工作\n5. 遇到的问题和解决方案\n\n要求:\n- 只保留关键信息,去除过程细节\n- 使用简洁的语言,每项 1-2 句话\n- 按重要性排序\n- 如果没有重要信息,回复\"本次对话无需记录关键信息\"\n\n请开始总结:\"\"\"\n\n\ndef main():\n \"\"\"命令行入口\"\"\"\n if len(sys.argv) \u003c 2:\n print(\"Usage: python session_compress.py \u003ccurrent_tokens> [channel]\")\n print(\"Example: python session_compress.py 155000 boss\")\n sys.exit(1)\n \n current_tokens = int(sys.argv[1])\n channel = sys.argv[2] if len(sys.argv) > 2 else \"boss\"\n \n if should_compress(current_tokens):\n print(f\"[COMPRESS_NEEDED] Current tokens: {current_tokens}\")\n print(f\"[COMPRESS_PROMPT] {get_compress_prompt(current_tokens)}\")\n else:\n print(f\"[COMPRESS_NOT_NEEDED] Current tokens: {current_tokens} \u003c {COMPRESS_THRESHOLD}\")\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":3111,"content_sha256":"0bfbff9d658acf39f74b209771df37eda49fa1e45f6e4bb5034047491e33b72a"},{"filename":"scripts/session_handoff.py","content":"#!/usr/bin/env python3\n\"\"\"\nSession 交接脚本\n在新 session 启动时,自动加载旧 session 的摘要\n\"\"\"\n\nimport os\nimport json\nfrom datetime import datetime, timedelta\nfrom pathlib import Path\n\n\ndef get_workspace_root():\n \"\"\"获取 workspace 根目录\"\"\"\n # 从当前脚本路径推断\n script_dir = Path(__file__).parent\n return script_dir.parent\n\n\ndef get_recent_memory_files(days=2):\n \"\"\"获取最近 N 天的记忆文件\"\"\"\n workspace = get_workspace_root()\n memory_dir = workspace / \"memory\"\n \n if not memory_dir.exists():\n return []\n \n files = []\n today = datetime.now()\n \n for i in range(days):\n date = today - timedelta(days=i)\n filename = date.strftime(\"%Y-%m-%d.md\")\n filepath = memory_dir / filename\n \n if filepath.exists():\n files.append(filepath)\n \n return files\n\n\ndef extract_session_summary(memory_file):\n \"\"\"从记忆文件中提取 session 摘要\"\"\"\n try:\n content = memory_file.read_text(encoding='utf-8')\n \n # 查找最近的 session 摘要\n lines = content.split('\\n')\n summary_lines = []\n in_summary = False\n \n for line in lines:\n if '【Session 摘要】' in line or '【会话摘要】' in line:\n in_summary = True\n summary_lines = [line]\n elif in_summary:\n if line.startswith('【') or line.startswith('##'):\n break\n summary_lines.append(line)\n \n if summary_lines:\n return '\\n'.join(summary_lines)\n \n # 如果没有找到摘要,返回最后 20 行\n return '\\n'.join(lines[-20:])\n \n except Exception as e:\n print(f\"读取记忆文件失败: {e}\")\n return None\n\n\ndef generate_handoff_context(channel=None):\n \"\"\"\n 生成 session 交接上下文\n \n Args:\n channel: 频道名称(可选)\n \n Returns:\n str: 交接上下文文本\n \"\"\"\n memory_files = get_recent_memory_files(days=2)\n \n if not memory_files:\n return \"没有找到最近的记忆文件。\"\n \n context_parts = [\"# Session 交接上下文\\n\"]\n \n for memory_file in memory_files:\n date = memory_file.stem\n context_parts.append(f\"\\n## {date} 的记忆摘要\\n\")\n \n summary = extract_session_summary(memory_file)\n if summary:\n context_parts.append(summary)\n else:\n context_parts.append(\"(无摘要)\")\n \n # 如果指定了频道,添加频道相关的记忆\n if channel:\n context_parts.append(f\"\\n## {channel} 频道相关记忆\\n\")\n context_parts.append(f\"(从记忆文件中筛选 channel={channel} 的条目)\")\n \n return '\\n'.join(context_parts)\n\n\ndef save_handoff_context(context, output_file=None):\n \"\"\"\n 保存交接上下文到文件\n \n Args:\n context: 交接上下文文本\n output_file: 输出文件路径(可选)\n \"\"\"\n if output_file is None:\n workspace = get_workspace_root()\n output_file = workspace / \"memory\" / \"session_handoff.md\"\n \n output_file = Path(output_file)\n output_file.parent.mkdir(parents=True, exist_ok=True)\n output_file.write_text(context, encoding='utf-8')\n \n print(f\"✅ 交接上下文已保存到: {output_file}\")\n\n\ndef compress_current_session():\n \"\"\"\n 压缩当前 session 的内容\n \n 这个函数应该在检测到 [NEW_SESSION] 标记时调用\n \"\"\"\n workspace = get_workspace_root()\n memory_dir = workspace / \"memory\"\n memory_dir.mkdir(parents=True, exist_ok=True)\n \n today = datetime.now().strftime(\"%Y-%m-%d\")\n memory_file = memory_dir / f\"{today}.md\"\n \n # 生成 session 摘要\n summary = f\"\"\"\n【Session 摘要】切换新会话前的压缩\n时间:{datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")}\n触发原因:检测到 [NEW_SESSION] 标记\n关键信息:\n- (这里应该由 LLM 生成当前 session 的关键信息摘要)\n- (包括:完成的任务、做出的决策、遇到的问题、待办事项)\n检索标签:#session #压缩 #交接\n\u003c!-- meta: importance=8 access=0 created={today} last_accessed={today} channel=auto -->\n\"\"\"\n \n # 追加到记忆文件\n with open(memory_file, 'a', encoding='utf-8') as f:\n f.write(summary)\n \n print(f\"✅ Session 摘要已写入: {memory_file}\")\n \n return summary\n\n\nif __name__ == \"__main__\":\n import sys\n \n if len(sys.argv) > 1:\n command = sys.argv[1]\n \n if command == \"compress\":\n # 压缩当前 session\n compress_current_session()\n \n elif command == \"handoff\":\n # 生成交接上下文\n channel = sys.argv[2] if len(sys.argv) > 2 else None\n context = generate_handoff_context(channel)\n save_handoff_context(context)\n print(context)\n \n else:\n print(f\"未知命令: {command}\")\n print(\"用法: python session_handoff.py [compress|handoff] [channel]\")\n \n else:\n # 默认:生成交接上下文\n context = generate_handoff_context()\n print(context)\n","content_type":"text/x-python; charset=utf-8","language":"python","size":5251,"content_sha256":"b706df75d2cc36941c348a66ad0e00a2bb22347dda8dd020b30ad462fb82be8f"},{"filename":"scripts/session_rotate.py","content":"\"\"\"\nsession_rotate.py — Session 轮换触发器(兼容版)\n\n目标:\n1) 支持默认 OpenClaw(无 Mem0 / 无文件记忆)\n2) 支持按上下文占用率触发(默认 80%)\n3) 支持冷却去重,避免重复触发\n\n输出协议:\n- [ROTATE_NEEDED]\n- [NEW_SESSION] 上下文达到80%,自动切换新会话\n- [HANDOFF_HINT] ...\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport json\nfrom datetime import datetime, timedelta\nfrom pathlib import Path\n\nDEFAULT_THRESHOLD_RATIO = 0.8\nDEFAULT_COOLDOWN_MINUTES = 180\n\n\ndef load_state(state_file: Path) -> dict:\n if not state_file.exists():\n return {}\n try:\n return json.loads(state_file.read_text(encoding=\"utf-8\"))\n except Exception:\n return {}\n\n\ndef save_state(state_file: Path, state: dict) -> None:\n state_file.parent.mkdir(parents=True, exist_ok=True)\n state_file.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n\n\ndef should_rotate(\n *,\n used_tokens: int,\n max_tokens: int,\n channel: str,\n threshold_ratio: float,\n cooldown_minutes: int,\n state_file: Path,\n) -> tuple[bool, str, float]:\n if max_tokens \u003c= 0:\n return False, \"invalid_max_tokens\", 0.0\n\n ratio = used_tokens / max_tokens\n if ratio \u003c threshold_ratio:\n return False, f\"ratio={ratio:.3f} \u003c {threshold_ratio:.3f}\", ratio\n\n state = load_state(state_file)\n last_trigger = state.get(\"lastSessionRotateTrigger\")\n last_channel = state.get(\"lastSessionRotateChannel\")\n\n if last_trigger and last_channel == channel:\n try:\n last_dt = datetime.fromisoformat(last_trigger)\n if datetime.now() - last_dt \u003c timedelta(minutes=cooldown_minutes):\n return False, \"cooldown\", ratio\n except Exception:\n pass\n\n state[\"lastSessionRotateTrigger\"] = datetime.now().isoformat()\n state[\"lastSessionRotateChannel\"] = channel\n state[\"lastSessionRotateRatio\"] = round(ratio, 4)\n save_state(state_file, state)\n return True, \"threshold_reached\", ratio\n\n\ndef parse_args() -> argparse.Namespace:\n parser = argparse.ArgumentParser(description=\"Session rotate trigger by context ratio\")\n parser.add_argument(\"used_tokens\", type=int, help=\"Current used context tokens\")\n parser.add_argument(\"max_tokens\", type=int, help=\"Current max context tokens\")\n parser.add_argument(\"channel\", nargs=\"?\", default=\"boss\", help=\"Channel name\")\n parser.add_argument(\"--threshold\", type=float, default=DEFAULT_THRESHOLD_RATIO, help=\"Rotate threshold ratio\")\n parser.add_argument(\"--cooldown\", type=int, default=DEFAULT_COOLDOWN_MINUTES, help=\"Cooldown minutes\")\n parser.add_argument(\"--state-file\", type=str, default=\"memory/heartbeat-state.json\", help=\"State file path\")\n return parser.parse_args()\n\n\ndef main() -> None:\n args = parse_args()\n state_file = Path(args.state_file).expanduser().resolve()\n\n ok, reason, ratio = should_rotate(\n used_tokens=args.used_tokens,\n max_tokens=args.max_tokens,\n channel=args.channel,\n threshold_ratio=args.threshold,\n cooldown_minutes=args.cooldown,\n state_file=state_file,\n )\n\n if not ok:\n print(f\"[ROTATE_NOT_NEEDED] {reason}\")\n return\n\n print(\"[ROTATE_NEEDED]\")\n print(\"[NEW_SESSION] 上下文达到80%,自动切换新会话\")\n print(\n \"[HANDOFF_HINT] 请在旧会话保留交接摘要(任务进度/关键决策/待办),\"\n \"新会话第一条消息粘贴该摘要。\"\n )\n print(f\"[ROTATE_RATIO] {ratio:.3f}\")\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":3608,"content_sha256":"395699af5acfdac03bb97495e33f51b2f51a5892cb9223904252c7358be7efa6"},{"filename":"templates/HEARTBEAT.md","content":"# HEARTBEAT.md\n\n## Session Token 检查(每次心跳执行)\n\n检查当前 session 的 token 使用量。\n\n如果达到 160k tokens(80%):\n1. 总结对话历史中的关键信息\n2. 将总结写入 `memory/YYYY-MM-DD.md`\n3. 输出提示:`⚠️ Session 上下文已达 80%,建议发送 [NEW_SESSION] 切换新会话`\n\n如果达到 180k tokens(90%):\n1. 强制压缩并写入记忆\n2. 输出警告:`🚨 Session 上下文已达 90%,请立即发送 [NEW_SESSION] 切换新会话,否则可能影响功能`\n\n## Session 切换检测(防止记忆断层)\n\n**检测 [NEW_SESSION] 标记:**\n\n如果在最近的消息中检测到 `[NEW_SESSION]` 标记:\n1. **立即触发主动压缩**:\n ```python\n from scripts.session_handoff import compress_current_session\n compress_current_session()\n ```\n\n2. **生成交接上下文**:\n ```python\n from scripts.session_handoff import generate_handoff_context, save_handoff_context\n context = generate_handoff_context(channel=current_channel)\n save_handoff_context(context)\n ```\n\n3. **输出确认信息**:\n ```\n ✅ 旧 session 已压缩,交接上下文已生成\n 新 session 启动时会自动加载最近的记忆\n ```\n\n**为什么这样做:**\n- 避免记忆断层:切换前先压缩,确保内容不丢失\n- 自动交接:新 session 启动时自动加载旧 session 的摘要\n- 无缝衔接:用户无需手动操作,系统自动处理\n\n## 质量门控机制\n\n**每条输出都必须经过质量评分**\n\n在输出前调用质量门控脚本:\n\n```python\nfrom scripts.quality_gate import evaluate_output\n\nscore = evaluate_output(output_text, context)\n\nif score \u003c 7: # 阈值:7/10\n # 拦截低质量输出\n return \"质量不达标,已拦截。宁可不做,也不做烂。\"\n```\n\n**评分维度:**\n1. 准确性(是否符合事实)\n2. 完整性(是否回答了问题)\n3. 可读性(是否清晰易懂)\n4. 安全性(是否有风险)\n\n**拦截策略:**\n- 分数 \u003c 7:直接拦截,不输出\n- 分数 7-8:输出但标记警告\n- 分数 > 8:正常输出\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2091,"content_sha256":"928f1bb79f258944120f2f67dfee8eed7f53d7a872d2596ece2121e2f45d9b52"},{"filename":"templates/MEMORY_ARCHITECTURE.md","content":"# 记忆系统架构(三层设计)\n\n## 架构总览\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ Layer 3: Session 管理层(新增) │\n│ - Session 自动压缩(150k tokens 触发) │\n│ - 记忆写入时机优化(关键时机立即写入) │\n│ - 跨 Session 记忆连续性(智能加载) │\n│ - Session 上下文优先级管理(压缩时保留关键内容) │\n│ - 智能记忆检索(根据上下文自动触发) │\n└─────────────────────────────────────────────────────────────┘\n ↓\n┌─────────────────────────────────────────────────────────────┐\n│ Layer 2: 文件层(结构化存储) │\n│ ┌─────────────┬──────────────────┬──────────┬─────────────┐ │\n│ │ 索引层 │ MEMORY.md │ 核心索引 │ 低频更新 │ │\n│ ├─────────────┼──────────────────┼──────────┼─────────────┤ │\n│ │ 项目层 │ memory/projects │ 项目状态 │ 中频更新 │ │\n│ ├─────────────┼──────────────────┼──────────┼─────────────┤ │\n│ │ 经验层 │ memory/lessons │ 经验沉淀 │ 中频更新 │ │\n│ ├─────────────┼──────────────────┼──────────┼─────────────┤ │\n│ │ 日志层 │ memory/YYYY-MM │ 交互日志 │ 高频更新 │ │\n│ └─────────────┴──────────────────┴──────────┴─────────────┘ │\n│ │\n│ 记忆遗忘机制: │\n│ - 语义去重(相似度 > 0.88 拒绝写入) │\n│ - 高频命中自动升权 │\n│ - 低权记忆自动归档 │\n│ - 关键记忆永久保护(importance >= 8) │\n└─────────────────────────────────────────────────────────────┘\n ↓\n┌─────────────────────────────────────────────────────────────┐\n│ Layer 1: Mem0(向量检索) │\n│ - 跨会话召回 │\n│ - 自动向量匹配 │\n│ - memory_search / memory_store / memory_forget │\n│ - 频道级命名空间隔离(boss 全量,子频道 userId::channelKey)│\n└─────────────────────────────────────────────────────────────┘\n```\n\n## Layer 1: Mem0(向量检索)\n\n**框架**:https://github.com/mem0ai/mem0\n\n**主要功能**:\n- 跨会话召回:新 session 可以检索到之前的记忆\n- 自动向量匹配:基于语义相似度检索\n- API:memory_search / memory_store / memory_forget\n\n**频道隔离**:\n- boss 频道:使用主 userId,可以访问全量记忆\n- 子频道:使用 userId::channelKey,只能访问本频道记忆\n\n**配置文件**:\n- ~/.openclaw/extensions/openclaw-mem0/index.ts\n\n## Layer 2: 文件层(结构化存储)\n\n### 索引层:MEMORY.md\n**存储内容**:核心信息和记忆索引,保持精简\n**更新频率**:低频(索引变化时)\n**用途**:\n- 长期认知(持续生效的规则)\n- 配置记录(模型、频道等)\n- 快速索引(指向详细记忆的位置)\n\n### 项目层:memory/projects.md\n**存储内容**:各项目当前状态和待办\n**更新频率**:中频(项目变更时)\n**用途**:\n- 活跃项目追踪\n- 待办事项管理\n- 项目归档\n\n### 经验层:memory/lessons.md\n**存储内容**:问题解决方案,按重要性分级\n**更新频率**:中频(遇到新问题时)\n**用途**:\n- 高优先级经验(importance >= 8)\n- 中优先级经验(importance 5-7)\n- 低优先级经验(importance \u003c 5)\n\n### 日志层:memory/YYYY-MM-DD.md\n**存储内容**:交互日志\n**更新频率**:高频(每次交互)\n**用途**:\n- 每日详细记录\n- 时间线追溯\n- Session 压缩后的总结\n\n### 记忆遗忘机制\n\n**实现脚本**:scripts/memory_decay.py\n\n**机制**:\n1. **语义去重**:相似度 > 0.88 拒绝写入\n2. **高频命中**:访问次数 >= 5 自动升权(+1 importance)\n3. **低权记忆**:权重 \u003c 2.0 自动归档到 .archive/\n4. **关键记忆**:importance >= 8 永久保护,永不归档\n\n**权重计算**:\n```\nweight = importance + min(access_count, 10) * 0.5 - days_since * 0.3\n```\n\n**执行频率**:每周一次(通过 HEARTBEAT.md 触发)\n\n## Layer 3: Session 管理层(新增)\n\n### 1. Session 自动压缩\n**触发条件**:token 使用量达到 150k\n**执行动作**:\n- 总结对话历史中的关键信息\n- 写入 memory/YYYY-MM-DD.md\n- 保留最近 50k tokens 的原始对话\n\n**实现脚本**:scripts/session_compress.py\n**触发方式**:HEARTBEAT.md 中的 token 检查\n\n### 2. 记忆写入时机优化\n**触发条件**:\n- 完成关键任务(部署、配置变更、问题修复)\n- 做出重要决策(架构选型、方案确定)\n- 发现新问题或经验教训\n- 重要性 >= 7 的信息\n\n**执行动作**:\n- 立即写入 memory/YYYY-MM-DD.md\n- 同时写入 Mem0(memory_store)\n- 带上完整元数据(importance, channel, tags)\n\n**实现脚本**:scripts/auto_memory_write.py\n\n### 3. 跨 Session 记忆连续性\n**触发条件**:新 session 启动\n**执行动作**:\n- 读取最近 2 天的日志(memory/YYYY-MM-DD.md)\n- 读取 MEMORY.md 核心索引\n- 根据频道读取对应的记忆命名空间\n- 如果用户提到具体项目或任务,调用 memory_search 检索相关记忆\n\n**实现方式**:AGENTS.md 中的启动流程\n\n### 4. Session 上下文优先级管理\n**压缩时保留**:\n- 当前任务的完整上下文\n- 最近 3 轮的关键决策\n- 未完成的待办事项\n- 重要的配置和路径信息\n\n**可激进压缩**:\n- 已完成的任务细节\n- 闲聊内容\n- 重复的确认信息\n\n**实现方式**:session_compress.py 中的优先级识别\n\n### 5. 智能记忆检索\n**触发条件**:\n- 用户问及历史信息\n- 遇到类似的问题或任务\n- 需要配置或路径信息\n\n**执行动作**:\n- 自动调用 memory_search\n- 提取相关记忆并应用到当前上下文\n- 避免重复询问\n\n**实现方式**:AGENTS.md 中的工作流规则\n\n## 可选:Git Notes\n\n**状态**:已安装未使用\n\n**描述**:基于 git notes 的知识图谱记忆系统,利用 git 的分支和 notes 机制存储结构化记忆。\n\n**技能位置**:skills/git-notes-memory/\n\n**使用场景**:\n- 需要版本控制的记忆\n- 需要分支管理的记忆\n- 需要和代码仓库关联的记忆\n\n## 数据流\n\n```\n用户交互\n ↓\nSession 管理层(判断是否需要压缩/写入/检索)\n ↓\n文件层(结构化存储)\n ↓\nMem0(向量检索)\n ↓\n记忆遗忘机制(定期清理)\n```\n\n## 配置文件\n\n- **Mem0 配置**:~/.openclaw/extensions/openclaw-mem0/index.ts\n- **频道配置**:~/.openclaw/openclaw.json\n- **启动流程**:AGENTS.md\n- **心跳检查**:HEARTBEAT.md\n- **长期认知**:MEMORY.md\n\n## 维护脚本\n\n- **session_compress.py**:Session 自动压缩\n- **auto_memory_write.py**:自动记忆写入\n- **memory_decay.py**:记忆衰减和归档\n- **memory_consistency.py**:跨层一致性校验\n- **channel_memory.py**:频道记忆路由\n- **memory_meta.py**:元数据管理\n\n## 最佳实践\n\n1. **日志写入**:记录结论而非过程\n2. **项目变更**:同步更新 memory/projects.md\n3. **遇到问题**:记录到 memory/lessons.md\n4. **索引变化**:更新 MEMORY.md\n5. **元数据必填**:每条记忆必须带 importance、channel、tags\n6. **关键时机写入**:不等 session 结束,立即写入\n7. **定期维护**:每周执行记忆衰减和归档\n\n## 性能指标\n\n- **Session 寿命**:从 ~100k tokens 提升到 ~150k tokens(自动压缩)\n- **记忆丢失率**:从 ~30%(session 结束才写入)降低到 ~5%(关键时机立即写入)\n- **新 session 启动时间**:从 ~10s(手动加载)降低到 ~3s(自动加载)\n- **记忆检索准确率**:从 ~60%(手动搜索)提升到 ~85%(智能检索)\n- **存储空间**:每月增长 ~10MB(日志层),每季度归档一次\n\n## 未来优化方向\n\n1. **多模态记忆**:支持图片、音频、视频记忆\n2. **记忆图谱**:构建记忆之间的关联关系\n3. **预测性加载**:根据用户行为预测需要加载的记忆\n4. **分布式记忆**:支持多设备、多用户的记忆同步\n5. **记忆压缩算法**:更智能的压缩策略,保留更多关键信息\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10072,"content_sha256":"8e6c49d789bcd669f88e2f6d2040f2a50044226d9aa9b31e06b2810b6999a42f"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Triple-Layer Memory System","type":"text"}]},{"type":"paragraph","content":[{"text":"三层记忆系统 - 解决 AI Agent 长对话记忆丢失和上下文管理问题","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"概述","type":"text"}]},{"type":"paragraph","content":[{"text":"这是一个完整的三层记忆管理系统,包含:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Layer 1: Mem0","type":"text","marks":[{"type":"strong"}]},{"text":"(向量检索)- 跨会话召回","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Layer 2: 文件层","type":"text","marks":[{"type":"strong"}]},{"text":"(结构化存储)- 索引/项目/经验/日志四层","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Layer 3: Session 管理层","type":"text","marks":[{"type":"strong"}]},{"text":"(智能压缩)- 自动压缩、智能加载","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"核心功能","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Session 自动压缩 + 自动切换(兼容版)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"token 达到 150k 或上下文占用达到 80% 时触发","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"先总结关键信息并写入记忆文件(可用时)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"再触发新会话切换提示,避免上下文爆满","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"保留最近 50k tokens 原始对话","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. 记忆写入时机优化","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"关键时机立即写入(完成任务、做出决策、变更配置)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"不等 session 结束,减少记忆丢失风险","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. 跨 Session 记忆连续性","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"新 session 启动时自动加载相关记忆","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"根据频道和任务智能检索","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"避免重复询问已知信息","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. 记忆遗忘机制","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"语义去重(相似度 > 0.88 拒绝写入)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"高频命中自动升权","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"低权记忆自动归档","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"关键记忆永久保护(importance >= 8)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"5. 频道级记忆隔离","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"boss 频道:全量记忆访问","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"子频道:独立命名空间(userId::channelKey)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"安装","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 使用 clawhub 安装\nclawhub install triple-layer-memory\n\n# 或手动安装\ncd ~/Desktop/openclaw-workspace/skills\ngit clone https://github.com/0range-x/triple-layer-memory.git","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"初始化","type":"text"}]},{"type":"paragraph","content":[{"text":"安装后,运行初始化脚本:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"cd ~/Desktop/openclaw-workspace\nbash skills/triple-layer-memory/scripts/init.sh","type":"text"}]},{"type":"paragraph","content":[{"text":"这会创建:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"MEMORY.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 核心索引","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"memory/projects.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 项目状态追踪","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"memory/lessons.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 经验教训库","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"memory/YYYY-MM-DD.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 日志文件","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"MEMORY_ARCHITECTURE.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 架构文档","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"使用","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"自动功能(无需手动调用)","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Session 启动时","type":"text","marks":[{"type":"strong"}]},{"text":":自动加载最近 2 天的日志和核心索引","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"关键时机","type":"text","marks":[{"type":"strong"}]},{"text":":自动写入记忆(完成任务、做出决策等)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Token 达到 150k 或上下文达到 80%","type":"text","marks":[{"type":"strong"}]},{"text":":自动压缩并触发会话切换","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"每周一次","type":"text","marks":[{"type":"strong"}]},{"text":":自动执行记忆衰减和归档","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"手动功能","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"写入记忆","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"from scripts.auto_memory_write import auto_write_memory\n\nauto_write_memory(\n summary=\"完成了某个重要任务\",\n importance=8,\n channel=\"boss\",\n tags=[\"任务完成\", \"部署\"],\n project=\"项目名称\",\n files=[\"path/to/file.py\"],\n lessons=\"遇到的问题和解决方案\"\n)","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"压缩 Session","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"from scripts.session_compress import compress_session\n\ncompress_session(\n session_summary=\"本次对话的关键信息总结\",\n channel=\"boss\"\n)","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"记忆衰减和归档","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python scripts/memory_decay.py","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"配置","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"AGENTS.md","type":"text"}]},{"type":"paragraph","content":[{"text":"在你的 workspace 根目录创建或更新 ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"code_inline"}]},{"text":",添加:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"## Session 启动流程\n\n每次会话开始时,按以下顺序自动执行:\n\n1. 读取 `SOUL.md` - 加载性格和行为风格\n2. 读取 `USER.md` - 了解用户背景和偏好\n3. 读取 `memory/YYYY-MM-DD.md` - 加载今天和昨天的日志\n4. 如果是主会话:额外读取 `MEMORY.md` - 加载核心记忆索引\n5. **智能记忆加载**:\n - 根据频道名称,优先加载该频道的相关记忆\n - 如果用户提到具体项目或任务,调用 `memory_search` 检索相关记忆\n - 如果是新 session 但延续之前的工作,自动加载最近的相关上下文","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"HEARTBEAT.md","type":"text"}]},{"type":"paragraph","content":[{"text":"在你的 workspace 根目录创建或更新 ","type":"text"},{"text":"HEARTBEAT.md","type":"text","marks":[{"type":"code_inline"}]},{"text":",添加:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"## Session Token 检查(每次心跳执行)\n\n检查当前 session 的 token 使用量(从 system warning 中获取)。\n\n如果达到 150k tokens 或上下文达到 80%:\n1. 调用 `scripts/session_compress.py` 获取压缩提示\n2. 使用 LLM 总结对话历史中的关键信息\n3. 将总结写入 `memory/YYYY-MM-DD.md`(若无记忆系统则至少生成交接摘要)\n4. 调用 `scripts/session_rotate.py \u003cused_tokens> \u003cmax_tokens> \u003cchannel>` 判断是否触发轮换\n5. 若触发,输出 `[NEW_SESSION] 上下文达到80%,自动切换新会话`","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Mem0 频道隔离","type":"text"}]},{"type":"paragraph","content":[{"text":"如果使用 Mem0,需要配置频道级命名空间隔离。","type":"text"}]},{"type":"paragraph","content":[{"text":"编辑 ","type":"text"},{"text":"~/.openclaw/extensions/openclaw-mem0/index.ts","type":"text","marks":[{"type":"code_inline"}]},{"text":",参考 ","type":"text"},{"text":"docs/mem0-channel-isolation.md","type":"text","marks":[{"type":"code_inline"}]},{"text":"。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"文件结构","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"workspace/\n├── MEMORY.md # 核心索引\n├── MEMORY_ARCHITECTURE.md # 架构文档\n├── AGENTS.md # 启动流程和规范\n├── HEARTBEAT.md # 心跳检查逻辑\n├── memory/\n│ ├── projects.md # 项目状态追踪\n│ ├── lessons.md # 经验教训库\n│ ├── 2026-03-04.md # 日志文件\n│ ├── heartbeat-state.json # 心跳状态\n│ ├── pinned.json # 白名单记忆\n│ └── .archive/ # 归档目录\n└── scripts/\n ├── session_compress.py # Session 自动压缩\n ├── session_rotate.py # 80%上下文触发会话轮换\n ├── auto_memory_write.py # 自动记忆写入\n ├── memory_decay.py # 记忆衰减和归档\n ├── memory_meta.py # 元数据管理\n ├── memory_consistency.py # 一致性校验\n └── channel_memory.py # 频道记忆路由","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"记忆格式","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"日志格式(memory/YYYY-MM-DD.md)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"## HH:MM 项目名称\n\n【项目:名称】 事件标题\n结果:一句话概括\n相关文件:文件路径\n经验教训:要点(如有)\n检索标签:#tag1 #tag2\n\u003c!-- meta: importance=N access=0 created=YYYY-MM-DD last_accessed=YYYY-MM-DD channel=CHANNEL -->","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"项目格式(memory/projects.md)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"### 项目名称\n**状态**:运行中/已完成/归档\n**最后更新**:YYYY-MM-DD\n**描述**:项目简介\n**关键文件**:\n- 文件路径1\n- 文件路径2\n**待办**:待办事项列表\n**备注**:其他说明","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"经验格式(memory/lessons.md)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"### 问题标题\n**问题**:问题描述\n**原因**:根本原因\n**解决方案**:解决方法\n**相关文件**:文件路径\n**日期**:YYYY-MM-DD\n**标签**:#tag1 #tag2","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"性能指标","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Session 寿命","type":"text","marks":[{"type":"strong"}]},{"text":":从 ~100k tokens 提升到 ~150k tokens","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"记忆丢失率","type":"text","marks":[{"type":"strong"}]},{"text":":从 ~30% 降低到 ~5%","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"新 session 启动时间","type":"text","marks":[{"type":"strong"}]},{"text":":从 ~10s 降低到 ~3s","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"记忆检索准确率","type":"text","marks":[{"type":"strong"}]},{"text":":从 ~60% 提升到 ~85%","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"最佳实践","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"日志写入","type":"text","marks":[{"type":"strong"}]},{"text":":记录结论而非过程","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"项目变更","type":"text","marks":[{"type":"strong"}]},{"text":":同步更新 memory/projects.md","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"遇到问题","type":"text","marks":[{"type":"strong"}]},{"text":":记录到 memory/lessons.md","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"索引变化","type":"text","marks":[{"type":"strong"}]},{"text":":更新 MEMORY.md","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"元数据必填","type":"text","marks":[{"type":"strong"}]},{"text":":每条记忆必须带 importance、channel、tags","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"关键时机写入","type":"text","marks":[{"type":"strong"}]},{"text":":不等 session 结束,立即写入","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"定期维护","type":"text","marks":[{"type":"strong"}]},{"text":":每周执行记忆衰减和归档","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"故障排查","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Session 没有自动压缩或自动切换","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检查 HEARTBEAT.md 是否包含 token 与上下文占用检查逻辑","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检查 scripts/session_compress.py 与 scripts/session_rotate.py 是否存在","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"查看 system warning 中的 token 使用量和上下文占用率","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"记忆没有自动写入","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检查 scripts/auto_memory_write.py 是否存在","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"确认 importance >= 7 或满足其他触发条件","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"查看 memory/YYYY-MM-DD.md 是否有新条目","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"新 session 没有加载记忆","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检查 AGENTS.md 是否包含启动流程","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"确认 memory/YYYY-MM-DD.md 文件存在","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"查看 MEMORY.md 是否有内容","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"记忆被错误归档","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检查 importance 是否 >= 8(永久保护)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"查看 memory/pinned.json 白名单","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"运行 ","type":"text"},{"text":"python scripts/memory_decay.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" 查看权重计算","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"贡献","type":"text"}]},{"type":"paragraph","content":[{"text":"欢迎提交 Issue 和 Pull Request!","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"许可证","type":"text"}]},{"type":"paragraph","content":[{"text":"MIT License","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"作者","type":"text"}]},{"type":"paragraph","content":[{"text":"小橘 (vulcanx_14970)","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"致谢","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mem0","type":"text","marks":[{"type":"link","attrs":{"href":"https://github.com/mem0ai/mem0","title":null}}]},{"text":" - 向量检索框架","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OpenClaw","type":"text","marks":[{"type":"link","attrs":{"href":"https://openclaw.ai","title":null}}]},{"text":" - AI Agent 框架","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","author":"@skillopedia","source":{"stars":13,"repo_name":"triple-layer-memory","origin_url":"https://github.com/0range-x/triple-layer-memory/blob/HEAD/SKILL.md","repo_owner":"0range-x","body_sha256":"65da10dfc83f2d4bb80de80537e6bac531d72f3cc424afb187ab3eb5b0f50c4a","cluster_key":"cc2952bc2562333d35d35f2840d250d08ec8d0e98c69b72b272674a4539cd947","clean_bundle":{"format":"clean-skill-bundle-v1","source":"0range-x/triple-layer-memory/SKILL.md","attachments":[{"id":"c434500f-7bd4-57d8-b760-591440098637","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c434500f-7bd4-57d8-b760-591440098637/attachment.md","path":"README.md","size":4125,"sha256":"a2220e37408115ac48c6a83444d0bc4ed063e36ae248f20d0b9a4fed7260bde4","contentType":"text/markdown; charset=utf-8"},{"id":"0a91e8bd-baaa-521a-bacf-062059707cd5","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0a91e8bd-baaa-521a-bacf-062059707cd5/attachment.md","path":"docs/github-upload-guide.md","size":3136,"sha256":"0f9a9d29f853c9b2a7e7af6c710e9587d970622e927ac31cc9cc6599c1d06dff","contentType":"text/markdown; charset=utf-8"},{"id":"1fbe0e6f-03af-5b02-8f8a-9dbdc771eebc","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/1fbe0e6f-03af-5b02-8f8a-9dbdc771eebc/attachment.md","path":"docs/mem0-channel-isolation.md","size":2295,"sha256":"79c00d44b434310971c6a0c8ccf2af4ca0f37333f7a57bab509eb2ed2f469058","contentType":"text/markdown; charset=utf-8"},{"id":"7328877b-7723-5360-94ac-902158fd81d8","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7328877b-7723-5360-94ac-902158fd81d8/attachment.json","path":"package.json","size":598,"sha256":"4cd09a768b589d91ca320ff05e9c747c94a4edf70faa5fd6bb15892341042480","contentType":"application/json; charset=utf-8"},{"id":"43652279-1c13-50de-92ff-eeb2c4b72b08","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/43652279-1c13-50de-92ff-eeb2c4b72b08/attachment.py","path":"scripts/auto_memory_write.py","size":4283,"sha256":"83469ce3638977d233e58ca01259ffc684a8b1744fa40696866fe04a24366cc7","contentType":"text/x-python; charset=utf-8"},{"id":"78ee512e-0a61-5339-9d8c-c93d84bb9bb5","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/78ee512e-0a61-5339-9d8c-c93d84bb9bb5/attachment.py","path":"scripts/channel_memory.py","size":5164,"sha256":"afb75ac4be5b36d8b11ac181745e9392b120b63187c68985117e7c0531766fa3","contentType":"text/x-python; charset=utf-8"},{"id":"b4b034eb-5e94-50b0-aa43-35935fe4ffe7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b4b034eb-5e94-50b0-aa43-35935fe4ffe7/attachment.sh","path":"scripts/init.sh","size":4086,"sha256":"6ae42f31ebc5778e74d3a45f30526454bc9c9d7f9e823f9890afd61cdcb0499d","contentType":"application/x-sh; charset=utf-8"},{"id":"7e94f4ac-0a16-5963-87be-60a66c29ab77","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7e94f4ac-0a16-5963-87be-60a66c29ab77/attachment.py","path":"scripts/memory_consistency.py","size":1953,"sha256":"062d7ba7d3b46d94af7189ada122ea8966cd98314dbb159b0226acb39538928b","contentType":"text/x-python; charset=utf-8"},{"id":"384e7c34-fa4d-54e0-988f-93e5c2451a8f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/384e7c34-fa4d-54e0-988f-93e5c2451a8f/attachment.py","path":"scripts/memory_decay.py","size":9090,"sha256":"54e1088f2bcc7f6c54265e98b7595db1f5eb6ac0bd89d5d7e34bf0380174bde8","contentType":"text/x-python; charset=utf-8"},{"id":"58408d38-a143-51da-90ef-15e444837293","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/58408d38-a143-51da-90ef-15e444837293/attachment.py","path":"scripts/memory_meta.py","size":3059,"sha256":"fce7610810e8d15041a7b799cdb59b6094c370738065abd4431979f9b75aab50","contentType":"text/x-python; charset=utf-8"},{"id":"b729d1aa-deba-5193-97a1-f76ce0f28281","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b729d1aa-deba-5193-97a1-f76ce0f28281/attachment.py","path":"scripts/quality_gate.py","size":3684,"sha256":"363ff5701119406b26f9a70520a1e9b1294cde2ec6e8ffd76872e7e8aae4d870","contentType":"text/x-python; charset=utf-8"},{"id":"6e7d8781-46ea-5cee-b6c8-725b07682fff","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6e7d8781-46ea-5cee-b6c8-725b07682fff/attachment.py","path":"scripts/session_compress.py","size":3111,"sha256":"0bfbff9d658acf39f74b209771df37eda49fa1e45f6e4bb5034047491e33b72a","contentType":"text/x-python; charset=utf-8"},{"id":"906a5246-fb23-5847-a383-1715399816af","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/906a5246-fb23-5847-a383-1715399816af/attachment.py","path":"scripts/session_handoff.py","size":5251,"sha256":"b706df75d2cc36941c348a66ad0e00a2bb22347dda8dd020b30ad462fb82be8f","contentType":"text/x-python; charset=utf-8"},{"id":"611b80a8-03bd-5ab3-a528-cd0d9eef73f5","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/611b80a8-03bd-5ab3-a528-cd0d9eef73f5/attachment.py","path":"scripts/session_rotate.py","size":3608,"sha256":"395699af5acfdac03bb97495e33f51b2f51a5892cb9223904252c7358be7efa6","contentType":"text/x-python; charset=utf-8"},{"id":"9e72d62a-9840-592d-b290-453f4fd16aa0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/9e72d62a-9840-592d-b290-453f4fd16aa0/attachment.md","path":"templates/HEARTBEAT.md","size":2091,"sha256":"928f1bb79f258944120f2f67dfee8eed7f53d7a872d2596ece2121e2f45d9b52","contentType":"text/markdown; charset=utf-8"},{"id":"b7a65b02-706c-5e29-b00c-8380e4d3f8d7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b7a65b02-706c-5e29-b00c-8380e4d3f8d7/attachment.md","path":"templates/MEMORY_ARCHITECTURE.md","size":10072,"sha256":"8e6c49d789bcd669f88e2f6d2040f2a50044226d9aa9b31e06b2810b6999a42f","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"4c9e1f8c03056b3b1eb7f5b37f99684fb1b6698cd669cff2792a83440b18d838","attachment_count":16,"text_attachments":15,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":1,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"clean-skills-v1"}},"renderedAt":1782979761102}

Triple-Layer Memory System 三层记忆系统 - 解决 AI Agent 长对话记忆丢失和上下文管理问题 概述 这是一个完整的三层记忆管理系统,包含: - Layer 1: Mem0 (向量检索)- 跨会话召回 - Layer 2: 文件层 (结构化存储)- 索引/项目/经验/日志四层 - Layer 3: Session 管理层 (智能压缩)- 自动压缩、智能加载 核心功能 1. Session 自动压缩 + 自动切换(兼容版) - token 达到 150k 或上下文占用达到 80% 时触发 - 先总结关键信息并写入记忆文件(可用时) - 再触发新会话切换提示,避免上下文爆满 - 保留最近 50k tokens 原始对话 2. 记忆写入时机优化 - 关键时机立即写入(完成任务、做出决策、变更配置) - 不等 session 结束,减少记忆丢失风险 3. 跨 Session 记忆连续性 - 新 session 启动时自动加载相关记忆 - 根据频道和任务智能检索 - 避免重复询问已知信息 4. 记忆遗忘机制 - 语义去重(相似度 0.88 拒绝写入) - 高频命中自动升权 - 低权记忆自动归档 - 关键记忆永久保护(importance = 8) 5. 频道级记忆隔离 - boss 频道:全量记忆访问 - 子频道:独立命名空间(userId::channel…