Agentic Memory 的工程本质:不是存储问题,是检索问题

几乎所有团队在第一次遇到 Agent 记忆问题时,第一反应都是去找一个向量数据库。

这个直觉不完全错,但它把问题想窄了。Agent 的记忆问题不是”怎么存”,而是”在对的时刻,把对的东西喂给模型”。这是一个检索问题,存储只是检索的前提条件。

先把问题说清楚

Agent 在执行任务时,有两种截然不同的”遗忘”场景:

场景一:上下文窗口溢出。 任务进行到中途,历史对话和工具调用记录超出了模型的 context window 上限。早期的内容被截断,Agent 开始”失忆”——它不知道自己在任务第三步做了什么决定,为什么放弃了某个路径。

场景二:会话间遗忘。 新一次任务开始,之前所有的执行历史、用户偏好、已解决的问题都消失了。每次都是全新出发,重复犯同样的错误,重新询问已经回答过的问题。

这两个场景性质不同,解法也不同。但很多团队在讨论 Agentic Memory 时把它们混在一起,最终设计出一个既解决不了场景一、又解决不了场景二的系统。

四个记忆平面

我习惯把 Agent 的记忆需求分成四个平面,不是按技术实现分,而是按信息的时间粒度和访问模式分:

工作记忆(Working Memory):当前任务的执行状态。目标是什么、已完成了哪些步骤、当前在等待什么、上一步的结果是什么。这部分信息时效性极强,任务结束即失效,但在任务进行中必须始终可见。工作记忆不应该依赖检索,它就应该在 context 里。

情节记忆(Episodic Memory):过去任务的执行记录。”上次用户让我帮他 review PR,他的偏好是只关注安全问题,不要涉及代码风格”——这类信息是情节性的,有具体的时间和场景。访问模式是按相似性检索:当前任务和过去哪个任务最像?

语义记忆(Semantic Memory):从经验中提炼的知识。”这个代码库使用 Go 1.21,不允许使用 _ = err,所有错误必须显式处理”——这类信息已经脱离了具体情节,成为了通用规则。访问模式是按关键词或分类检索。

程序记忆(Procedural Memory):怎么做某件事的模式。不是”我做过什么”,而是”我应该怎么做”。SOP、操作手册、tool use 的最佳实践。这类记忆通常以结构化文档的形式存在,在任务开始时注入,而不是运行时动态检索。

把这四个平面分开,就能避免一个常见的设计失误:把所有东西都扔进向量数据库,然后发现向量检索对工作记忆完全不适用(工作记忆需要的是确定性访问,不是相似性匹配),对程序记忆也很低效(SOP 应该被完整读取,不是片段化检索)。

检索比存储难

存储是相对容易解决的问题。真正的工程难点集中在检索这一侧。

检索触发的时机问题。 什么时候从记忆库里取信息?一个常见的做法是在每轮对话开始时统一检索,但这会在上下文里填入大量当前不需要的信息。更好的做法是按需检索——Agent 在推理过程中意识到自己需要某类信息时,主动调用记忆工具。这要求 Agent 有足够好的元认知能力:它得知道自己不知道什么。

检索精度与召回的取舍。 向量检索的召回率不错,但精度往往不足。一次任务相关的记忆可能有几十条,但实际有用的只有三条。把所有召回结果都塞进 context,是在用上下文空间换检索的懒惰。精度优先的方案需要在检索后加一层 rerank 或者 Agent 自身的过滤,成本更高,但 context 利用率也更高。

写入时机与质量。 记忆是在哪个时刻写入的?任务执行中实时写,还是任务结束后统一整理?实时写的好处是不遗漏,缺点是噪声多——执行过程中的试错、失败路径都会被记录下来。任务结束后整理的质量更高,但需要一个专门的”记忆整理”步骤,以及对这个步骤质量的保证。

我们在内部项目里最终采用了分层写入的策略:执行过程中只记录关键决策点(不是所有步骤),任务结束后由一个轻量级的 summarization Agent 生成情节摘要写入情节记忆,如果摘要中发现了可提炼的通用规则,再单独写入语义记忆。这三层是独立的写入路径,不互相阻塞。

一个容易忽视的问题:写-读不对称

记忆系统有一个结构性的不对称:写入时你不知道未来会怎么读,读取时你不知道当初为什么这样写。

这导致一个工程上的实际困境:你在写入记忆时无法预判最优的检索键。

用向量数据库举例。你在写入一条记忆时选择了某种 embedding 方式,这个 embedding 代表了你对”这条记忆未来会被什么样的查询命中”的隐式假设。但 Agent 未来实际使用的查询方式你并不清楚。随着任务场景扩展,早期写入的记忆可能用越来越不合适的 embedding 表示。

解法之一是写入时同时生成多种索引:embedding 向量用于语义检索,关键词用于精确匹配,时间戳和任务类型用于结构化过滤。在检索时根据查询特征选择合适的索引,而不是用一种索引应对所有场景。

代价是写入成本增加,索引维护复杂度上升。这是一个必须接受的权衡。

两个常见的失败模式

过度记忆(Memory Bloat)。 记什么都存,结果记忆库里充满低质量的噪声。检索时召回的全是不相关内容,反而干扰了 Agent 的判断。表现症状:随着使用时间增长,Agent 的任务完成质量不升反降。

根本原因通常是缺少遗忘机制。人类记忆有自然的衰减,Agent 的记忆系统需要主动设计遗忘策略:按时间衰减、按访问频率降权、定期触发记忆整理和去重。

上下文幻觉(Context Hallucination)。 Agent 把检索回来的记忆当作事实,即使这些记忆已经过期或者在新场景下不再适用。一个经典案例:Agent 从记忆里检索到”这个用户不喜欢在代码里加注释”,但这是半年前针对另一个项目的偏好,当前项目要求注释。

解法是给记忆标记时效性和适用范围,检索时返回这些元数据,让 Agent 自行判断记忆的适用性。这要求在写入时就做好结构化标注,是前期投入换后期收益的事情。

与 Harness 的关系

记忆系统不是独立运作的,它是 Harness 架构中的一个组件。

工作记忆的管理是上下文管理的核心职责(Harness 的第三层)。情节记忆和语义记忆通过工具的形式暴露给 Agent——search_memorystore_memory 是工具,受权限模型约束,可以通过钩子监控每次读写操作。

这个设计的好处是:记忆系统的访问是可审计的。你可以看到 Agent 在什么时刻检索了什么记忆,检索结果是否被使用,从而判断记忆系统的质量问题出在哪个环节。

如果记忆系统是一个黑盒、Agent 透明地访问、没有工具层隔离,你就失去了这个可观测性,排查问题的难度会成倍上升。


记忆问题是 Agent 系统从 demo 到生产的核心门槛之一。

不是因为技术不成熟,向量数据库、知识图谱、结构化存储都已经是成熟的工具。是因为记忆系统的设计决策高度依赖具体任务场景,没有通用方案,每一个看似简单的选择背后都有不小的权衡。

把这个问题想清楚,先于选型。


Agentic Memory 的工程本质:不是存储问题,是检索问题
https://www.krli.org/2026/04/16/Agentic-Memory-工程设计/
作者
李科燃
发布于
2026年4月16日
许可协议