Harness 工程 · 记忆机制
学习舱 / Harness 工程 / 记忆机制

记忆机制:auto memory、三级记忆与持久化

整理中 深度 · 应用 更新 2026-09-22

前置 Harness 概览、上下文压缩、记忆/CLAUDE.md

记忆机制:auto memory、三级记忆与持久化

一句话定位:记忆机制是 Harness 部件 ③状态 的「记性」半边——上下文是工作台、记忆是仓库,这套机制决定什么值得写进仓库、写在哪一层、什么时候取回来。前置:什么是 Harness、上下文压缩(压缩后的工作记忆是会话内的「临时仓库」)、记忆的产品行为(记忆文件怎么建、放哪级目录,产品篇已讲,本篇讲机制)。

先从一次「失忆重逢」说起

你跟 Agent 说「我们项目的接口都用 /api/v2 前缀」,它这一轮记得牢牢的,后面所有代码都乖乖带上前缀。

三天后新开会话,它把接口路径写回 /api/v1——会话断了,说过的话就没了。你把这条约定写进项目的记忆文件,下个会话果然生效;可换个项目,你自己的偏好(比如注释风格)又得重说一遍。而当你攒了几百条记忆之后,新问题又来了:每次注入的记忆太多,上下文被塞满,它反而变笨了。

Agent 的「记性」到底存在哪、什么时候写、什么时候取?为什么有的记忆跟项目走、有的跟人走、有的谁都不该看见?

答案是:记忆不是一块存储,而是一套分级的体系——会话内靠上下文、跨会话靠文件、海量了靠检索库;写入有触发判断、加载有位置讲究、隔离有键位设计。三级的读写路径各不相同,正因如此才各有各的失效模式。

记忆三级:按「离当下多远」分层 第 1 层 · 会话内(工作记忆) 上下文里的近期对话与刚干过的活 写:每轮自动 · 取:直接在场 · 失:会话结束(压缩后剩摘要) 第 2 层 · 跨会话文件 项目约定、个人偏好——人可读、可手改、可入库管版本 写:值得记时用工具落盘 · 取:会话启动载索引,相关才注入 第 3 层 · 检索库 海量历史记忆——向量库 / 图数据库,机器检索高效 写:批量入库 · 取:语义查询 + 排序筛选 隔离边界 跟项目的: 锁在项目内 跟人的: 跨项目随人走 多租户的: 键位隔离永不串 隔离靠键位设计, 详见动手段 越往下存得越多、找得越慢、丢得越难——记忆体系就是把「值得长期留的」逐层下沉

图:记忆三级与隔离边界——「第 1 层」到「第 3 层」是本篇编号,右侧是每层该守的隔离线

渐进拆解

你自己的记性就是三级体系——脑子里正想着的(第 1 层,转眼就忘)、便签和笔记本(第 2 层,写下来才靠得住)、图书馆(第 3 层,海量的书按主题检索取回)。没有人把所有事都写进笔记本(太累、翻不过来),也没有人靠「努力回忆」记住图书馆里每本书——分级不是偷懒,是让每一层干自己擅长的事。

跟着一条记忆走完它的一生,写入、注入、退休三段各有机关:

一条记忆的一生:写入 → 注入 → 退休 对话中出现 「接口都用 /api/v2」 判断:值得记吗 重复出现 / 纠正 / 事实 写入第 2 层 用写文件工具落盘 带来源标注 谁说的 · 何时 新会话启动 载入记忆清单(不载全文) 相关时注入 以带标记的提醒进消息流 退休:约定变更时覆盖旧条目、长期不相关时清理——不退休的记忆堆会变成没人信的杂物间

图:一条记忆的一生——上行是写入链(判断、落盘、带来源),下行是注入链(载清单、相关才注入),末尾是退休

大白话:记忆机制就是三道判断题:什么时候写——重复出现的偏好、用户纠正过的事、确定的事实才值得写;写到哪——跟项目的进项目记忆,跟人的进全局记忆,量大的进检索库;怎么读——先读清单不读全文,相关才注入,注入时标明「这是记忆」。

auto memory(自动记忆)

不等你开口,Agent 自己判断「这值得记」并写入第 2 层文件,实现上有两个常被问到的机关(均为社区逆向口径)。

  • 写入走的就是普通工具机制:记忆文件不是什么特殊存储,就是 Harness 用写文件工具落盘的普通文件,所以人能直接打开看、直接改、能进版本库,透明是它最大的优点。
  • 注入走 system-reminder 而不是直接改系统提示词:系统提示词是「角色设定」,整场会话稳定不变(前缀稳定,提示词缓存才可复用);记忆是「会变的数据」,以带标记的提醒形式插进消息流——既让模型分得清「这是记忆不是当前对话」,又不扰动系统提示词。

这套「你写约定文件 + 它记主题文件 + 压缩兜底」的产品行为,记忆产品篇有完整展开。

