Agent AtlasAI Agent 知识库
04.01记忆与知识 · Memory & Knowledge

记忆系统设计

工作记忆、情景记忆、语义记忆与程序记忆;写入、检索、整合、遗忘的完整生命周期。

上下文窗口是内存,记忆是硬盘。没有好的写入与检索策略,硬盘越大,噪声越多。

记忆不等于「把历史存起来」

一个常见的错误做法是:把所有对话存进向量库,每次检索 top-k 塞回上下文。结果:

  • 检索到大量寒暄和重复内容;
  • 旧偏好覆盖新偏好;
  • 敏感信息被反复带出;
  • 上下文膨胀,模型反而更糊涂。

记忆系统要回答四个问题:存什么、怎么存、何时取、何时忘。

四类记忆

类型内容存储例子
工作记忆当前任务的目标、计划、观察上下文 / State「正在核对第 3 张发票」
情景记忆具体发生过的事事件表 + 向量「上次用户要求用英文回复」
语义记忆事实、偏好、领域知识结构化表 + 向量「用户偏好顺丰,不接受放门口」
程序记忆做事的方法、技能提示模板 / 工作流「退款必须先查政策再确认金额」

工作记忆由上下文工程管理;后三类是长期记忆,需要独立的生命周期。

生命周期

图 1 · 记忆的生命周期
01写入抽取事实、偏好、事件,去重、脱敏
02整合合并重复、解决冲突、建立关系
03检索按相关性、时效、重要性取用
04遗忘过期、低价值、用户要求删除

大多数团队只做了「写入」和「检索」,忽略了整合与遗忘,结果记忆库逐渐腐化。

存什么:从对话中抽取结构化记忆

不要直接存原始对话。先抽取成原子事实:

json
{
  "type": "preference",
  "key": "shipping.carrier",
  "value": "顺丰",
  "confidence": 0.9,
  "source": "conversation:2026-10-12#msg_18",
  "observed_at": "2026-10-12T10:32:00Z",
  "scope": "user:u_123",
  "sensitivity": "low"
}

字段解释:

  • type:preference / fact / episode / procedure;
  • key:可合并的语义键,避免同义重复;
  • confidence:模型抽取的置信度,低置信度不直接生效;
  • source:可追溯,出错时能回查;
  • observed_at:时效判断;
  • scope:用户、租户、项目,防止串数据;
  • sensitivity:决定是否允许写入、是否需要脱敏。

对情景记忆,可以存摘要而不是全文:

json
{
  "type": "episode",
  "summary": "用户投诉配送延迟,最终补偿 20 元优惠券",
  "outcome": "resolved",
  "lesson": "该用户对时效敏感,后续优先发顺丰",
  "at": "2026-10-20"
}

怎么存:组合多种存储

存储适合不适合
关系库精确字段、偏好、权限、审计语义相似检索
向量库语义回忆、文档片段精确匹配、数值范围
图数据库实体关系、多跳推理简单键值查询
对象存储原始对话、文件、附件低延迟查询

生产系统通常是组合:

text
用户偏好      → PostgreSQL(key-value + 版本)
历史事件      → 事件表 + 向量索引(摘要)
领域知识      → 文档库 + 向量 + 倒排
实体关系      → 图(可选)
原始会话      → 对象存储(保留 N 天)

检索时先用结构化过滤缩小范围,再做语义检索,最后按规则排序。

写入策略:不是每句话都值得记住

一个实用的打分:

text
importance = 0.4 × 新颖性
           + 0.3 × 与目标的相关性
           + 0.2 × 用户明确表达
           + 0.1 × 情绪强度

低于阈值的内容不写入长期记忆。写入前还要:

  1. 去重:相同 key 的旧值合并或覆盖;
  2. 冲突检测:新偏好与旧偏好矛盾时,保留时间更新、置信度更高的,并记录变更;
  3. 脱敏:手机号、地址、证件号按策略处理;
  4. 可撤销:记录来源,用户要求删除时能定位。
不要把所有对话直接灌进向量库

这会让检索结果充满寒暄、重复和过时信息。长期记忆应该是「提炼后的状态」,不是「聊天记录备份」。

检索:相关性不是唯一维度

一个好的记忆检索分数:

