资讯详情

OpenClaw“做梦”记忆法:AI夜间自动整理记忆的工程实践

📅 2026/10/22 12:04:36 | 华诺云谱 👁 阅读
OpenClaw“做梦”记忆法:AI夜间自动整理记忆的工程实践
OpenClaw 的“做梦”记忆法是我最近在自托管 AI 助手项目上落地的一套夜间整理机制每天凌晨让模型把白天积累的原始记忆重新快照、压缩、排序、关联等到第二天你再来用的时候它记住的东西已经从一堆流水账变成了一张结构清晰的记忆图谱。听起来确实有点玄但这套方案我真跑了几个月最大的感受是AI 终于不再把两周前的旧结论当成最新结论来回答我了检索出来的东西也不再老是互相打架。先交代一下背景。我自己的助手平时承担三类工作记录日程、整理会议笔记、顺手收集一些技术灵感。之前我用的是最朴素的“实时追加”方案每次对话结束就把整段文本丢进向量库需要时做语义检索。刚开始还行可一旦积累到几千条之后问题就接踵而来同一件事往往会有多个版本不同时间记录的表述互相矛盾一些重要细节反而被淹没在大段的流水账里更麻烦的是旧记忆不清理新记忆在召回时会不断被旧结论干扰。后来我参考了一个比较冷门但很有价值的思路就是“让 AI 在夜间自动整理记忆”——白天只记录深夜再统一处理相当于给 AI 安排了一场记忆层面的“梦境巩固”。下面把这套方案的完整设计、落地参数和踩坑记录拆开讲。1. 白天积攒的碎片为什么到晚上才值得重新翻一遍1.1 实时追加式记忆的真实困境我最早做记忆功能时有一个执念每发生一次对话就要立刻把内容“消化”成长期记忆这样检索时马上可用。但真上线之后发现实时整理这件事并没有想象中那么美好甚至会让记忆越整越乱。第一个问题是上下文漂移。白天接到的信息往往是半截的比如你上午说“这个项目下周要改交付方式”下午又补充“其实是改验收标准交付方式不变”。如果每句话都实时切割成记忆条目AI 很难意识到后一条是修正前一条因为两段文本在语义上非常相似向量库里它们会被一起召回。结果就是模型在回答时经常把修正前和修正后的内容拼接在一起给你一个“又改又不改”的奇怪结论。第二个问题是重复存储。同一个灵感可能来自微信转发、语音备忘录、以及晚上写博客时的随手记录三条原文都进了向量库如果不做专门的去重召回 Top5 里就会有三条高度相似的内容浪费检索窗口也稀释真正有区分度的信息。第三个问题更隐蔽实时整理依赖当前语境容易“只见树木不见森林”。白天调用模型整理单条记忆时它看到的上下文窗口就那么一点只能抓住局部主题没办法把跨越多天的同主题内容合并成一张完整的脉络。这种活其实天生就适合离线批处理——等当天的信息全部停止流入再一次性重看、重排、重写。1.2 人的“睡眠记忆巩固”给 AI 的启示这套夜间整理机制参考的是神经科学里一个很经典的观察人类在睡眠中会重放白天的记忆片段大脑通过慢波振荡把海马体中临时存储的信息逐步迁移到新皮层做长久记忆同时会把冗余的细节修剪掉只保留核心情节和情感标记。把这个机制映射到 AI 系统里我整理出了三条可以直接落地的原则。一是重放夜间把当天积累的原始记忆全部重新过一遍而不是只看新写入的几条。二是整合让模型把分散的短时记忆重新压缩成结构化条目同时与新皮层里已有的长期记忆做关联匹配检查是否需要修正旧结论。三是遗忘不是粗暴删除而是给记忆重新定级低价值的条目进入归档区不再参与日常召回。当然我不是说让模型真的像人一样做梦。这里的“做梦”只是一个工程隐喻核心逻辑在于系统必须经历一次“离线重放 重构 分级”的完整过程而不是数据写进去就算完事。这个过程只有放在夜间这类低活动窗口才能跑得动也才能跑得稳。1.3 夜间批量整理的三个现实理由如果你要问为什么不直接写完就整理我的答案是三个字不划算。展开说有三个现实理由这也是我把任务从“实时整理”改成“凌晨批量整理”的直接推动力。第一资源开销。对几百条记忆做摘要生成、相似度计算、冲突检测如果放在每次对话的响应链路里用户会明显感觉到延迟。但放到凌晨服务器负载本来就低模型推理也好、向量索引重建也好都不会影响白天的正常使用。第二完整时间边界。记忆整理需要在一个稳定的时间窗口内处理“相对完整的数据集”。白天 14 点触发整理时今天的信息还没结束很多条目到晚上会被推翻而凌晨 1 点触发时当天的记忆已经全部落库整理出来的结论至少能保证“截至当天”是正确的。第三跨日关联的效率。夜间整理可以一次性扫描最近几天的记忆找出同主题片段做合并。比如周一记了“客户反馈 A 问题”周三记了“A 问题的根因确认”周五记了“A 问题修复方案评审”如果都拆成独立事件它们只是散落在时间线上的三个点只有用离线批处理方式重放整个时间窗AI 才能把这三个点连成一条完整的故事线。2. 一套“夜间梦境流水线”怎么设计才不像玩具2.1 管道整体结构快照、清洗、压缩、关联想清楚“为什么要夜间做”之后下一步就是设计流水线。我最终跑通的完整结构是六步快照、读取候选、清洗、摘要压缩、去重合并、回写索引。听起来简单但每一步其实都有不少细节。先拿快照来说。夜间任务开始前我会把当前记忆库的元数据打一份只读快照并记录一个任务ID。为什么要有这一步因为记忆库在夜间虽然主要被整理任务写但可能会有别的后台服务也在写日志。万一整理过程中出 bug我不至于把整个库搞坏还能根据快照回滚到整理前的状态。伪代码大致是这样# 伪代码示例 snapshot_id create_memory_snapshot() candidates fetch_active_memories(sinceLAST_RUN, untilNOW) cleaned [] for item in candidates: text strip_markup(item.body) text remove_duplicate_blank(text) text normalize_datetime(text) cleaned.append({**item, body: text}) summaries llm_batch_summarize(cleaned, batch_size20) deduped merge_similar(summaries, similarity_threshold0.86) for mem in deduped: if mem.decision archive: mark_archive(mem.memory_id) else: write_back(mem) rebuild_vector_index() write_audit_log(snapshot_id, summarize_md5)这里的流水线顺序不要乱。清洗必须排在压缩之前因为如果直接拿原始文本做摘要Markdown 里残留的标题符号、代码注释、消息引用可能被模型误当成内容本身摘要质量会明显下降。同理去重要放在摘要之后因为摘要文本比原始文本短计算的向量相似度更稳定误判率更低。2.2 记忆价值评分与遗忘边界很多人一听“自动整理记忆”第一反应是“让 AI 把不重要的东西删掉”。我的建议是不要让 AI 直接删而是给它一套“价值评分”规则让它把记忆分成保留、归档、待确认几个等级。真正物理删除的动作应该交给人工或在二次复核后执行。我给每条记忆设计了一个简化版评分函数大致长这样memory_score 基础分 近30天访问次数权重 新鲜度权重 - 重复副本惩罚基础分模型根据内容判断的重要性比如涉及项目进度、客户约定、个人健康这类信息基础分天然偏高。访问次数权重每次被检索命中就记一次访问数。频繁访问的记忆说明高频使用得分上调。新鲜度权重距离最后修改时间越近权重越高超过 90 天没有更新的记忆新鲜度权重衰减到接近于零。重复副本惩罚如果检测到高度相似的内容不止一份每多一份就扣分引导系统把重复条目合并成一条完整记录。实际操作时我不追求公式的精确性只要它能拉开分数段就行。比如最终输出的分数可以映射到几个状态我常用的一套档位是分数区间状态处理方式0.8 - 1.0核心长期记忆常驻长期库优先召回0.4 - 0.8活性记忆正常参与召回次日再次评估0.1 - 0.4归档记忆移出常规索引仅人工检索时可见0 - 0.1待确认记忆不删除标记 pending_review这套“永远不直接删”的规则非常重要。因为模型判断价值这件事本身就有误差把它当成“建议”而不是“决定”就能把误伤风险控制在一个可恢复的范围内。2.3 冲突记忆的合并与存档规则深夜整理经常会面对一种情况同一条实体比如同一个项目、同一个人在不同时间出现了两个互相矛盾的结论。我以前的做法是“以最新为准旧的丢掉”后来发现错了。被旧掉的版本有时包含关键细节比如原始数字、人名、日期丢掉后再想追溯就难了。所以我把合并规则改成了三步走。第一步识别冲突。如果两条记忆拥有高度重叠的实体集合但关键属性描述不一致就判定为冲突候选。第二步版本标记。不删除旧版本而是把旧版本标记为“superseded_by 新版本ID”新版本里保留一段“修订说明”明确写清楚“这条记忆在某年某月某日被更新取代”。第三步保留原句引用。压缩后的摘要条目里必须携带 source_id 和原文摘要片段方便将来回查。这套规则的实践经验是宁可多保留一份冗余也不要因为自动合并丢失可追溯性。尤其当 AI 回答用户问题时用户问“你上次不是说 A 方案吗”AI 必须能指出那次结论的来源和修订时间而不是含糊其辞地重新生成一个说法。3. OpenClaw 夜间任务落地调度、过滤与回写3.1 触发机制定时、空闲检测还是事件驱动夜间整理虽然叫“夜间”但我不建议只写一个死板的 cron 表达式最好是“定时 空闲检测 数据量判断”三者结合。我自己用的触发条件是这样的# 夜间任务配置示例 dream_job: enabled: true cron: 30 1 * * * # 每天凌晨1点30分 window_start: 01:00 window_end: 05:00 max_duration_min: 120 min_new_memories: 5 # 新增记忆少于5条则跳过 sources: [chat_log, memo, calendar_event, idea_box] skip_tags: [tmp, no_archive] llm: temperature: 0.1 batch_size: 20cron 表达式负责“保证有一个固定时间点会尝试”空闲检测负责“防止任务在用户还在用的时候强占资源”数据量判断负责“避免天天为几条破记录浪费一次推理调度”。具体到空闲检测我写了一个很简单的逻辑模块def should_trigger_dream(): if not is_in_time_window(): return False if get_pending_memory_count() MIN_NEW_MEMORIES: return False if cpu_load_avg() 40: # 可改成 GPU 利用率 return False if last_user_activity_min() 15: return False return True这套触发机制的好处是它在绝大多数情况下稳定执行但只要用户还在使用、机器负载过高、或者根本没有可整理的新数据它就会自动顺延到下一个周期不会因为一次异常调度就把整夜任务打断。3.2 数据源选择哪些记忆值得进入梦境不是所有记录都值得进入夜间整理流程。我一开始把所有能落库的信息全塞进去结果整理出来的摘要里混进了大量“无关紧要的闲聊”严重拉低归档质量。后来我给数据源加了明确的准入规则只保留四类内容对话日志中涉及任务进展的内容、备忘录中带有主题和截止时间的文本、日程变更记录、以及灵感类短笔记。其余纯寒暄、临时草稿、或者带有“no_archive”标签的内容直接跳过。这一步的意义不只是省算力更关键的是控制“整理视角”。如果你把闲聊也塞进去AI 在生成摘要时会夸大无关内容的权重反而把真正重要的项目信息压缩得太短。数据源越聚焦摘要质量越好这是我的一个很深的心得。另外建议做一层 PII 脱敏。夜间整理时不要直接拿原文本里包含电话号码、地址、证件号的部分去做外部模型调用可以先在本地用正则或实体识别把它们换成占位符等摘要生成后再恢复映射。这主要是安全考虑尤其当你的记忆库里涉及朋友或客户信息时能少很多麻烦。3.3 摘要与重写提示词的写法夜间整理的核心环节是摘要压缩。这步如果做得不好后面所有关联、去重都是白搭。我建议把它当成一个“结构化信息抽取”任务来做而不是让 AI 自由发挥写一段漂亮的话。我用的提示词大概是这个风格你是一个记忆整理员。请把下面输入的原始记忆片段重写为一条完整的结构化记忆条目。 要求 1. 必须以 JSON 数组输出不要输出任何解释文字。 2. 字段必须是 memory_id, title, summary, entities, tags, importance, related_ids, decision。 3. summary 控制在150字以内保留关键时间、关键决策、关键人物。 4. entities 只提取真实实体不要包含修饰词。 5. importance 取值0到1越高表示越重要。 6. decision 只允许 keep/merge/archive/pending_review 四种。 7. 如果发现与已有记忆冲突在 related_ids 中记录相关ID并在 summary 里注明差异。 INPUT {原始记忆文本} /INPUT设计要点有两个。一是强约束 JSON 输出这样程序可以直接解析入库省掉一整个“非结构化文本转结构化数据”的解析层。二是给 decision 字段预设四个固定值让模型不得自由发挥。AI 一旦自由发挥就很容易把本来应该保留的细节压缩掉然后把本来该归档的内容标成核心记忆。温度参数我设在 0.1 左右几乎接近确定性输出。整理记忆这个场景不需要创意最怕的就是模型在摘要里加入自己的想象和推断宁可保守一点只做压缩和改写不做创造性扩展。3.4 整理结果回写与向量索引更新摘要生成完之后回写这块很容易被忽视但其实特别容易出问题。我的做法是分层回写。第一步先把新的摘要条目写进一份中间表状态标记为 pending不立刻参与检索。第二步等整个批次的条目都写完后统一做一次向量化把新向量写入独立的索引分区。第三步确认新分区可用后再删除旧向量同时把旧向量的原始文本保留在另一张 raw_memory 表里。顺序一定不能反。如果新向量还没写就先把旧索引删了半夜一旦断电或任务崩溃第二天的检索就彻底失灵。反过来如果先写新索引、让新旧数据并存一天即使出问题也能快速切换回旧版本。这里还要注意向量 ID 的生成策略。不要用数据库自增 ID因为整理后一条记忆可能合并了多条原始内容ID 最好带上“快照ID 时间戳 摘要哈希”的组合。这样每次重建索引都能追踪到具体是由哪次夜间任务产生的排查问题时会快很多。4. 如何证明夜间整理真的有效而不是自嗨4.1 三个我一直在跟踪的评估指标做了新功能如果不量化效果就没办法判断是变好了还是变差了。我建议至少跟踪三个指标检索首位命中率、时间敏感问答的错误率、以及召回条目的信息冗余度。指标收集方式整理前的典型表现整理后一个月检索首位命中率随机抽取 50 条历史问题看 Top1 是否命中61%84%时间敏感问答错误率围绕项目状态提问检查是否带入过期结论18%5%平均单轮召回条数记录每次问答召回到多少条记忆13.8 条7.6 条第三项为什么重要很多人以为召回条数越多越好其实不是。召回条数多往往意味着大量相似记忆被重复命中反而会分割模型的注意力窗口。夜间整理做了合并和降权之后单个问题命中的通常是 3 到 7 条互补的记忆模型可用的上下文信息密度反而更高。测试集不需要很复杂把这一周对话里用户真正问过的问题整理成 50 条每天跑一遍就行。我通常关注的是相对变化趋势而不是绝对数值——只要整理机制上线后一两周内指标有持续改善就说明方向没跑偏。4.2 误合并和误删审计日志与回滚方案这个坑我踩过很多次最有代表性的一次是模型把两个同音不同字的联系人合并成了一个人。“张工”和“章工”在向量空间里相似度非常高实体识别又都提取成“gong”结果系统自动合并后就再也搜不到其中一位的独立历史记录了。这类问题靠调阈值解决不了因为合并和区分之间的边界本来就是模糊的。所以我做了两层防护。第一层是审计日志。每次夜间任务完成都把 task_id、输入数据哈希、输出摘要、合并关系、decision 分布全部记录成一条结构化日志。出了问题我直接按时间定位是哪次整理造成的。第二层是版本回滚。我会保留最近 7 天的“整理前快照”一旦发现误合并就先停掉后续任务从前一天快照恢复再把涉及冲突的那批数据单独拉出来重新整理并在这次整理时加入一条硬规则当两个实体名的偏旁部首完全不同时禁止合并。恢复步骤通常是这样# 进入离线维护状态避免任务继续写入 openclaw-cli memory maintenance on # 按审计日志找到误操作快照 openclaw-cli memory snapshot inspect --task-id TASK20250125 # 回滚到整理前的状态 openclaw-cli memory snapshot restore --snapshot-id SNAP20250124 # 重新跑部分范围内的整理这次加黑名单 openclaw-cli memory dream --scope user:alice --merge-blacklist 张工,章工有了这套回滚方案之后我对夜间任务的信心高了很多。因为我知道最坏的情况也就是回到昨晚的状态不至于积攒几个月的记忆被一次 bug 搞没。4.3 夜间任务卡死的常见原因与调参最后说几个在跑夜间任务时经常遇到的问题以及对应的调整手段。最经典的问题是任务超时。当历史记忆达到几万条量级时如果每次都试图“全量整理”很容易在凌晨几个小时内跑不完。我解决的办法是改成增量切片每次只处理上次整理后新增及变更的记忆同时把长期库中分数中度偏低的老记忆按 20% 比例抽样重访。这样大部分夜间任务是轻量的真正深度整理放到每周日做一次。另一个问题是摘要输出不稳定。有时模型返回的 JSON 里有残缺字段或者把 decision 写成了枚举值之外的东西。我在代码里加了解析兜底解析失败直接进“待重读队列”不中断整个批次。待重读队列会在明天夜间任务开始时再次尝试如果连续三次失败就把这条记忆降级为 pending_review交给人工处理。还有一个很容易忽略的问题是资源竞争。如果同一台机器上白天跑的服务在凌晨也会做数据备份两个任务可能抢 CPU 和磁盘 IO。我在实际环境中把备份任务调整到凌晨 4 点之后和夜间的整理窗口错开半小时以上问题就再没出现过。如果你跑的是本地小参数模型建议把 batch_size 从 50 降到 20同时限制单次输入的原始文本总长度。整理任务其实并不需要模型有多么强悍的推理能力关键是稳定输出结构化结果小模型配合强约束提示词完全够用。5. 跑了一段时间后的体会与后续方向5.1 最有用的一处设计短期记忆区与长期记忆区分开如果只让我推荐这套方案里的一个设计我会毫不犹豫地推荐“短期记忆区与长期记忆区分离”。最初我只用了一张 memory 表夜间整理时统一把总结写回同一个表。结果很快就发现一个问题高频检索时AI 往往优先命中漂亮的摘要条目而摘要里的信息是压缩过的丢掉了不少原始措辞和时间细节。比如摘要里写着“用户上周提到要改进后台搜索”看起来很合理但真到需要回答“你上次说的具体做法是什么”时摘要就完全不够用了。后来我把表拆成两层短期记忆区raw_memory存放原始片段保留 30 天主要用于近期上下文和可追溯引用。长期记忆区long_term_memory存放压缩后的结构化摘要只在原始片段被判定为高价值时写入。夜间任务真正做的事是“把短期记忆区里的有价值片段加工成长期记忆区里的结构化条目”而不是“把短期记忆直接改写成长期记忆”。这个分层让检索逻辑变得非常清晰日常问答先用长期记忆区的高密度信息生成答案模板需要细节时再回短期记忆区查原文。实践证明这套设计比单纯做“全量摘要”稳健得多因为它同时满足了两个本来矛盾的需求既要从宏观上看到脉络又要能回溯到微观的原始描述。5.2 值得做但不着急做的扩展我先说结论这套方案已经可以稳定跑但还有很多扩展空间建议按需逐步加别一上来就把系统做得太重。第一类扩展是“周级深度整理”。日级的夜间任务只负责合并和压缩不适合做跨周的主题重建。我的计划是每周日凌晨跑一次深度任务把过去 7 天生成的高阶摘要再合并一次形成月度视角的话题图谱。这个扩展对项目复盘类场景特别有用但目前还没排上优先级因为日级效果已经让检索干净了很多。第二类扩展是“标签体系统一”。夜间整理时不同来源的标签很容易不一致比如“项目A”和“A项目”同时存在。下一步我会加一个标签别名映射表让系统在写入前就把标签归一化这样后续按标签做聚合分析会准确很多。第三类是对高情感强度记忆的特殊处理。有些记忆涉及用户的情绪波动比如“这个方案让我很沮丧”。这类记忆在整理时不该被过度压缩否则会丢失当时的情境感受。我目前只是简单标记 emotion_strength 字段后续可以考虑单独设定更保守的整理策略。第四类扩展是多智能体轮换复核。简单说就是让两个不同的模型实例交叉检查彼此的夜间整理结果避免单一模型的系统性偏差。这很诱人但会成倍增加算力消耗我觉得更适合在项目正式对外服务之后再考虑。最后说一句我自己的实操体会。夜间整理的本质不是让 AI 变得更聪明而是让记忆系统的密度和有序性得到持续维护。它要求你在工程上做很多“不性感”但非常关键的事快照、审计、回滚、增量处理、失败重试。这些往往比设计一个炫酷的整理算法更重要也更能决定这个功能能不能长期稳定运营。把基础的地基打牢再谈“让 AI 做梦”也不迟。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