Agent 记忆体系:短期、长期与工作记忆

做 AI 面试产品时最尴尬的场景:候选人在第 3 题提过"我有 K8s 集群运维经验",第 7 题追问时,面试官(Agent)忘了——上下文太长被截断,或者被新内容挤出

Agent 的记忆不是"一个缓存",是三层体系:短期记忆(上下文窗口)、长期记忆(持久存储)、工作记忆(当前任务状态)。

一、三层记忆模型

记忆层 存什么 生命周期 实现
短期记忆 当前对话上下文 一次会话 LLM 上下文窗口
工作记忆 当前任务状态 一个任务 结构化状态(JSON)
长期记忆 用户画像、历史事实 永久 向量库 / 数据库

二、短期记忆:上下文窗口的管理

问题:上下文窗口有限(4k/32k/128k),对话越长越挤。

技术:上下文压缩

5 0 1 3 0 0
1
2
3
4
5
6
def compress_history(session):
    recent = session[-10:]                    # 原文保留
    middle = session[10:-10]
    summary = llm.summarize(middle)          # 摘要
    facts = extract_facts(session)           # 关键事实抽取
    return {"recent": recent, "summary": summary, "facts": facts}

关键事实抽取(面试场景):

1
2
3
4
{"facts": [
  {"type": "skill", "value": "K8s 集群运维", "round": 3},
  {"type": "experience", "value": "主导过 20+ 微服务迁移", "round": 5}
]}

追问时从 facts 里找,而不是翻完整历史——这就是"记得住前面说过什么"的实现。

三、工作记忆:任务状态的唯一事实源

工作记忆 = 当前任务的进行状态,必须结构化、可持久化:

1
2
3
4
5
6
7
8
9
{
  "session_id": "s-001",
  "current_step": "STEP3",
  "questions_asked": 3,
  "answers": [
    {"q": "Go GC 原理?", "a": "三色标记...", "score": null}
  ],
  "pending": "第 3 题未回答完"
}

为什么必须是结构化状态而不是自然语言

  1. 可校验(current_step == expected_step
  2. 可持久化(服务重启不丢)
  3. 可追踪(出问题能回放)
  4. 可并发(多实例共享状态)

关键:Agent 的每一轮动作前先读工作记忆,动作后更新——状态在系统里,不在模型的"记忆"里(这就是我在 Prompt 状态机里讲的原则)。

四、长期记忆:跨会话的积累

存什么

怎么存

怎么用

" + X 3 X "

长期记忆的价值:AI 面试官第二次面试同一个候选人时,记得上次的表现——这是"像个真人面试官"的关键。

五、记忆的一致性问题

问题 1:短期和长期不一致

会话中候选人说"我熟悉 Rust",会话结束时写入长期记忆——但中途 Agent 的回答可能已经用了旧画像。

解法长期记忆只在会话结束(或关键节点)写入,会话中短期记忆为准。

问题 2:记忆污染

候选人的随口一提(“我了解一点 Rust”)被当成"精通 Rust"写进画像。

解法:写入长期记忆要过置信度门(确认/重复/关键上下文才写),别啥都存。

问题 3:隐私

长期记忆存了用户隐私,删除/导出要支持。

解法:记忆数据与用户账号绑定,提供查看/删除接口(合规必备)。

六、架构总览

A g e n t + + / / J S O N R e d i s / D B
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 每轮循环
def agent_loop(session, user_msg):
    # 1. 读工作记忆 → 当前状态
    state = load_state(session.id)
    # 2. 检索长期记忆 → 相关画像
    profile = memory.search_profile(session.user_id)
    # 3. 组装上下文(短期压缩 + 事实 + 状态 + 画像)
    ctx = build_context(session, state, profile)
    # 4. LLM 调用
    reply = llm.chat(ctx)
    # 5. 更新工作记忆
    save_state(session.id, update(state, reply))
    return reply

七、踩坑记录

  1. 压缩摘要失真:摘要丢细节(“用户问过 GC 但没深入”)→ 事实抽取用结构化,不依赖摘要
  2. 工作记忆和上下文不同步:状态说 STEP3,上下文显示 STEP2 → 每轮结束强制校验一致性
  3. 长期记忆写入过频:每轮都写画像 → 记忆被噪音污染 → 只写"高置信度事实"
  4. 记忆检索成本:每轮都查向量库 → 慢 → 画像缓存在工作记忆,变化才回写

总结

Agent 记忆的核心认知:

  1. 三层分工:短期管上下文、工作管任务状态、长期管跨会话积累
  2. 上下文压缩 + 事实抽取:让 Agent"记得住"前面的关键信息
  3. 状态放系统不放模型:工作记忆结构化,可校验可恢复
  4. 长期记忆要过置信度门:别让随口一提污染画像

Agent 没有记忆 = 每轮都是新同事。 有了三层记忆体系,它才像那个"了解你"的老熟人。