text
score = 0.55 × 语义相关
      + 0.20 × 时效(越近越高)
      + 0.15 × 重要性
      + 0.10 × 使用频率

然后再做:

  • scope 过滤:只取当前用户/租户;
  • 类型过滤:当前任务需要偏好还是事实;
  • 冲突消解:同一 key 只保留最新有效值;
  • 预算截断:最多取 N 条、M 个 token。

只按向量相似度取 top-k,常见问题是「语义相近但已经过时」的记忆被反复召回。

遗忘:记忆系统最重要的功能

没有遗忘,记忆会变成负担。策略:

策略说明
TTL临时偏好、会话上下文 7–30 天过期
衰减长期未使用的记忆权重下降
容量上限每个用户最多 N 条,超出按分数淘汰
用户删除提供「忘记我」接口,级联删除向量与原文
冲突覆盖新事实替代旧事实,旧版本标记失效
敏感隔离高敏感记忆单独存储,更短保留期

「用户要求删除」不是可选功能。记忆里可能包含地址、偏好、健康信息,必须有删除与导出能力。

一个最小实现

python
def remember(user_id: str, text: str, kind: str = "fact"):
    extracted = extract_memory(text)  # LLM + Schema
    if extracted.confidence < 0.6:
        return None
    if extracted.sensitivity == "high":
        text = redact(extracted.value)

    existing = db.find_memory(user_id, extracted.key)
    if existing and existing.value == extracted.value:
        db.touch(existing.id)
        return existing.id

    mem = db.upsert_memory(
        user_id=user_id,
        key=extracted.key,
        value=extracted.value,
        kind=kind,
        confidence=extracted.confidence,
        source=extracted.source,
        observed_at=now(),
    )
    vector.upsert(mem.id, embed(extracted.summary), metadata={"user_id": user_id, "kind": kind})
    return mem.id


def recall(user_id: str, query: str, limit: int = 5):
    hits = vector.search(embed(query), filter={"user_id": user_id}, top_k=limit * 3)
    scored = []
    for h in hits:
        mem = db.get_memory(h.id)
        if not mem.active:
            continue
        score = 0.55 * h.score + 0.20 * recency(mem.observed_at) + 0.15 * mem.importance
        scored.append((score, mem))
    scored.sort(reverse=True, key=lambda x: x[0])
    return [m for _, m in scored[:limit]]

记忆的评估

  • 召回率:该记住的是否记住了?(写入测试)
  • 准确率:检索出来的记忆是否相关?(检索测试)
  • 时效性:是否用了过时偏好?
  • 冲突率:同一事实是否存在多个矛盾版本?
  • 污染率:是否检索到其他用户/租户的数据?
  • 删除有效性:删除后是否还能被检索到?

构造测试集:给 Agent 一段多轮对话,埋入 10 条应记住的事实和 10 条不应记住的噪声,然后在新会话中提问,看它能否正确回忆。

反模式

记忆没有作用域

所有用户共享一个向量库,检索时不加 user_id 过滤。轻则答错,重则泄露隐私。

用模型判断「是否重要」但不校验

模型可能把寒暄记为重要偏好。写入前用规则 + 置信度阈值,并允许人工抽检。

只增不删

记忆库越来越慢、越来越吵。必须有 TTL、容量上限和删除接口。

把原始对话当记忆

检索到三页聊天记录,模型要从里面找一句话。应该存提炼后的原子事实。

检查清单

  • 区分工作记忆与长期记忆
  • 记忆有类型、key、来源、时间、置信度
  • 写入前做去重、冲突检测、脱敏
  • 检索有 scope 过滤与多维排序
  • 有 TTL、衰减、容量上限、用户删除
  • 记忆可追溯、可审计
  • 有召回率、准确率、污染率测试
  • 跨用户/租户严格隔离

小结

  • 记忆不是聊天记录备份,而是提炼后的状态。
  • 四类记忆对应不同存储与检索方式。
  • 写入要有门槛,检索要多维排序,遗忘要可执行。
  • 隐私与作用域隔离是底线。
  • 用测试集验证「该记住的记住了,不该用的没用」。

下一篇进入 RAG:当记忆来自外部文档时,如何把检索做对。

读完了?进度会保存在本地浏览器。
内容会持续修订。发现错误或想补充,欢迎反馈。 遇到问题?查排查手册 →