记忆是有额度的:为什么它后来什么都不记了


你一定有过这种时刻:上周你明确告诉 Hermes“这个项目的部署流程是 X”,这周它又问了一遍。你翻它的记忆文件,发现里面塞满了三个月前的临时决定、已经被推翻的旧结论、以及几条内容几乎一样的重复条目。你想让它“记住这件事”,它每次都答应——然后什么都没存。

内存写满这件事最阴险的地方在于它不报错。Hermes 的记忆有字符上限,额度用完时新的写入会被静默跳过。等你发现的时候,已经错过了多少该记的东西,谁也说不清。社区插件 hermes-dreaming(2026-10-04 进入官方插件目录)就是冲着这个问题来的:每天夜里做一次确定性的记忆整理。

思路:夜里先做机器能做的,只在必要时叫醒模型

这个插件最值得学的一点是它的分工。整条夜间流程里,脚本一次都不调用 LLM:

  • 一个纯标准库的 Python 脚本读取你已有的记忆(MEMORY.md / USER.md)和最近的真实对话;
  • 筛选、评分、比对、隔离,全部离线完成;
  • 只有当确实存在需要“你”决定的事情时,它才唤醒 agent,让 agent 通过常规的 memory 工具去落地那几条改动。

也就是说,大部分夜晚它是免费的:什么都不用算,什么都不用改。

它怎么判断“这条值得记”

证据来自真人,而且跨天。 一个事实只有被人在不同日期提到过才算数。定时任务的提示词、上下文压缩横幅、URL、不受信任的聊天内容、以及 agent 自己的输出,都不能作为佐证。这条规则直接掐掉了“agent 自说自话记了一堆幻觉”的路径。

评分沿用 OpenClaw 的权重:相关性、频率、多样性、新鲜度、整合度、丰富度,再加一道“是否需要佐证”的闸门。

和现有记忆逐条比对:精确匹配、显式别名规则、以及三个方向的词干包含匹配。这里有个很聪明的区分——如果候选事实和已有条目说的是同一件事、但数字不一样,它不会被当成“重复”丢掉,而是标成 conflicts(可能的更新),并且带上最近的条目、所在文件、以及一个逐字锚点,供 replace 使用。

先筛一遍再给你看:密钥和提示注入会被隔离;带日期的临时事件会过期(支持俄语 / 英语 / 泰语日期写法);语义上高度接近的条目只出现一次。

两道保险:唤醒闸门与丢失护栏

  • 唤醒闸门:安静的夜晚它直接输出一个“不用唤醒 agent”的信号,模型根本不会启动。特别的是,记忆文件接近字符上限本身就算“有事要做”——因为上限会静默拦截写入,不主动检查就永远没人发现。
  • 丢失护栏:如果一夜之间记忆里有相当比例的条目消失了,下一次报告会明确指出来。

另外它会在 memories/DREAMS.md 里留一本“梦境日记”,记录每条候选的来源,方便你回溯。

安装

要求 Hermes ≥ 0.21、Python ≥ 3.9,纯标准库。

# 1. 装插件并启用
hermes plugins install itpartypattaya/hermes-dreaming
hermes plugins enable hermes-dreaming

第二步是安装脚本。这一步不能省,原因是 Hermes 只从 ~/.hermes/scripts/ 目录运行 cron 脚本(符号链接会被拒绝),所以安装器要把两个前置闸门脚本复制过去:

python3 ~/.hermes/plugins/hermes-dreaming/skills/dreaming/scripts/install.py

安装器会复制两个闸门脚本、从示例生成 ~/.hermes/dreaming.json、在状态文件的临时副本上做一次空跑,并检查事实来源和内核版本。它是幂等的,也可以用 install.py --check 只做校验不改动——每次升级后都跑一次,因为 scripts/ 里的副本可能和技能里的版本不一致。

第三步是编辑配置,这部分没人能替你做:

$EDITOR ~/.hermes/dreaming.json

要填的是时区、trusted_chat_ids、agent_names、fact_source。注意 trusted_chat_ids 是 fail-closed 的:在你把群聊列进去之前,没有任何群聊能作为记忆佐证,插件会保持什么都不做。如果某个受信任的群是论坛结构,把那些“不是人在说话”的线程(agent 自己的告警、助手桥接、机器生成卡片)写进 excluded_threads。

最后是定时任务。创建任务走的是 Hermes 的 Python API(CLI 没有 enabled_toolsets 参数,而 cron/jobs.json 是调度器的实时状态,不适合手改),装之前先干跑看一眼计划:

~/.hermes/hermes-agent/venv/bin/python \
    ~/.hermes/plugins/hermes-dreaming/skills/dreaming/scripts/install_cron.py --deliver local --dry-run

计划没问题就去掉 --dry-run 再跑一次。任务会绑定插件自带技能的限定名,所以插件必须先启用;已有任务会被跳过,如果某个任务加载的是别的技能,脚本会报出来,用 --rebind 把它指回来。

每条候选都有归宿

这套流程最不像“AI 小玩具”的地方,是它不会没完没了地问你同一件事:

  • 一条候选要么被写入记忆,要么进入拒绝名单(你回一句“过时了”就永久关闭,按文本匹配);
  • 新事实、冲突、衰退问题最多每 14 天出现一次;
  • 一条记忆经过“还重要吗”的确认后(保留,或带新日期原地重写)会进入 90 天的静默期;
  • 冷却期只在 agent 真的回答过之后才开始——某个夜晚跑了一半失败,第二天会原样重来;
  • 每晚最多落地 6 条改动,而且 replace 必须用脚本给的逐字锚点。

注意

  • 它不是记忆提供者,不注册任何 provider:它只审阅内置记忆和全息存储(holographic store)里已有的内容,和现有的记忆插件是互补关系;
  • 事实来源可以是全息存储、SQLite / JSONL 导出,也可以是“无”;
  • 整个包不改动 Hermes 内核,装的即目录里评审过的代码。

想看记忆的其余部分怎么运作,可以读记忆提供者目录迁移和定时任务的记忆连续性;命令层面见 hermes memory 参考 与插件目录指南。