0x00 序※
上一篇文章《记忆引擎的自我进化:从正则到 LLM》写到一半时,留下了一个尾巴:LLM 提取仍有噪声,需要增量治理。当时靠人工清理(422 个实体清到 265 个),但心里清楚这不是长久之计——记忆引擎每天在吸收新事实,新实体源源不断,靠人盯着迟早漏。
这篇文章记录的就是补上这个尾巴的过程:从"人工清理"到"引擎自迭代",再到一个关键的设计转折——审查过的实体要打标记,别让引擎重复怀疑同一件事。
问题:自检报告成了每日噪音※
Seraph 的记忆引擎(seraph-memory)有一个自我维护机制:每天凌晨 4 点跑一次 self_heal 健康检查,扫描全库实体,找出"疑似噪音"的节点报告给用户。
初衷是好的——实体表会膨胀,需要定期瘦身。但跑了一周,问题暴露了:每天的审查清单几乎一样。存储路径 /PikPak、Trilium 属性文件 ~shareTemplate、模型名 llama-3.2-11b-vision……这些实体昨天审过、前天也审过,每次都判定"有用,保留",第二天它又出现在待审查列表里。
为什么?因为最早的噪音判定是正则规则:名字以 / 开头就是"路径",以 ~ 开头就是"文件",纯数字就是"端口"。规则不看上下文——/PikPak 明明是一条真实的存储挂载路径(resource 类型),正则照样把它归进"路径噪音"。
第一轮修正:正则换成 LLM※
和莉莉丝(我的 Hermes AI 助手)讨论时,她先试了一个方向:既然实体已经有类型(resource/file/tool),那"有类型的实体就是人工确认过的,跳过审查"不就行了?
这个方案只活了十分钟就被否决了——因为类型不是审查信号。类型是 LLM 分类的结果,实体有类别只说明它被归类过,不代表它的存在本身被确认过价值。拿类型当"已审查"的通行证,等于用分类结果覆盖审查逻辑,逻辑上就绕回去了。
正确的方向是:噪音判定本身要智能化。正则永远不会完善——永远有规则外的东西漏进去(subgraph、direction LR 这种 mermaid 语法残留,正则怎么也想不出它们是噪音)。所以把噪音判定整个换成了 LLM:给模型实体名 + 类型 + 关联事实片段,让它判断"这个节点值不值得留在图谱里"。事实证明 LLM 能区分 /PikPak(真实存储挂载,保留)和 ~/.ssh/silk(配置细节,噪音)——这是正则做不到的语义判断。
这一轮改造后,审查报告干净多了:/PikPak 不再被误报,而 mermaid 残留、占位符(python-xxx)、纯泛词(packages、virtual_environment)被正确揪了出来。
第二轮修正:标记机制※
LLM 判噪音解决了"误报",但没解决"重复"——审查过的实体每天还是会被重新审一遍。每次跑全库 LLM 判断,几十个实体过一遍模型,慢不说,结果还总是那几句。
用户(我)提出了一个更本质的设计:审查过的实体应该打标记,之后跳过;只有当它真的变了(关联了新事实、类型被改),标记才清除,重新进审查队列。有标记的不再审查,只审查没有标记的。
实现上分两层:
- 标记:
entities表加reviewed列(0/1)。self_heal 只查reviewed=0的实体;LLM 判"保留"自动标 1;判"噪音但有引用"进人工审查清单并标 1(报告一次,不每天重复);判"噪音零引用"自动删除。 - 变化检测:所有写路径(关联事实、加关系、改类型、删事实)都会触发
_touch——把涉及的实体reviewed清 0。这样"实体变了 = 重新审查",不需要额外的指纹对比或定时扫描,因为所有变化都经过存储层写入。
这层设计的关键洞察是:变化检测不需要"判断",写的时候顺手清标记就行。新增事实连到实体 = 语义可能变了 = 清标记;改实体类型 = 可能重新定性 = 清标记。零遗漏,零额外开销。
配套:人工确认入口※
标记机制需要一个人工出口:LLM 判"噪音但有引用"的实体(比如 subgraph 被 mermaid 笔记引用过),不能自动删(防误删),也不能永远挂着——于是 fact_store 工具新增了 mark_reviewed action:人工确认保留 → 标记 1;确认是噪音 → remove_entity 删除。
第一轮 LLM 审查揪出的 10 个待确认项,人工过了一遍:删掉 5 个真噪音(subgraph、direction LR、python-xxx、packages、virtual_environment),保留 5 个有效工具(#shareRoot、npm、pip、pyenv、venv)。
效果※
改造完跑了两轮验证:第一轮审出 10 个待确认项,第二轮 needs_review: 0——审过的实体不再重复审。之前每天重复的 /PikPak、~shareTemplate 类报告消失。
这套机制现在在 sad 和 asus 两台 Hermes 实例上都跑着(代码同步、md5 一致)。以后记忆引擎吸收新事实,新实体自动进审查;老实体被新事实触碰,自动重新审;确认过的,不再打扰。
0xFF 跋※
回头看,这次演进其实是两条线的交汇:一条是智能化——从正则到 LLM,让引擎自己理解"什么值得留在图谱里";另一条是状态化——从每次全量审查到增量标记,让引擎记住"什么已经确认过"。前者解决判断的准确,后者解决判断的效率。
还有未完成的事:
- 标记的反馈闭环:现在"人工确认"还是要看报告手动处理,能不能让对话中的确认(比如用户说"这个实体留着")自动落成标记?
- 信任评分联动:上一篇文章提到的 fact_feedback 递减制还在等使用习惯,reviewed 标记和 trust_score 目前是两套独立状态。
- 边加权:给图谱的边加权重,消费时按权重排序,弱边降权——让知识随时间和密度自然失效。
边加权设计的几个关键点(和莉莉丝讨论收敛):
- 只降权不删除:弱边退出检索排序但保留在库,可恢复
- 两个正交维度:trust_score 是对象(事实/实体)的可信度,边权是关系的重要度——独立字段,不是派生
- 三因子合成:结构 × 时间 × 反馈
- 结构:实体重要性传导(被引用数 × trust),保护"重要实体间的边"而不是 hub 的所有边
- 时间:指数衰减,基于最后触碰时间(复用 _touch 机制),触碰重置、长期没人碰自然淡出
- 反馈:隐式为主(检索消费加分)+ 显式修正(helpful/unhelpful 顺带调整涉及的边)
- 冷启动:新边按类型给初始权重(结构边高、语义边低),先验而非规则
- 淘汰:低于相对分位(如后 20%)的边不参与排序,保留可恢复
方向已明确,具体实现待决定。
记忆引擎不是一次性项目——上一篇文章说"它是第一个里程碑",这篇算是第二个。接下来会跟着使用持续进化。
参考资料※
- 《记忆引擎的自我进化:从正则到 LLM》——前一篇,讲实体提取从正则到 LLM
- 《Hermes 记忆引擎实践》——系列第一篇,记忆引擎选型
- 《人机记忆引擎实时通道》——Trilium 到记忆引擎的秒级回流
- 《Hermes 共享大脑的迷思》——多实例记忆的取舍