引言:为什么“记忆”是 AI Agent 的命脉?
如果你用过智能客服、编程助手或个性化推荐机器人,你一定遇到过这样的问题:
- 昨天刚告诉助手“我喜欢简洁的回答”,今天它又长篇大论;
- 对话一长,它就忘了几分钟前说过的重要信息;
- 同一个错误,纠正了三次,它依然会犯。
这些现象的背后,都指向同一个技术瓶颈:记忆系统。
对于互联网行业来说,记忆不只是存储聊天记录,而是可被决策利用的外部状态。谁能让 Agent 记住用户的偏好、习惯、任务进度,谁就能在个性化服务这条赛道上建立真正的壁垒。
然而,构建一个生产级的 AI 记忆系统远比想象中复杂。本文将带你理解 2026 年最新的 Memory 架构思考,并站在测试开发的视角,看看我们如何为这样的系统保驾护航。
一、记忆的本质:不是“仓库”,而是“通道”
很多人误以为记忆就是“把历史数据存起来,需要时查一下”。但原文提出了三个核心命题,颠覆了这种理解。
命题 A:记忆 ≠ 存储,而是“从历史到决策的通道”
记忆的价值不在于存了多少历史,而在于历史能否在当下影响决策。
举个例子:一个客服 Agent 存了 10 万条对话记录,但如果它在处理“退货流程”时,不知道用户三分钟前刚说过“已经寄回快递”,那这些记录就是死的。
真正有用的记忆系统,必须能把历史转化为当前可用的证据、摘要或子图,直接送入推理层。
命题 B:记忆的最小闭环是 (Ledger, Views, Policy)
- Ledger(原始账本) :追加式记录每一次写入、更新、删除。就像数据库的 WAL 日志,是“绝对真相”。
- Views(派生视图) :为了方便检索而构建的向量索引、知识图谱、时序列表等。它们可以是有损的,但必须能追溯到 Ledger。
- Policy(控制层) :决定什么时候读、读多少、什么时候写、怎么更新、如何遗忘。Policy 必须是显式的、可训练的、可回放的,不能只靠 prompt 里的“暗示”。
这三者缺一不可:没有 Ledger 就不可审计;没有 Views 就不可用;没有 Policy 就不可持续迭代。
命题 C:基本单位是事件序列,但不能直接当记忆用
原始事件流(用户输入、系统动作、时间戳、作用域……)是“真相来源”,但它太底层、太稀疏。真正把历史变成能力的是 Views(对事件的重组、压缩、索引)和 Policy(决定怎么用这些视图)。
小结:Memory 是一个闭环系统:Raw Ledger → Views → Policy → Commit → Provenance(可回放)。
二、快慢双系统:System 1 + System 2 的分工
为了平衡通用能力和个性化记忆,原文借鉴了认知科学中的“双系统”思想:
- System 1(快系统) :就是通用 LLM(大语言模型),负责推理、规划、工具调用。它的权重是相对固定的,保证了泛化能力。
- System 2(慢系统) :专门负责记忆的读写、检索、更新、固化。这是一个外置的、可观测、可回放的控制回路。
为什么非要拆开?
因为如果把所有记忆都内化到 LLM 权重里(即不断微调),会遇到两个问题:
- 灾难性遗忘(学了新任务,忘了旧能力);
- 不可解释、不可回滚(改了权重就回不去了)。
而外置的 System 2 让记忆变得可插拔、可迁移、易归因。
原文甚至给出了一个函数表达:
最终输出 = f_LLM(当前输入, 记忆系统提供的上下文)
这意味着:你可以换不同的 LLM,记忆系统照样工作;也可以升级记忆策略,而不用重新训练模型。
对于业务来说,这种设计意味着记忆能力可以作为一个独立的基础设施,被多个 Agent 共享和迭代。
三、非参数化 Memory:不用微调也能逼近微调的效果
很多人认为“要想让模型记住,就得微调”。但微调成本高、周期长、易退化。原文大量篇幅论证:通过精心设计的非参数化记忆(外部存储 + 策略),可以在工程上逼近参数化(微调)的上限。
核心思路:修正项 Δ
把 LLM 的一步决策看成输出一个概率分布(logits)。外部记忆的作用,就是对这个分布施加一个可控的修正项 Δ。
Δ 可以来自检索到的相似经验、技能、或时序证据。
两个有启发的论文
- JitRL:在推理时检索相似历史轨迹,计算优势函数,对 logits 做加性调制。效果类似于“推理时的梯度下降”。
- UMEM:不是孤立存储单条记忆,而是构建“语义邻域”,存储一类问题的通用解法,从而复现参数化模型的泛化能力。
上限由什么决定?
非参数化 Memory 的效果上限,不取决于“存了多少”,而取决于三个瓶颈:
- 接口带宽:你能往 LLM 的上下文里塞多少有效信息(受 token 数、注意力长度限制)。
- 检索与聚合误差:视图的近似程度,错检、漏检会污染 Δ。
- Policy 的可学习性:写多了污染,写少了学不到;更新错了会滚雪球。这是最被低估的瓶颈。
这意味着,测试开发在 Memory 项目中的核心工作之一,就是量化这三个瓶颈,并设计实验来验证改进效果。
四、业务场景适配:三个典型例子
为了让上面的抽象概念落地,我们来看三个真实的业务场景。
场景一:智能客服 Agent(电商行业)
需求:用户可能隔几天回来问同一个订单的问题。Agent 需要记住用户之前抱怨过“物流太慢”,本次对话要主动安抚,并推荐补偿方案。
Memory 架构如何适配:
- Ledger:记录每次交互的完整事件(时间、用户 ID、问题、客服动作、用户反馈)。
- Views:构建按用户的时序知识图谱(TKG),每条事实带有效时间窗口。例如“用户认为物流慢”这条事实,只在最近 7 天内有效。
- Policy:当用户再次进线时,系统先检索该用户在最近 30 天内的“负面情绪标签”,如果存在且未解决,则主动道歉并提供优惠券。Policy 由一个小型 RL 模型控制,决定是否触发“安抚动作”。
测试开发关注点:如何验证 TKG 的时间切片是否正确?如何确保 Policy 在 A/B 实验中不会因为写入了错误事实而导致长期负收益?
场景二:个人效率助手(办公行业)
需求:用户每天安排任务,助手需要记住用户的习惯(“每周五下午写周报”),并在合适时间主动提醒。
Memory 架构:
- Ledger:存储用户每一次“任务创建/修改/完成”的事件。
- Views:通过递归固化(如 SimpleMem)将重复行为压缩成“周期性记忆单元”。
- Policy:当时间接近周五 14:00 时,Policy 触发检索“周报相关任务”,并主动推送给 System 1 生成提醒。
测试开发关注点:固化的记忆会不会丢失关键细节(比如周报模板变了)?Policy 的主动推送会不会干扰用户正在进行的其他任务?
场景三:代码辅助 Agent(研发行业)
需求:Agent 帮助开发者写单元测试。它需要记住项目里常用的 Mock 模式、私有 API 的使用方式等。
Memory 架构:
- 程序性记忆层(Procedural Layer) :将成功的测试生成轨迹抽象为可复用的 Skill(技能)。例如“对于 Spring Boot 的 Repository 层,先 Mock 数据库,再用 assertThat 校验”。
- 非参数化 PPO:通过历史环境回报来评估每个 Skill 的价值,保留高价值技能,淘汰低价值技能。
- Integration Layer:Skill 以 latent token 的形式直接注入到 LLM 的注意力计算中,而不是拼接到 prompt 里(降低 token 开销)。
测试开发关注点:Skill 的可执行性怎么验证?如果代码库升级导致某个 Skill 失效,系统能否自动检测并降级?
五、测试开发在 AI 项目中的具体工作(重点)
在传统的软件开发中,测试主要关注功能、性能、安全。但在 AI 项目中,尤其是 Memory 系统这类状态复杂、行为概率化、长期演化的系统,测试的范畴被大大扩展了。
以下是根据原文思想,结合工程实践总结的 7 类测试开发工作,并附具体示例。
1. Ledger 审计测试(溯源与不可篡改性)
目标:确保每一次记忆的写入、更新、删除都被完整记录在 Raw Ledger 中,且可回放。
测试示例(伪代码):
def test_ledger_append_only():
agent = AgentWithMemory()
agent.remember("user_preference", "likes_short_answer")
agent.update("user_preference", "likes_detailed_answer", old_value="likes_short_answer")
agent.forget("user_preference")
ledger = agent.get_ledger_entries()
assert ledger[0].action == "ADD"
assert ledger[0].value == "likes_short_answer"
assert ledger[1].action == "UPDATE"
assert ledger[1].old_value == "likes_short_answer"
assert ledger[1].new_value == "likes_detailed_answer"
assert ledger[2].action == "DELETE"
assert ledger[2].value == "likes_detailed_answer"
# 确保没有物理删除,只有追加 tombstone
assert ledger[2].is_tombstone == True
2. Views 一致性测试(派生视图 vs 原始账本)
目标:验证向量索引、知识图谱等派生视图是否与 Raw Ledger 保持一致(允许有损,但必须可追溯)。
测试示例:
def test_view_consistency():
# 写入 100 条记忆
for i in range(100):
agent.add_memory(f"fact_{i}", f"content_{i}")
# 强制重建视图
agent.rebuild_views()
# 抽样验证:随机选 20 条,检查能否通过向量检索找回
for fact_id in random.sample(range(100), 20):
retrieved = agent.search(f"content_{fact_id}", top_k=5)
assert fact_id in [r.id for r in retrieved], f"Fact {fact_id} missing in view"
# 验证删除后视图同步更新
agent.delete_memory("fact_42")
retrieved_after = agent.search("content_42")
assert"fact_42"notin [r.id for r in retrieved_after]
3. Policy 决策可复现测试(确定性回放)
目标:对于相同的输入序列和初始状态,Policy 应该输出相同的决策序列(在无随机采样时)。这需要记录所有随机种子和内部状态。
测试示例:
def test_policy_reproducibility():
env = create_test_environment()
policy = MemoryPolicy(seed=42)
trace1 = run_episode(env, policy, record_actions=True)
# 重置环境,重新加载初始 ledger 和 views
env.reset()
policy.reset(seed=42)
trace2 = run_episode(env, policy, record_actions=True)
assert trace1.actions == trace2.actions # 每次 ADD/UPDATE/DELETE 序列必须一致
4. 时序正确性测试(双时态与时间旅行)
目标:验证 bi-temporal 逻辑 —— 同一个事实在不同查询时间下应返回不同版本,且系统能正确处理“事后纠错”。
测试示例:
def test_temporal_recall():
# 模拟时间 2026-01-01:用户说“我住在北京”
agent.set_current_time("2026-01-01")
agent.remember("user_home_city", "Beijing")
# 模拟时间 2026-02-01:用户说“我搬到了上海”
agent.set_current_time("2026-02-01")
agent.update("user_home_city", "Shanghai", old_value="Beijing")
# 查询时间 2026-01-15:应该返回 Beijing
result_past = agent.recall("user_home_city", query_time="2026-01-15")
assert result_past.value == "Beijing"
# 查询时间 2026-03-01:应该返回 Shanghai
result_current = agent.recall("user_home_city", query_time="2026-03-01")
assert result_current.value == "Shanghai"
# 事后发现 2026-01-20 用户其实还在北京,只是预告要搬 —— 追加纠错记录
agent.set_current_time("2026-02-15") # 系统当前时间
agent.correct("user_home_city", valid_time_start="2026-01-20", valid_time_end="2026-01-31", value="Beijing (still)")
# 再查询 2026-01-25:应该返回纠错后的值
result_corrected = agent.recall("user_home_city", query_time="2026-01-25")
assert result_corrected.value == "Beijing (still)"
5. 技能库(Skill)验证测试
目标:对于程序性记忆,需要验证技能的可执行性、不破坏环境、且收益可测量。
测试示例:
def test_skill_execution():
skill = agent.skill_pool.get("write_spring_repo_test")
# 准备一个隔离的沙箱环境(临时目录 + mock 数据库)
with Sandbox() as sandbox:
result = skill.execute(context={
"repo_class": "UserRepository",
"methods": ["findByEmail"]
})
assert result.exit_code == 0
assert "assertThat" in result.generated_code
# 执行生成的测试代码
test_result = sandbox.run_tests()
assert test_result.passed >= 1
6. A/B 实验平台与效果归因
目标:在生产环境同时运行多套 Policy 或 View 策略,并收集指标判断优劣。测试开发负责搭建实验框架和指标采集。
测试示例(配置化实验):
# experiment_config.yaml
name:"policy_early_stop_vs_full_retrieval"
duration:7d
traffic_split:
control:50% # 使用固定 top-10 检索
treatment:50%# 使用 InfMem 风格的自适应早停
metrics:
-avg_response_time
-task_success_rate
-memory_write_staleness
observability:
-traceeverypolicydecisiontojaeger
-exportmetricstoprometheus
测试开发需要编写脚本,自动对比两组实验的指标,并做显著性检验(例如 t-test)。
7. 压力与长期稳定性测试
目标:Memory 系统会随着时间不断累积数据。测试需要模拟长达数月甚至数年的交互,验证不会出现性能衰减、内存泄漏、视图膨胀失控。
测试示例:
def test_long_term_stability():
agent = create_memory_system()
# 模拟 1000 个虚拟用户,每个用户进行 10000 轮对话
for day in range(365):
for user in virtual_users:
# 每个用户每天产生 3~10 次交互
interactions = generate_interactions(user, count=random(3,10))
for in_text, expected_action in interactions:
agent.process(user, in_text)
# 每天结束后,检查系统指标
assert agent.ledger_size < MAX_LEDGER_BYTES # 应该自动归档或压缩
assert agent.avg_retrieval_latency < 500# ms
assert agent.memory_leak_check() == False
# 模拟周末压缩任务
if day % 7 == 0:
agent.run_consolidation()
assert agent.view_error_rate() < 0.01
六、总结与展望
AI Agent 的记忆系统不是一个简单的“向量数据库 + prompt”,而是一个包含原始账本、派生视图、可学习策略、时序结构、程序性技能和统一注入层的复杂闭环。
对于互联网行业的工程团队来说,构建这样的系统需要:
- 算法创新(如非参数化 PPO、双时态图谱);
- 系统工程(低延迟检索、可观测性、A/B 框架);
- 质量保障(上述 7 类测试开发工作缺一不可)。
而测试开发工程师在 AI 项目中的角色,正在从“找 bug”升级为“定义正确性、设计实验、量化瓶颈、保障长期可维护性”。这是挑战,也是机遇。