文章提出三种管理Agent陈旧指令的方法:关闭(被新指令替代时标记并降权)、衰减(长期未使用则逐步降低优先级)、降级(误操作时明确负标记),并给出向量数据库实现思路。
项目进行到一年时,一个 Agent 的记忆里积累了三条已经不该再被执行的指令。它记得用 npm 安装包,但自六月起又多了用 pnpm 的指令——两条同时存在,哪条先被召回都有可能。它还记得一个库 bug 的临时解决方案,但那 bug 早在春季就已修复,几个月来再没人用过。它记得对失败的集成测试重试直到通过,而 Agent 最后一次这么做时,重试掩盖了一个真正的回归问题。这三条指令与它们各自回答的问题匹配度,和当初写入时一模一样。
让过时或错误的指令被"遗忘"需要三个操作,衰减(decay)只是其中之一。当一条指令被新指令替代时,将其关闭(close):保留原内容、标记它停止适用的日期以及替代它的是哪条新指令,读取时优先选择开启(open)状态的指令。对于长期未被使用且未被确认的指令进行衰减,降低其排名权重,使其随时间推移不再以全部强度参与竞争。对于 Agent 执行时导致失误的指令,主动将其压下(push down),打上明确的负向标记。三个操作都不会删除任何内容。删除(deletion)仅限用于:密钥、个人数据应要求删除,以及纯粹的无用噪音(没有任何依赖它的东西)。
向量库按嵌入空间的相似度排名,而年龄、弃用和替代都不是这个空间的维度。相似度没有年龄也没有状态:去年的规范与今天的查询在匹配度上与当初毫无差别,余弦距离不会告诉你哪些已弃用。向量库没有坏。它回答的是"什么最相似?",而 Agent 需要的是"当前什么是对的?"。
勤勉反而让这个问题更严重:Agent 写记忆越认真,库里积累的废弃指令就越多,召回时命中其中之一的概率就越高。
上下文衰减会在指令长时间未被使用或确认的情况下,降低其召回优先级,使其在排名中逐渐下沉,而不是以全部强度参与竞争。它改变的是排名,不是存储。三个操作各自对应一条指令应该停止生效的不同原因:
关闭(Closing)。 当一条指令被替代时,不要覆盖它,也不要删除它。将其标记为已关闭,记录它停止适用的时间,并链接其后续指令:"用 npm 安装包,适用至 2026-06,被 pnpm 替代"。读取时优先选择开启状态的指令,但关闭的那条仍然存在——这比看起来更重要:当 Agent 被问到为什么一月分支里有 package-lock.json 时,它需要一月的指令来回答。覆盖是重写历史;关闭是版本化管理。
关闭需要知道什么替代了什么,而这在修正发生的瞬间才能确切得知。所以在写入修正时,修正本身就应该指明它关闭了哪条指令,而不是留给后续流程根据两条相似的文本来猜测。
衰减(Decay)。 从未被召回、从未被确认、也从未被反驳的指令,不应该永远以全部强度参与竞争。在一个可控的存储上实现衰减的一种方式:在每条记录上保存 last-used 和 last-confirmed 两个日期,写入时同时设置这两个值。读取时,获取比实际需要更多的候选结果,将每条结果的检索得分乘以一个系数,该系数随上述两个日期中较近的那个以来的时间递减,并在大于零的下限处截断,这样一条匹配问题很紧密的老记录仍然有机会被召回。衰减应该降权,而不是抹除。静默删除的衰减与数据丢失无法区分。
压下(Push down)。 有些指令并不老,只是错了,而且你知道它错了,因为按它行事导致了失败。这类指令值得一个明确的负向标记,使下一次同样的问题出现时,它排在备选指令之后。压下是定向的:只作用于导致误导的那条记录。衰减是环境性的:影响所有未被使用的东西。
删除(Deleting)。 硬删除有狭窄但真实的用武之地。判断标准很简单:如果没有任何东西曾经依赖该记录,删除它;如果有任何东西依赖过,关闭它而不是删除。
对于纯文本,三个操作都是编辑习惯:每条记录加一行状态行(active,或 closed, replaced by ...);定期审查生成一份清单供人审批,而不是静默删除;以及一条规则——永远不要在原地重写旧记录。这套方法有效,人就是垃圾回收器。
对于记忆系统,同样的三个操作变成需要关注的属性:记录上的状态和有效期窗口、只降权不删除的衰减机制,以及用于标记"导致误导"的反馈通道。
代码使用 PyPI 上的 mnemoverse 0.4.0(Mnemoverse 的 Python SDK,Mnemoverse 是作者的公司),安装方式见 Python SDK 页面。示例覆盖了关闭操作:写入时和读取时,以及 Agent 行为后的评分。Agent 自身的逻辑略去。
from mnemoverse import MnemoClient
client = MnemoClient() # reads MNEMOVERSE_API_KEY
DOMAIN = "project:web"
# January: the instruction as it was given
old = client.write(
"Instruction (2026-01, repo: web): install packages with npm.",
concepts=["instruction", "package-manager", "npm"],
domain=DOMAIN,
)
if not old.stored:
raise SystemExit(f"Not stored: {old.reason}")
# June: the correction names the instruction it closes, in the same write
new = client.write(
"Instruction (2026-06, repo: web): install packages with pnpm, not npm. "
"Replaces the 2026-01 npm instruction.",
concepts=["instruction", "package-manager", "pnpm", "npm"],
domain=DOMAIN,
supersedes=[str(old.atom_id)],
)
if not new.stored:
raise SystemExit(f"Not stored: {new.reason}")
print(new.superseded) # the ids this write marked as replaced
# Before acting: read, and act only on instructions nothing has replaced
result = client.read("how do I install packages in the web repo", domain=DOMAIN)
current = [item for item in result.items if item.superseded_by is None]
for item in current:
print(item.content)
# After acting: rate what was used (1.0 helped, -1.0 misled)
if current:
client.feedback(
atom_ids=[item.atom_id for item in current],
outcome=1.0,
query_concepts=result.query_concepts,
domain=DOMAIN,
)
# Explaining the past: ask for replaced instructions too
history = client.read(
"which package manager did the web repo use in January",
domain=DOMAIN,
include_history=True,
)
for item in history.items:
print("replaced" if item.superseded_by else "current", item.content)
六月的写入在 supersedes 中指定了一月的记录,API 文档说明了这样做的结果:"目标记录不会被删除;它获得一个 superseded_by 指针指向新 atom,但仍可通过 ID 获取"。对已替代记录在普通读取中隐藏是一个组织设置("Hide replaced memories",在控制台 Settings 下),默认关闭,所以一次读取可以把一月和六月的指令同时返回。针对这种情况,文档指明了需要检查的字段:"隐藏开关关闭时,这个字段用来区分已替代版本和当前版本"。所以代码自身过滤 superseded_by,无论设置开关与否结果都一样。开关打开时,普通读取只返回当前记录,而 include_history=True 会让已替代记录在同样排名规则下重新可被召回,正如 Reading history 文档所述。
评分会重新排序下次返回的结果。但这有局限性:反馈"改变下一次读取的顺序,不改变存储的文本"。两次 stored 检查是为写入门槛服务的:写入内容与同域最近记忆过于相似则不会被存储,被拒绝的写入不会返回 id,也就没法传给 supersedes。
写入一条指令,然后写入一条指明被替代的修正指令。问 Agent 如何执行该任务。它应该遵循修正指令,而不是原始指令。
让它解释在旧指令下发生的某件事,比如一月的 lockfile。它应该找到已关闭的指令并说明它已被替代,这说明关闭保留了删除会丢失的历史。
对照组:问一条从未被替代的指令,比如如何运行测试。它应该作为当前指令返回。如果它被标记为已替代,或者 npm 指令未被标记,说明关闭没有生效,第一个答案也就不能证明任何东西。
文档的 library 页面有更完整的版本,包括在将指令托付给一个记忆系统前应该关注什么。你的 Agent 还在遵循哪条已废弃的指令?