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

你一定有过这种时刻:上周你明确告诉 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 参考 与插件目录指南。