深色模式
Agent 记忆机制 Memory
摘要:无记忆的 Agent 每次都从零开始,无法跨轮次利用上下文,也无法在长期任务中保持状态。本文区分短期记忆(上下文窗口)、长期记忆(向量/KV 存储)与工作记忆(中间状态),讲清向量召回、记忆写入一致性、压缩与失效等生产要点。注意:记忆与 RAG 不同——RAG 是检索外部知识,记忆是保存 Agent 自身经历与用户偏好。
核心概念:记忆的几种形态
| 类型 | 载体 | 生命周期 | 典型用途 |
|---|---|---|---|
| 短期记忆 | LLM 上下文窗口(KV cache) | 单次会话 | 当前对话、本轮推理轨迹 |
| 工作记忆 | 图状态 / 变量 | 单次任务 | 规划中的子目标、中间结果 |
| 长期记忆-语义 | 向量库 / KV | 跨会话持久 | 用户偏好、事实、知识 |
| 长期记忆-情节 | 向量库 / 日志 | 跨会话持久 | 过去任务轨迹、错误案例 |
记忆 ≠ RAG
RAG 检索的是「外部权威知识库」(如文档);记忆保存的是「Agent 或用户自身产生的经验与偏好」。两者底层都可用向量库,但语义与安全边界不同:记忆可能含 PII,需更严格的访问控制。
架构与原理
写入流程:任务进行中把中间状态放工作记忆;任务结束或关键信息出现时,抽取要点写入长期记忆(语义/情节)。读取流程:每轮把「与当前任务最相关的长期记忆」通过向量召回注入上下文(类似 RAG 但来源是自身经历)。
生产实践:向量召回记忆
长期记忆通常用向量库(pgvector / Milvus 等,见 ../vector/vector-db-overview)。核心是「写入时 embedding,读取时相似性 top-k」。
python
# memory_store.py —— 记忆存取示意 [未实测]
import hashlib
from openai import OpenAI
client = OpenAI()
def embed(text: str) -> list[float]:
r = client.embeddings.create(model="text-embedding-3-small", input=text) # [版本相关]
return r.data[0].embedding
def write_memory(text: str, kind: str):
vec = embed(text)
# 伪:写入 pgvector / Milvus,带 kind 与 timestamp 字段
db.insert({"vec": vec, "text": text, "kind": kind})
def recall(query: str, top_k=5, kind=None) -> list[str]:
vec = embed(query)
hits = db.search(vec, top_k=top_k, filter={"kind": kind} if kind else None)
return [h["text"] for h in hits]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
记忆写入要防「污染」
若把未过滤的模型输出或工具返回直接写进长期记忆,错误信息与注入内容会被反复召回,越用越错。对策:写入前做校验/人工确认;对来源标注「可信度」;定期清理低质量记忆。
操作步骤 / 配置
bash
pip install pgvector openai # 向量库 + embedding [版本相关]1
sql
-- pgvector 示例表(示意)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE memory (
id bigserial PRIMARY KEY,
text text,
kind text,
embedding vector(1536) -- 维度与 embedding 模型一致 [版本相关]
);
CREATE INDEX ON memory USING ivfflat (embedding vector_cosine_ops);1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
验证
- 召回准确性:构造「已知偏好」后新开会话提问,确认能召回该偏好。
- 隔离性:不同用户记忆互不可见(tenant_id 过滤),避免越权读取。
- 压缩率:长会话压缩后端到端任务成功率不应明显下降。
回滚 / 清理
- 记忆是状态数据,回滚需「按 tenant / 时间」删除错误批次,而非整体回退。
- 用户注销或合规删除(如 GDPR「被遗忘权」)必须能精确擦除其记忆行。
- 定期清理过期/低置信度记忆,控制存储与召回噪声。
故障排查
- 召回无关内容:embedding 模型与查询域不匹配,或 top-k 过大引入噪声。对策:调小 top-k、加重排序(rerank)。
- 上下文溢出:召回过多记忆撑爆窗口。对策:摘要化 + 预算上限。
- 写入漂移:语义记忆被情节内容污染。对策:kind 分表 + 写入校验。
安全与合规
- 数据泄露:记忆库含用户 PII,召回后可能跨用户泄露。对策:tenant 隔离 + 严格访问控制 + 输出扫描。
- 提示注入:被召回的记忆文本可能含注入指令。对策:记忆内容标记为不可信数据。
- 越权篡改:攻击者伪造记忆写入。对策:写入鉴权 + 来源签名。
- 成本失控:每次召回都带 embedding 与向量检索开销,高频调用需缓存与批处理。
成本 / 性能
记忆系统的边际成本主要在 embedding 与向量检索。以 text-embedding-3-small(1536 维)为例,embedding 单价约 $0.02/MTok [版本相关];向量检索本身毫秒级。真正的开销是「每轮都召回并注入上下文」带来的输入 token 增长——需靠摘要与 top-k 控制。性能上,向量检索 p99 通常 < 50ms,瓶颈在 LLM 上下文变长后的推理延迟。建议:对稳定记忆做 Prompt Caching,对冷启动用少而精的 top-k(3–5)。