三级体系与作用域

  • 第 1 层 · 会话内上下文(含压缩后重建的工作记忆):读写零成本,但随会话蒸发。本篇的「工作记忆」取宽义,指会话内在场的全部内容;压缩篇特指重写后重建的工作集,是它的子集。
  • 第 2 层 · 跨会话文件:作用域决定隔离——跟项目的锁在项目里,跟人的跨项目随人走。除了约定与偏好,项目的目录结构说明、历史修复的教训也属此层。
  • 第 3 层 · 检索库:容量近乎无限,但每次取用都要付检索与注入的预算。

作用域错配是记忆事故的第一大来源:个人偏好写进项目记忆,换个项目就「失忆」;项目约定写进全局记忆,别的项目被无关约定污染。

全生命周期

  1. 写入:显式指令「记住这个」,或自动抽取候选——判断依据是重复性与纠正信号,同样的话说过两遍、用户刚纠正过一次都是强信号。
  2. 检索:发生在每轮组装上下文的时候,先按当前任务查出候选,再决定注入哪些;这属于 Context 工程的组装环节,本篇只管记忆侧的排序。
  3. 更新:约定变更时覆盖旧条目而非追加新条目——两条矛盾记忆并存是最坏的状态。
  4. 删除:长期不相关就清理。
  5. 可信度:每条记忆带来源——用户亲口说的、推断的、从旧会话摘要来的;可信度不同,使用时的把握不同。

文件 vs 检索库(第 2 层与第 3 层的分界)

文件(第 2 层)检索库(第 3 层)
长处透明、可人审、可版本化能语义查询海量记忆
短处翻不动大量条目对人不可读、调试困难、检索质量依赖排序算法

状态外部化是第 2 层的工程化用法:把待办清单、任务进度写成文件(而非指望对话历史),会话断了文件还在。Anthropic 的上下文工程一文把它叫「结构化笔记」,状态机篇的中断恢复靠的正是它。

业界现状(2026)

记忆已经从功能变成赛道:

主体定位机制口径数字
Mem0即插即用的记忆层混合多种存储后端2026-04 算法更新后官方口径:LoCoMo 长对话基准 92.5 分、LongMemEval 94.4 分,单次检索控制在 7K token 以内;论文口径:对 OpenAI 原生记忆约 26% 的相对精度优势,p95 延迟较「把全部上下文塞给模型」的做法低约 91%——省的正是没被塞进去的那些上下文 token
Letta(前身 MemGPT)有状态 Agent 平台,而非记忆 API记忆分层且由 Agent 自己编辑——思路直接来自操作系统「Agent 自己管分页」—
图记忆(Mem0 的图变体、Neo4j 系)关系查询把人与事的关系存成图,适合「谁和谁是什么关系」这类查询—

共同趋势:检索质量与 token 预算的平衡是这门生意的核心指标——记忆不再是「存得下」,而是「取得准、取得省」。

动手:写入判断与召回管线

写入端与读取端各一段伪代码(写入段呼应上文的「记忆一生」,召回段呼应下方的召回管线图):

def maybe_remember(turn, memory):
    for fact in extract_candidates(turn):     # 自动抽取候选事实
        if not worth_keeping(fact, memory):  # 已有同款 / 琐碎 / 已有更新版本
            continue
        memory.write(fact, scope=scope_of(fact),   # 项目级 or 全局级
                     source=turn.user, when=now())  # 可信度:来源 + 时间
    return memory

def recall(memory, query, session_key):       # session_key 带租户/会话标识
    hits  = keyword_search(memory, session_key, query)  # 字面一路
    hits += vector_search(memory, session_key, query)   # 语义一路
    hits = mmr_diversify(hits, lam=0.7)       # 既相关、又不互相重复
    hits = decay_rank(hits, now())            # 时间衰减:新记忆靠前
    return inject(hits[:K], as_="system-reminder")      # top-k 注入消息流

「四层记忆架构」对照:记忆课程里还有一种按骨架分层的讲法(该课程第 08 讲「四层记忆架构设计」)。公开可考的是讲次标题与它的配套武器——混合搜索、MMR 去重与时间衰减(第 09 讲,目标「准、不重、够新」,正是上面召回管线的三步);四层各自的名目在公开资料中考无可考,本篇不硬凑。可以对照的是分层思想本身:存储按介质分层(对应本篇第 2/3 层)、召回管线独立成层(本篇的管线四步)、时间维度单独治理(时间衰减)——骨架的影子都在三级体系里。

召回端那段是第 3 层的门道,其中的 MMR(最大边际相关)值得单独解释:挑下一条注入记忆时,同时要求「与查询相关」和「与已选中的条目不重复」,两股力量按权重平衡——这就是去重的算法化。整条管线画出来更直观:

召回管线:从查询到注入的四步 键位隔离 session_key 圈定范围 字面检索一路 关键词精确命中 语义检索一路 向量近邻召回 合并与去重 MMR:相关且不重复 衰减排序注入 新的靠前 · top-k 四步管线守住三条质量底线:准不准(两路合查)、重不重(MMR 去重)、够不够新(时间衰减) 隔离在最前:键位不对,后面再准也是别人的记忆

图:召回管线——隔离、双路检索、去重、衰减四步,守住「准、不重、够新」三条底线;最左的键位隔离是串味防线

同一概念的叫法对照:

本篇用词文献中的其他叫法深挖去处
记忆三级短期 / 长期(时间轴)+ 项目 / 全局(作用域轴)记忆产品篇
四层记忆架构记忆课程第 08 讲的骨架讲法:公开可考仅讲次标题+配套三件武器(混合搜索/MMR/时间衰减,第 09 讲),四层名目公开考无可考、正文已注明不硬凑(本篇重组为三级 + 召回管线)本篇
auto memory自动记忆 · 主题文件记忆本篇
system-reminder 注入提醒标记 · 动态上下文注入本篇
状态外部化结构化笔记 · 文件系统记忆状态机
召回管线混合检索 + MMR + 时间衰减本篇

边界与取舍:记性太好也是一种病

记忆注入是有上下文代价的

每次召回都占当轮预算,记性「太好」的 Agent 会把大量似曾相识的历史塞回上下文——注意力被稀释,回答质量反而下降(这正是 Context 工程篇说的注意力预算问题)。取舍标准:注入的记忆要「当前任务用得上」,宁缺毋滥;召回管线的去重与衰减不是锦上添花,是预算防线。

文件与检索库的分界

自测第一问的答案,这里先给结论。判断标准就两条:人要不要直接看它、量有多大。约定、偏好、事实——条目少、需要人审、最好进版本库 → 文件(第 2 层);对话历史级别的海量记忆、靠语义查、人永远不逐条读 → 检索库(第 3 层)。多数团队该从文件起步:透明可调试,出了错一眼能看出来;等条目真的翻不动了再上库,别一上来就把记忆变成黑盒。

串味是记忆系统的信任杀手

多租户(一套系统同时服务多个客户)场景下,A 客户的偏好泄漏给 B 客户,比「失忆」严重得多——失忆是能力问题,串味是事故。防线是把隔离做进键位:每条记忆的键里带上租户与会话标识,检索第一步先按键位圈定范围(即召回管线的第一步),而不是检索完再过滤——事后过滤一旦有漏网就是事故,事前圈定才从结构上把串味堵死。

坏味道预警

记忆只写不清,三个月后没人敢信任何一条旧记忆——缺的是退休机制与可信度标注;如果你的 Agent 「总是提起无关旧事」,缺的是召回的相关性过滤而不是更大的记忆库。记忆的「写而不删」与上下文的「只进不出」是同一种病,药方也同源——判断标准见上下文压缩。

自测

合上文章先自己答,再展开对照:

记忆什么时候该写文件、什么时候该进向量库?判断标准?

判断标准就两条:人要不要直接看它、量有多大。约定、偏好、确定的事实——条目少、需要人审、最好进版本库 → 写文件(第 2 层);对话历史级别的海量记忆、靠语义查询、人不逐条读 → 进向量库/图库(第 3 层)。作用域配套:跟项目的约定锁在项目内,跟人的偏好放全局。实践路径多数团队是从文件起步、撞到量再上库——先用足透明性,再换检索性。

Session 隔离、多租户隔离下记忆怎么设计才不串味?

核心是把隔离做进键位而非事后过滤:每条记忆的键(session_key)带上租户标识与会话标识,检索第一步先按键位圈定范围,圈外的记忆不进候选池——事后过滤一旦漏网就是事故,事前圈定才从结构上把串味堵死。分层看:会话内靠会话本身的边界(见上下文压缩篇),跨会话文件靠文件夹作用域(跟项目的锁项目内、跟人的随人走),检索库靠键位隔离多租户。另配来源标注让污染可追溯;MMR 去重与时间衰减让串进来的旧记忆即使漏网也难以排到注入位。

参考与延伸

本系列的后续学习路线(推荐顺序):Skill 机制 → 状态机与 Checkpoint → 多 Agent 编排。

本节点大纲与自测题(6 个子点 · 2 问)

大纲

  • auto memory:写入时机、加载位置、system-reminder 的意义
  • 记忆体系:短期 / 长期 / 项目级(目录结构、约定、历史修复)
  • 记忆操作全生命周期:写入、检索、更新、删除、可信度
  • 文件系统记忆 vs store 记忆、状态外部化与待办管理
  • 四层记忆架构:混合检索、MMR 去重与时间衰减(准、不重、够新)
  • 记忆产品生态:Mem0 等的定位

自测——答不上来就是缺口

  • 记忆什么时候该写文件、什么时候该进向量库?判断标准?
  • Session 隔离、多租户隔离下记忆怎么设计才不串味?