第 15 章:Memory Engineering
本章导读
- 核心问题:如何把历史任务中有价值的经验沉淀为 Memory。
- 关键词:Memory、Semantic Memory、Episodic Memory、Procedural Memory、Project Memory
- 学习产出:从 build #4312 中沉淀“修改 OrderStatus 需同步状态机”的项目记忆。
1. 本章要解决什么问题
前面我们讨论了 Context、Skill、Tool 和 Harness。
现在进入另一个核心能力:Memory。
很多人把 Memory 理解成“把聊天记录存起来”。
这是非常危险的简化。
真正的 Memory Engineering 要回答的是:
什么信息值得被记住?
记住多久?
记在哪个作用域?
如何检索?
如何更新?
如何删除?
如何防止错误记忆污染未来任务?
Anthropic 在 Context Engineering 文章中提到 memory tool:让 Agent 把信息存放在上下文窗口之外,在跨会话、跨窗口的任务中继续引用。
这说明 Memory 的本质不是“更长上下文”,而是:
把可复用的状态、经验和知识放到 Context Window 之外,并在需要时重新注入。
本章核心观点是:
Memory 不是聊天历史,而是经过筛选、结构化、可检索、可治理的长期上下文资产。
2. Memory 与 Context 的关系
Memory 和 Context 的关系可以这样理解:
Memory 是外部存储中的长期信息
Context 是当前模型调用中可见的信息
Memory 不等于 Context。
Memory 只有在被检索、选择、压缩、注入后,才成为当前 Context 的一部分。
这个区别非常重要。
错误做法:
把所有历史对话都拼接进上下文。
正确做法:
把历史信息结构化存储为 Memory。
当前任务需要时,检索最相关、最可信、最有用的记忆进入上下文。
3. Memory 的分类
3.1 Short-term Memory:短期记忆
短期记忆服务当前会话或当前任务。
例如:
- 当前计划;
- 已完成步骤;
- 当前假设;
- 最近工具结果;
- 未解决问题;
- 用户刚刚确认的约束。
短期记忆通常存放在 Session 或 Checkpoint 中。
它不一定进入长期 Memory。
3.2 Long-term Memory:长期记忆
长期记忆跨会话保存。
例如:
- 用户偏好;
- 项目常见问题;
- 历史修复经验;
- 团队规范;
- 常用命令;
- Agent 过去学到的模式。
长期记忆必须谨慎写入,因为它会影响未来任务。
3.3 Semantic Memory:语义记忆
语义记忆保存事实和知识。
例如:
OrderStateMachine 负责订单状态转换校验。
项目使用 JUnit 5 和 Mockito。
CI 使用 PostgreSQL 而不是 H2。
它类似知识库。
3.4 Episodic Memory:情景记忆
情景记忆保存过去发生过的事件。
例如:
2026-07-01 的 CI 失败是因为新增 OrderStatus 后没有更新状态机。
任务 #1234 中用户拒绝了数据库迁移方案。
它适合用于排查重复问题、复盘历史决策。
3.5 Procedural Memory:过程记忆
过程记忆保存做事方法。
例如:
修改状态枚举时,先搜索状态机,再更新测试,最后运行 OrderServiceTest。
Procedural Memory 与 Skill 很接近。
区别是:Skill 通常是显式编写和发布的能力包;Procedural Memory 可能来自历史经验沉淀。
3.6 User Memory:用户记忆
用户记忆保存用户偏好和工作方式。
例如:
- 用户喜欢中文总结;
- 用户希望先给架构图再给代码;
- 用户偏好 Java / Spring Boot;
- 用户不喜欢过度解释基础概念。
用户记忆必须受隐私和删除权约束。
3.7 Project Memory:项目记忆
项目记忆保存项目级经验。
例如:
这个项目的测试命令是 ./mvnw test。
修改 Controller 后必须更新 OpenAPI 文档。
历史上 Redis 相关测试经常因端口冲突失败。
Project Memory 只能在对应项目作用域内使用。
4. Memory 写入原则
Memory 写入比检索更危险。
因为错误写入会长期影响 Agent。
4.1 不是所有信息都值得记住
不应写入长期记忆的内容:
- 临时猜测;
- 未验证假设;
- 一次性任务细节;
- 过期错误;
- 敏感数据;
- 用户隐私;
- 大段原始日志;
- 模型自我推理草稿。
适合写入长期记忆的内容:
- 用户明确偏好;
- 被验证的项目事实;
- 可复用流程;
- 历史问题根因;
- 团队长期规范;
- 常见坑;
- 经过确认的决策。
4.2 Memory 必须有作用域
Memory 至少应区分:
USER
PROJECT
TEAM
ORGANIZATION
GLOBAL
不能让一个项目的经验污染另一个项目。
也不能让一个用户的偏好影响另一个用户。
4.3 Memory 必须有来源
每条 Memory 应记录来源:
- 用户明确告诉;
- 工具观察;
- 任务总结;
- 人工确认;
- 文档提取;
- 历史 Issue。
没有来源的记忆很难信任。
4.4 Memory 必须有置信度
例如:
用户明确确认:confidence = 1.0
测试结果证明:confidence = 0.9
Agent 推断:confidence = 0.4
低置信度记忆不应直接注入关键任务上下文。
4.5 Memory 必须有生命周期
有些记忆长期有效,例如项目技术栈。
有些记忆会过期,例如临时分支策略。
Memory 应支持:
- expiresAt;
- lastAccessedAt;
- updatedAt;
- deprecated;
- archived。
5. Memory 与 Skill 的关系
Skill 是显式组织的能力包。
Memory 是运行过程中积累的信息。
二者可以互相转化。
例如多个历史任务都产生类似记忆:
修改 OrderStatus 时必须更新 OrderStateMachine。
当这个模式足够稳定,就应该从 Memory 提升为 Project Skill 或 AGENTS.md 规则。
也就是说:
重复出现的高价值 Memory → Skill / Project Knowledge
6. 架构图 / 流程图
6.1 Memory 生命周期
6.2 Memory 类型
6.3 Memory 到 Skill 的沉淀
7. Java / Spring Boot 落地方案
7.1 MemoryRecord
public record MemoryRecord(
String id,
MemoryType type,
MemoryScope scope,
String scopeId,
String content,
String source,
double confidence,
Sensitivity sensitivity,
Instant createdAt,
Instant updatedAt,
Instant expiresAt,
Map<String, Object> metadata
) {}
7.2 MemoryType
public enum MemoryType {
SEMANTIC,
EPISODIC,
PROCEDURAL,
USER_PREFERENCE,
PROJECT_KNOWLEDGE,
TASK_SUMMARY
}
7.3 MemoryScope
public enum MemoryScope {
USER,
PROJECT,
TEAM,
ORGANIZATION,
GLOBAL
}
7.4 MemoryService
public interface MemoryService {
MemoryRecord write(MemoryWriteRequest request);
List<MemoryRecord> retrieve(MemoryQuery query);
void update(String memoryId, MemoryUpdateRequest request);
void delete(String memoryId, DeleteReason reason);
}
7.5 MemoryWriter
public interface MemoryWriter {
Optional<MemoryRecord> maybeWrite(AgentEvent event, MemoryPolicy policy);
}
maybeWrite 这个名字很重要。
因为默认不是“都写入”,而是“判断是否值得写入”。
7.6 MemoryStore
MemoryStore 可以组合多种存储:
PostgreSQL:结构化元数据
Vector DB:语义检索
Object Storage:原始证据或长文档
Search Index:全文检索
Memory 不能只存在向量库里。
因为治理需要结构化字段。
8. 常见误区
8.1 把聊天记录当 Memory
聊天记录只是原始材料,不是工程化记忆。
8.2 模型随意写入长期记忆
长期记忆应受策略控制,必要时需要用户或系统确认。
8.3 没有作用域
Memory 串用会带来严重错误和隐私风险。
8.4 没有过期机制
过期记忆比没有记忆更危险。
8.5 只用向量数据库
向量检索不能替代权限、生命周期、审计和删除。
9. 贯穿案例:CI 失败分析 Agent
CI 失败分析会产生有价值的 Project Memory。
对于 build #4312,如果最终确认根因是新增 OrderStatus.PENDING_REVIEW 后没有更新 OrderStateMachine.allowedTransitions,可以写入一条项目级过程记忆:
{
"type": "PROCEDURAL",
"scope": "PROJECT",
"scopeId": "order-service",
"content": "When modifying OrderStatus, update OrderStateMachine.allowedTransitions and run OrderServiceTest.",
"source": "CI build #4312 analysis",
"confidence": 0.92
}
这条 Memory 未来可以帮助 Agent 更快分析类似失败。
但并不是所有内容都应该写入长期 Memory。完整 CI 日志、临时猜测、用户私密信息、一次性 build token 都不应保存为长期记忆。
这个案例说明,Memory Engineering 的关键不是“多记”,而是把被验证、可复用、有作用域的经验沉淀下来。
10. 本章小结
本章讨论 Memory Engineering。
核心结论:
- Memory 是上下文窗口之外的长期上下文资产。
- Memory 不等于聊天历史,必须结构化、可检索、可治理。
- Memory 应区分语义、情景、过程、用户和项目记忆。
- Memory 写入必须有作用域、来源、置信度和生命周期。
- 重复高价值 Memory 可以沉淀为 Skill 或 Project Knowledge。
一句话总结:
Memory 的价值不在于让 Agent 什么都记住,而在于让它在正确作用域内记住真正可复用的经验。
11. 实践任务
任务 1:设计 MemoryRecord 表
用 SQL 或 Java 定义 MemoryRecord,包含:type、scope、content、source、confidence、expiresAt。
任务 2:Memory 写入判断
列出 10 条 Agent 运行事件,判断哪些应该进入长期 Memory,哪些应该丢弃。
任务 3:项目记忆实验
从一个真实项目中提取 3 条常见坑,写成 Project Memory。
任务 4:Memory 到 Skill
选择一条反复出现的项目记忆,改写成 AGENTS.md 规则或 Skill 片段。