忘事终结者 · 记忆保鲜柜
> 一句话定位:我做的不是检索,是记忆工程——判断什么值得记、什么时候该忘、怎么压缩不失真。
> 版本:v2(已落地 本地 MiniLM 嵌入 + 知识图谱 + MCP 暴露)。v0=四工具基础引擎,v1=reflect 自动巩固 + 跨会话 prefetch。
为什么需要
LLM 本身无状态,每次对话从零开始,业界叫「金鱼问题」。跨会话靠摘要硬撑会「上下文崩溃」。本技能补上现有 wise-forgetting 缺的主动层:跨会话的提炼 / 冲突 / 衰减。
理论支柱(四本书提取)
四本书 设计规则 四工具/公式 的完整映射:
- 《认知天性》 检索巩固、间隔、合意困难、细化、巩固/再巩固
- 《记忆的七宗罪》 何时该忘(transience)+ 防失真(misattribution/suggestibility/bias)
- 《为什么学生不喜欢上学》 工作记忆有限 必须 offload 到长期记忆
- 《卡片笔记写作法》 原子化、双向链接、元认知盒子
四工具(对齐 MemForge,LOCOMO #1)
| 工具 | 职责 | 科学来源 |
|---|---|---|
| remember | 摄取 + 取舍(rubric)+ 原子化存储 + 置 dirty 标记 | 卡片笔记原子化;七宗罪·心不在焉(取舍) |
| recall | 召回 + 打包成「编译后上下文」 + 再巩固 | 认知天性·检索巩固(再巩固) |
| reflect | 巩固 / 提炼(近重复索引) / 冲突检测 + 自动触发 | 认知天性·细化+巩固;卡片笔记·链接;四层模型长文(防摘要崩溃) |
| forget | 衰减 / 遗忘(降权非删除) | 认知天性·间隔+合意困难;七宗罪·transience/persistence |
| prefetch(v1) | 跨会话开局自动打包上下文(常驻+近期+相关) | 七宗罪·transience(忘了就重说主动 prefetch);认知天性·检索巩固 |
召回打分
score = sim·0.40 + recency·0.30 + importance·0.20 + freq·0.10
recency = 0.5^(days / 30)
命中后 importance += 0.05 # 再巩固:检索强化记忆
衰减(forget)
effective = base · 0.97^(days_since_last_recall)
if emotional_weight >= 0.7: floor 0.6 # 高情感价值不遗忘(七宗罪·persistence)
归档: effective < 0.12 且 days > 60 且 非高情感
防失真三条铁律(来自《记忆的七宗罪》)
- 每条记忆必记 source(出处)。
- 合并冲突保留双方 + 时间戳,绝不单方面覆盖。
- 不凭空补全,存原文 not 改写后。
使用
# 自测(模拟昨天/今天两会话)
python memory_vault.py
# 作为模块
from memory_vault import remember, recall, reflect, reflect_auto, forget, prefetch, prefetch_session
reflect 自动巩固(v1 新增)
reflect() 做三件事,且可自动触发(不用每次手动跑):
1. 冲突检测:相同内容不同 source 标低置信 + 时间窗标 superseded_by(旧的指向新的,但保留不删,防失真铁律②)。
2. tag 互链:同 tag 记忆双向链接,提高提取效率(卡片笔记)。
3. 提炼/合并:近逐字重复(bigram sim >= 0.62 且共享 tag/同层) 提炼成 [巩固] 索引,原文转 consolidated 状态但仍可经 links 回溯。不截断、不丢原文(四层模型长文警告:迭代摘要会"上下文崩溃")。
自动触发:remember 累计新增达 REFLECT_DIRTY_THRESHOLD=5 条,或距上次 reflect 超 REFLECT_COOLDOWN_DAYS=1 天 reflect_auto() 才执行;否则跳过(冷却)。会话结束/定时调用 reflect_auto() 即可,无需人工。
> 边界:v1 仅合并字面近重复;同义不同表述(paraphrase)字面重合低,保守不并,留给 v2 嵌入检索。
跨会话 prefetch(v1 新增 · 解决"昨天聊的今天要重说")
新会话开局调用 prefetch(session_intent),自动把相关记忆打包成可注入上下文块:
- 常驻事实:base_importance >= 0.85(用户偏好/硬约束,永远带)。
- 本会话相关:按 session_intent 语义召回(sim+时效+重要+频次)。
- 近期在聊:按 last_recalled/created_at 时效召回(即使没说意图也能接上话)。
- 合并去重 token 预算裁剪(默认 2000 字) 标记召回即再巩固。
- 会话刚开尚未有意图:prefetch_session() 退化为仅"常驻+近期"。
返回的 block 直接贴在系统提示/会话开头,格式示例:
## 记忆保鲜柜 · 跨会话上下文(自动 prefetch)
> 打包时间:...;每条附 source 与 confidence;召回即再巩固。
### 常驻事实(高重要,随时在)
- 【user_stated · conf 0.95】示例用户是某城市女性,某科技公司产品经理(示例占位,请按需替换)
### 本会话相关(按意图召回)
- 【derived · conf 0.85】忘事终结者采用四层记忆模型...
### 近期在聊(按时效召回)
- 【derived · conf 0.8】记忆保鲜柜用 JSONL 文件存储...
接线示例(自动跑进 Agent 工作流)
不想每次手动想"该不该记"?把下面三个调用点嵌进 Agent 主循环,记忆就在后台跑起来。完整可运行示例见 wiring_example.py(python wiring_example.py 跑端到端演示;演示用独立临时 vault,不污染真实记忆)。
会话开局 session_start(intent) # 1. 自动 prefetch,把 block 注入系统提示
每次用户发言 capture_user_turn(text) # 2a. 正则启发式版(demo 用)
capture_user_turn_llm(text, llm_fn) # 2b. 生产版:LLM 读 rubric 判记不记
会话结束 session_end() # 3. reflect_auto 巩固 + forget 巡检
# 接线骨架(真实部署)
from wiring_example import session_start, capture_user_turn, session_end
import memory_vault as mv
# ① 开局:把记忆注入上下文(sys_prompt 是你要喂给 LLM 的系统提示)
r = session_start("继续忘事终结者 v2")
sys_prompt += "\n\n" + r["block"]
# ② 每轮:用户说什么,先过一遍 capture
# 生产版(推荐):LLM 读 rubric 判断记不记 —— 见 llm_capture.py
from llm_capture import capture_with_llm, mock_llm, openai_llm
capture_with_llm(user_text, your_llm_fn) # your_llm_fn = openai_llm / 你 agent 的 completion
# ③ 收尾:巩固 + 巡检
session_end()
重要边界(诚实声明):wiring_example.py 里的 classify() 只是正则启发式,用来让 demo 不依赖 LLM 也能跑。生产版「LLM 读 取舍rubric.md 判断记不记」已经写好:llm_capture.py 的 capture_with_llm(turn, llm_fn)。
llm_fn是注入函数,契约llm_fn(prompt) -> str,不硬编码任何 key/API,memory_vault仍零依赖。- 离线可跑:内置
mock_llm模拟 LLM 的 JSON 输出(python llm_capture.py直接演示整条链路)。 - 真实部署:把
mock_llm换成openai_llm(文件底部片段,填OPENAI_API_KEY)或你 agent 自己的 completion 调用即可。 - 决策逻辑与 rubric 完全一致,只是判断者从正则换成 LLM,三个调用点(start / capture / end)不变。
> vault 路径可用环境变量 WANGSHI_VAULT_DIR 覆盖(见 memory_vault.py),方便测试/多工作区隔离,不影响默认 memory_vault/ 行为。
四层落点(你机器上,零新依赖)
- 工作:
memory_vault/working.jsonl+ 当前 ctx - 情景:工作区
YYYY-MM-DD.md日志 +conversation_search - 语义:
~/.workbuddy/MEMORY.md - 程序:
SKILL.md/ 行为模板
路线
- v0(已发布):SKILL.md +
memory_vault.py(零依赖 JSONL) + 取舍 rubric,接现有 MEMORY.md。 - v1(已发布):reflect 自动巩固(提炼/冲突时间窗)+ 跨会话 prefetch(开局自动打包上下文)。 实跑自测通过。
- v2(当前):本地 MiniLM 嵌入(paraphrase 级去重)+ 知识图谱边/多跳 + MCP 暴露。 已落地。详见下文。
v2 新增能力
1. 本地 MiniLM 嵌入(paraphrase 级去重)
embed.py:可插拔后端,优先级fastembed(无 torch,轻量)>sentence_transformers> 零依赖 trigram-cosine 回退。- 模型
sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2(支持中文)。 - 开启:在 venv 执行
pip install fastembed,联网首次调用自动下载模型(约 110MB)。未开启时优雅降级为 trigram,v2 行为与 v1 完全一致,绝不硬失败。 - 开启后:recall/prefetch 用余弦相似度;reflect 合并阈值从字面
0.62升到语义0.80同义不同表述也能合并(v1 遗留的真缺口补上)。 - 嵌入向量带进程内缓存,避免重复计算。
2. 知识图谱(边 + 多跳)
- 边来源:显式
links+ 同 tag 共现 + 同源;reflect 落图到vault_meta.json["graph"]。 graph_related(start_id, hops=2):多跳 BFS,返回{邻居id: 跳数}。- prefetch 经图扩展:选中的 1 跳邻居作为「图谱关联」补进上下文(预算内),接上话更完整。
3. MCP 暴露(给其他 Agent 调用)
mcp_server.py:用官方mcpSDK(FastMCP,锁mcp<2)暴露 6 个工具:
remember/recall/reflect/forget/prefetch/graph_related。- 运行:
python mcp_server.py(stdio 传输,宿主以子进程拉起)。 - 注册:把下片段并入
~/.workbuddy/mcp.json的mcpServers,并在 WorkBuddy 连接器页 Trust 该服务器:
{
"mcpServers": {
"忘事终结者": {
"command": "<你的 python 解释器路径>",
"args": ["<技能目录>/mcp_server.py"]
}
}
}
- 依赖(在 venv 装):
pip install "mcp[cli]<2"与可选pip install fastembed。
使用
# 自测(模拟昨天/今天两会话,含图谱遍历)
python memory_vault.py
# 作为模块
from memory_vault import remember, recall, reflect, reflect_auto, forget, prefetch, prefetch_session, graph_related
from embed import backend # 查看当前嵌入后端
版权与署名
本技能为原创方法论落地实现,可免费使用与二次分享。
方法论溯源(仅方法名与理论框架,未包含任何书籍原文摘录):
- 记忆架构参考 Mem0(mem0ai/mem0)、MemForge(MemForgeAI/memforge,LOCOMO 基准第 1)、Letta / MemGPT(letta-ai/letta)的公开设计;
- 记忆科学原理取自《认知天性》《记忆的七宗罪》《为什么学生不喜欢上学》《卡片笔记写作法》四本公开著作的方法论述,未摘录原文;
- 四层记忆模型(工作 / 情景 / 语义 / 程序)为认知科学通识框架。
使用许可:CC BY 4.0(署名 + 非商业性使用)。
作者与联系方式
本 skill 由「七仔的AI工具箱」维护。欢迎就技能使用、问题反馈与二次分享交流:
- 微信公众号:七仔的AI工具箱
- 抖音号:七仔的AI工具箱
- CSDN 博客:七仔的AI工具箱
本 skill 可免费使用与二次分享;转载请注明出处「七仔的AI工具箱」。