评估记忆质量——以及它能捕获的陷阱。
记忆系统会静默失效。智能体仍在回答、仍在行动、在演示里仍看着没问题——而它在悄悄回忆一条过期事实、服从一条被毒化的记忆,或在压缩中遗忘了一条约束。你无法调优你没有度量的东西。本文定义记忆特有的指标,以及它们存在所要捕获的失效模式。
为什么通用评估漏掉记忆缺陷。
端到端的任务成功率评估最终会捕获一个损坏的记忆系统,但很晚、很嘈杂,且不告诉你哪一层坏了。记忆失效是弥散的:第 12 轮一次错误回忆,会在第 30 轮表现为一个糟糕动作。你需要把记忆栈与智能体推理隔离开的评估,并对每个操作设置定向探针:写入、回忆、压缩、更新。
原则:每一个可能丢失或扭曲信息的记忆操作,都有它自己的数据集和它自己的指标。聚合任务成功率是集成测试;这些是单元测试。
核心记忆指标。
- Recall@k(记忆)——给定一条 N 轮前写入的已知事实,以及一个本应浮现它的查询,它在前 k 个里吗?最重要的单个数字。把它作为存储规模和轮次距离的函数来跟踪——一个在 100 条记忆时正常、在 5 万条时损坏的系统,是常态失效轨迹。
- 回忆精度/干扰率——被注入上下文的记忆中,真正相关的比例是多少?高召回配低精度,会用看着自信的垃圾毒化推理。
- 约束存活——一次压缩后,所有硬约束在结果状态中是否仍成立?以每约束每压缩的严格通过/失败来度量。
- 过期率——当一个事实已被更新,后续回忆中返回旧值的比例是多少?直接度量更新路径。
- 写入精度——写入长期记忆的一切中,真正值得持久的比例是多少?低写入精度是未来回忆崩塌的领先指标。
# eval/memory_eval.py def recall_at_k(mem, probes, k=5) -> float: # probe = (fact_id, query, turns_ago) injected earlier hit = 0 for p in probes: got = mem.recall(p.query, k=k) hit += int(p.fact_id in {g.id for g in got}) return hit / len(probes) def staleness_rate(mem, updates) -> float: # update = (key, old_val, new_val); recall after update stale = 0 for u in updates: v = mem.recall(u.key, k=1)[0].text stale += int(u.old_val in v and u.new_val not in v) return stale / len(updates)
在每次对记忆栈的改动上,针对一条合成的长时程轨迹(数百轮,植入的事实、植入的更新、植入的约束)运行这些。这就是 retrieval-augmented-memory 中的权重调优和 context-compaction 中的触发器所针对的评估框架。
陷阱:上下文毒化。
一条错误的、幻觉的或对抗性的陈述被写入长期记忆,随后被以与真实记忆同等的权威性回忆出来,并传播开——智能体据它推理,产出与它一致的输出,而那输出本身可能又被写回。一个自我强化的谬误。
- 给写入路径设门控:不要在没有落地依据的情况下,把模型生成的论断作为语义事实持久化。一个推断被存为推断,而非事实(即
retrieval-augmented-memory中的来源标注)。 - 绝不把回忆到的记忆放进权威系统块:它是证据,不是策略。毒化一个提示可恢复;毒化一条指令是服从。
- 评估探针:注入一条已知为假的记忆,然后度量它在答案中浮现的频率,以及智能体是否曾把一个派生谬误写回。无法传播回存储的毒化即被控制住。
陷阱:过期记忆。
一个事实在写入时为真、现在错了——用户换了团队、API 版本升级了、策略改了。记忆系统自信地回忆出那个过时值。这正是仅追加向量库必然导致、而就地键值更新(memory-stores)能防止的失效。
- 语义记忆就地更新:一个键,一个当前值。新观察覆盖它,而非累积。
- 带时间戳、冲突时偏好较新者:当两条记忆相左时,时近性打破平局,并把分歧暴露出来,而不是静默挑一个。
- 评估探针:上面的过期率指标。非零的过期率意味着更新路径坏了——P0,因为智能体现在自信地错着。
陷阱:检索漂移与压缩失忆。
两种共享一个特征的失效——系统看起来健康,因为它仍返回貌似合理的结果——因此没有定向探针就不可见。
- 检索漂移:一个在任务开始时构造一次的线索,持续回忆早期、如今已无关的记忆,而任务已经向前推进。通过度量 recall@k 作为进入任务的轮次距离的函数来捕获,而不只是在第 1 轮。一条在任务中途衰减的曲线就是漂移。修复:每轮从当前状态重建线索。
- 压缩失忆:一条约束或未闭合回路在摘要中被丢弃,智能体当它从未存在过般继续推进。通过
context-compaction中的约束存活与未闭合回路存活检查来捕获。修复:为硬约束和活跃回路设一个钉住的、永不压缩的块。
memory eval report (synthetic 300-turn trajectory)
recall@5 @ store=1k 0.91 ok
recall@5 @ store=50k 0.58 FAIL ← redundancy collapse
recall@5 by turn-distance: t1 0.94 t150 0.61 FAIL ← drift
staleness rate 0.00 ok (kv in-place update)
constraint survival 18/20 FAIL ← compaction dropped 2
write precision 0.41 WARN ← tighten write gate
这份报告就是交付物。一个记忆系统不是在十轮演示里能用就"完成"了——它是在你将真正投入生产运行的存储规模和任务长度下,这些数字在一条合成长时程轨迹上仍然成立时才完成。先度量;本节其他每篇文章都是你针对这块仪表盘去拧的旋钮。