# Agent Memory (智能体记忆)

*笔记是你能读能改的真相，索引只是可以丢弃的缓存。*

> **Agent Memory（智能体记忆）** = **你能读、能改的笔记** + **可以随时丢弃的索引**。每条笔记都引用它的来源；索引（全文、向量、图、轮廓）只是笔记的派生物；后台维护作业只**提议**修改，绝不改写原始日志。

**AN-07** · 符合性等级: L2 Memory · 概念簇: 知识

## 要解决的问题

记忆框架把记忆放进不透明的数据库：无法检查、对比、迁移、纠正，也难以可靠删除；索引和嵌入模型被绑死。而记忆本身就是攻击面：2026 年的[一项研究](https://arxiv.org/abs/2606.04329)里，持久记忆投毒在两个智能体上的平均攻击成功率达 50.46%；[另一项研究](https://arxiv.org/abs/2607.05189)用一封精心构造的邮件，在文件系统和向量两种记忆后端上都得了手。

同时，“哪种记忆架构最好”远没有定论：基准互相矛盾。一份不押注任何检索算法的设计，才扛得住三年的变化。

## 工作方式

- **笔记是真相。** Markdown 加 YAML frontmatter：`kind`（情景、语义、程序、偏好）、`subject`、`sources`、`confidence`、`valid_from`、`valid_to`、`supersedes`、`origin`、`reviewed`。
- **更新而非覆盖。** 新事实 `supersedes` 旧事实；区分有效时间与记录时间，因为事实会变，而常见基准几乎不测这一点。
- **索引是缓存。** BM25（如 SQLite FTS5）、向量（可以多套并存）、可选的图；每个派生物带**配方**与**输入**。换嵌入模型就是后台重算，旧索引保留到新索引的黄金召回测试达标为止。
- **两类派生。** 确定性的（切块、BM25、固定模型的嵌入）可复现；生成式的（LLM 摘要、抽取出的事实）只能“再生成并比对”，因此标记 `generated: true`，并且从不作为唯一副本。
- **写入路径。** `nas_remember` 把笔记（含来源）写到当前分支；污点随之继承。来自 `external` 污点会话的笔记进入**隔离区**，标记为未审阅：可以被召回，但**不自动加载**，也不会进入 `MEMORY.md`。
- **读取路径。** `nas_recall` = 搜索、候选、预算视图加证据指针，并显示笔记的来源与审阅状态。
- **维护作业**（夜间或空闲时）：去重、把情景整合成语义事实、标记矛盾、让过期的事实失效、重建索引。作业在分支上产出提案，由人或智能体审阅；**绝不删除原始日志**；度量“后悔率”（被回滚的提案比例）。
- **黄金召回测试。** 每个 Home 一组“问题、期望笔记”，换模型或索引器时自动回归。

## 从小处开始

- `memory/notes/*.md` 加 frontmatter；用 SQLite FTS5 做检索。
- 在 CI 里跑十条黄金问题。
- 向量索引和维护作业都可以以后再加；先把“来源”和“已审阅才自动加载”做对。

## 接口草图

仅作示意。字段名在规范 v0.3 之前可能调整。

*memory/notes/customer-acme.md*

```markdown
---
id: mem_4kq2
kind: semantic
subject: customer/acme
valid_from: 2026-10-02
valid_to: null
confidence: 0.8
origin: agent
reviewed: true
sources:
  - nas://home-box/agents/cleo/journal/2026-10-02.md@9f2c1de#L12-L18
supersedes: [mem_1xa9]
---
Acme renewed for 24 months; the champion moved from Dana to Luis.
```

## 规范的要求

- 笔记**必须**能脱离 Memory 层被读取（它们是 Store 里的普通文件）。
- 每个派生物**必须**带配方与输入；索引**必须**可丢弃并可重建。
- 由受污染会话写入的笔记，在被审阅之前**不得**自动加载。
- 新事实**必须**以 `supersedes` 取代旧事实，而不是覆盖。
- 维护作业**必须**在分支上工作并只提议；**不得**删除原始日志。
- 每个 Home **应当**带黄金召回测试，在模型或索引器变化时运行。

## 借鉴与区别

下面这些都是现成的思路，OpenClaw 的记忆架构已经做了来源标签、按层隔离和整合时的污点传播。**真正新的部分：** OpenClaw 在**单个运行时内部**做；我们提议在**共享的存储里**做，让任何运行时都受益；并把索引降为可丢弃的缓存，使检索算法可以更换而记忆不丢。

- [Letta Context Repositories](https://www.letta.com/blog/context-repositories/)
- [Letta: is a filesystem all you need?](https://www.letta.com/blog/benchmarking-ai-agent-memory/)
- [OpenClaw memory architecture](https://docs.openclaw.ai/concepts/memory-architecture)
- [Long-term memory security survey](https://arxiv.org/abs/2604.16548)
- [Graphiti](https://github.com/getzep/graphiti)
- [MemGPT](https://arxiv.org/abs/2310.08560)

## 坦诚的局限

- 生成式派生物不可能逐位重现。
- 维护作业可能把错误“固化”成事实，所以它只提议，不直接改。
- 哪种记忆架构最好，目前没有定论。

## 开放问题

- 何时由智能体自己写，何时交给维护作业？
- 跨模型版本的回归标准是什么？

## 常见问题

### 为什么用文件，不用向量数据库？

文件是你能读、能改、能 diff、能带走的真相；向量索引是它的派生缓存，可以并存多套、随时重建。Letta 的基准说明，只给智能体 `grep` 和文件工具就有竞争力，但各家基准互相矛盾，所以设计不押注某一种检索算法。

### 怎样防止记忆被投毒？

无法保证绝不被写入，但可以限制后果：外部来源的内容带着 `external` 标签；受污染会话写的笔记进入隔离区，不自动加载；合并要经过审阅；出了问题可以顺着来源链找到受影响的笔记并回滚。

### 换嵌入模型要迁移记忆吗？

不需要。笔记不变，只是在后台用新的配方重算索引；旧索引保留到新索引的黄金召回测试达标为止。

## 相关概念

- [Budgeted Reads (预算化读取)](https://agentnas.com/zh-cn/concepts/budgeted-reads/): 同一个文件可以用轮廓、章节、行范围或全文来读，按预算降级。
- [Cascade Forget (级联遗忘)](https://agentnas.com/zh-cn/concepts/cascade-forget/): 沿血缘删除派生物，按保留类处理历史，并如实报告做不到的部分。
- [Trust Labels (信任标签)](https://agentnas.com/zh-cn/concepts/trust-labels/): 来源与敏感度两个小标签，加上会话污点，强制执行 Rule of Two。

---

规范网址: https://agentnas.com/zh-cn/concepts/agent-memory/
更新于: 2026-11-11 · 规范草案 v0.2 · CC BY 4.0
