AI Agent 工程实践(03):Memory 设计——Agent 到底应该记住什么?

发布时间:2026-07-09

标签:AI Agent|LLM|Memory|上下文工程|工程实践


系列导航

上一篇:AI Agent 工程实践(02):为什么 Rules 要分层?

下一篇:待定(Review 机制 / Benchmark / Audit Trail)

本文是 AI Agent 工程实践 系列的第 03 篇。


给 Agent 加上"记忆"那天,我以为它会变聪明。

结果三天后,它开始答非所问:记得住我上周随口提的一句玩笑,却忘了当前任务的关键约束。

我一度以为是模型不行,直到翻了它的上下文------里面塞满了几百条"记忆",真正有用的不到一成。

问题不是它记得太少,而是它什么都记,于是什么都没记住

本文你将学到

  • ✓ 为什么"给 Agent 加记忆"经常让它更笨,而不是更聪明
  • ✓ 短期 / 工作 / 长期 / 归档:记忆到底该分几层,各层边界在哪
  • ✓ 项目记忆 vs 用户记忆------为什么必须拆开,混在一起会怎样
  • ✓ Memory 的完整生命周期:什么时候写、什么时候晋升、什么时候清理

适合阅读

  • ✓ 正在给 Agent / Copilot 做"记忆"功能的开发者
  • ✓ 用 Claude Code / Cursor / LangGraph 且被"上下文越来越乱"困扰的人
  • ✓ 对"上下文工程(Context Engineering)"感兴趣的人

问题背景

系列第 02 篇 里,我讲了 Rules 怎么分层------那解决的是"规则该在什么时候出现"。这一篇讲一个更棘手的问题:记忆该记什么、记多久。

几乎所有 Agent 框架都在宣传"我们有 Memory"。教程也都在教你怎么"把历史对话存起来,下次再喂回去"。听起来很美好------Agent 有了记忆,就像人一样能积累经验。我照做了。然后遇到一连串问题:

上下文越来越臃肿。 每开一次对话,Agent 先"回忆"一大堆历史,token 消耗蹭蹭涨,响应越来越慢。

关键信息被稀释。 当前任务真正需要的那几条,淹没在几百条陈年记忆里。模型的注意力被无关信息分走,输出质量反而下降。

旧信息污染新决策。 上个项目用的是 FastAPI,这个项目用 Flask,可它"记得"FastAPI,于是不停给我推 FastAPI 的写法。

记忆之间开始打架。 我三个月前说"喜欢详细注释",上周又说"代码尽量精简"。两条都被记着,Agent 到底该听谁的?

一句话概括:加了记忆,Agent 没变聪明,反而被自己的记忆拖垮了。 这不是"有没有记忆"的问题,是"怎么管理记忆"的问题------和 Rules 分层一样,本质是规模问题

错误尝试

第一次尝试:什么都记,全量回灌

最朴素的想法:把所有历史对话都存下来,下次对话时全部塞回上下文。"记得越多越聪明"嘛。

结果:上下文迅速膨胀到几千 token 起步。更糟的是,模型在长上下文里出现了典型的"迷失在中间"(Lost in the Middle)现象------放在开头和结尾的信息还记得,夹在中间的关键约束直接被忽略。

记得多 ≠ 用得上。

第二次尝试:只留最近 N 条(滑动窗口)

既然全量太重,那就只保留最近 20 条消息,老的丢掉。简单粗暴。

结果 :短期是清爽了,但把"这个项目用红涨绿跌配色"这种说过一次、长期有效 的关键约定也一起丢了。过几轮它又开始问"配色用什么"。滑动窗口砍掉的不是噪声,是按时间一刀切,而重要性和时间根本不成正比。

两次尝试指向同一个教训:记忆的问题,不能用"记多少"来解决,要用"怎么分类、怎么流转"来解决。

关键观察

我把 Agent 一周的上下文导出来做了个统计,按"这条信息在后续任务里被真正用到"来分类:

记忆类型 举例 后续被用到的比例
当前任务上下文 正在改的文件、当前报错 ~95%
项目级约定 技术栈、目录规范、命名 ~70%
用户长期偏好 语言、代码风格、汇报格式 ~60%
一次性事实 某次临时路径、搜索结果 ~3%
闲聊 / 情绪 随口的玩笑、寒暄 ~1%
pie title Agent 上下文里的信息价值分布 "高频复用(值得长期记)" : 20 "当前会话有用(用完即弃)" : 25 "噪声(记了反而添乱)" : 55

记住一切,等于什么都没记住。

超过一半的"记忆"是一次性的噪声,把它们和真正的长期约定平等地塞进上下文,就是在稀释注意力。

定位真正原因

问题不在"记得多少",而在所有记忆被平等对待、生命周期完全相同:一次性的临时路径和"这个项目用 Flask"这种长期约定,被存在同一个地方、同样长久地活着、同样默认加载。

正确思路是给记忆分层,让不同价值的信息走不同的"寿命"和"加载策略":短期记忆用完即弃,长期记忆按需晋升,噪声定期清理。

这其实和上一篇的 Rule RAG 是同一个哲学:不在推理时把所有东西硬塞给模型,而是让对的信息在对的时候出现。 Rules 管的是"规则何时出现",Memory 管的是"记忆何时出现"------两者都是**上下文工程(Context Engineering)**的一部分。

最终方案:四层记忆 + 生命周期

我把记忆拆成四层,每层有不同的存活时间和加载策略:

层级 存什么 生命周期 是否默认加载
Conversation(对话层) 当前对话的原始消息流 会话内,session 结束即弃 是(但滚动裁剪)
Working Memory(工作记忆) 本次会话提炼的关键状态、当前任务进度 单次会话 是(精简版)
Long Memory(长期记忆) 跨会话的持久约定:项目记忆 + 用户记忆 长期,可更新 按需检索
Archive(归档层) 冷数据、历史日志、过期记忆 永久但压缩 否,仅显式检索

信息在这四层之间单向流动 + 定期回收:新信息先进对话层,被判定为"有长期价值"才晋升到长期记忆,长期记忆里过时的再降级到归档。

长期记忆为什么要拆成"项目"和"用户"

这是最容易被忽略、也最关键的一刀。很多 Agent 把两者混成一个大 memory,于是换个项目就开始串味。

  • 项目记忆(Project Memory) :只在当前项目生效。技术栈、目录规范、命名约定、这个项目特有的坑。换项目就不该带过去。
  • 用户记忆(User Memory) :跟着走、跨所有项目。语言偏好、代码风格、汇报格式、工作习惯。

判据很简单:问一句"换个项目还成立吗?" 成立的进用户记忆,不成立的进项目记忆。"我喜欢中文回复"是用户记忆;"这个项目用红涨绿跌"是项目记忆。分开存,才不会拿 A 项目的约定去污染 B 项目。

实际收益

指标 全量回灌 分层 + 生命周期
每次对话默认加载的记忆量 全部历史(数百条) 精简工作记忆 + 3 条常驻(个位数)
换项目时的串味 频繁(旧栈污染新项目) 基本消除(项目记忆隔离)
关键长期约定的存活 易被滑动窗口误删 稳定(晋升到长期层)
上下文噪声占比 ~55% 显著下降(噪声不晋升)

数据来自主观经验估算,不是严格 A/B Test,但反映了分层前后的量级差异。

架构图 / 流程图

记忆的四层流动

关键点 :越往下越持久、越精炼;只有对话层是易失的,其余都要落盘。晋升(promotion)是主动决策,不是自动全存。

记忆的生命周期(状态流转)

图片多样性:这里用了 Mermaid 的 pie / flowchart / stateDiagram 三种图;实际发文时可再补一张 ProcessOn/draw.io 版的四层示意图,进一步提升 CSDN 图片多样性得分。

代码或配置示例

记忆的目录结构

我把落盘的记忆按"归属"组织,一眼就能看出哪些跟人走、哪些跟项目走:

bash 复制代码
# 用户级(跨项目,跟人走)
~/.agent/
└── MEMORY.md                 # 用户长期记忆:语言、风格、习惯
项目级(仅当前项目)
<project>/.agent/memory/
├── MEMORY.md                 # 项目长期记忆:技术栈、规范、约定(精炼)
├── 2026-07-09.md             # 每日工作日志(append-only,短期→归档)
└── archive/                  # 归档层:过期日志压缩沉淀

记忆管理策略(YAML 配置)

用配置显式声明每层的寿命和晋升条件,而不是让它们"自然生长":

yaml 复制代码
# memory-policy.yaml --- 记忆生命周期策略

conversation:
  scope: session          # 会话内有效
  max_messages: 30        # 滚动裁剪,超出丢弃
  persist: false          # 不落盘

working_memory:
  scope: session
  persist: false
  distill: true           # 会话结束前蒸馏关键状态,决定是否晋升

long_memory:
  project:                # 项目记忆
    scope: project        # 仅当前项目生效
    max_chars: 3000       # 超出触发蒸馏压缩
  user:                   # 用户记忆
    scope: global         # 跨项目生效
    max_chars: 4000
  promotion:
    rule: "reused >= 2 OR user_explicit == true"   # 复用≥2次 或 用户明确要求 才晋升

archive:
  trigger: "not_hit_days > 30"   # 30 天未命中 → 降级归档
  compress: true
  ttl_days: 365                  # 归档超期清理

写入与晋升逻辑(伪代码)

python 复制代码
def on_new_info(info: Info, ctx: Context) -> None:
    """一条新信息进来时的处理"""
    # 1. 一律先进对话层
    ctx.conversation.append(info)
    # 2. 与当前任务相关 → 提炼进工作记忆
    if relevant_to_current_task(info, ctx.task):
        ctx.working_memory.upsert(info)

def on_session_end(ctx: Context) -> None:
    """会话结束时决定谁能"活下来" """
    for item in ctx.working_memory:
        if should_promote(item):                 # 复用≥2 或 用户明确要求
            target = "user" if is_cross_project(item) else "project"
            long_memory.write(item, scope=target)   # 关键:分流到项目/用户
    # 对话层直接丢弃,不落盘

def cleanup(long_memory: LongMemory) -> None:
    """定期清理:去重、降级、蒸馏"""
    long_memory.dedup()                          # 合并重复/冲突项,保留最新
    for item in long_memory.stale(days=30):
        archive.move(item)                       # 长期未命中 → 归档
    if long_memory.over_limit():
        long_memory.distill()                    # 超出容量 → 蒸馏压缩

代码不多,但把三个动作说清楚了:分流写入、按条件晋升、定期清理。 这三个动作缺一个,记忆迟早失控。

设计权衡

候选方案 优点 缺点 为什么不选
全量回灌历史 实现最简单,"绝不遗漏" 上下文爆炸、迷失在中间、噪声稀释注意力 记得多不等于用得上,规模一大必崩
滑动窗口(只留最近 N 条) 上下文恒定、实现简单 按时间一刀切,误删长期约定 重要性和时间不成正比,砍错了对象
全部塞向量库,用时检索 容量无上限、语义召回 召回噪声多、无生命周期、冷热不分 只解决"存",没解决"该不该记、记多久"
四层 + 生命周期 冷热分层、项目/用户隔离、可晋升可清理 需设计晋升与清理策略 选择理由:唯一同时管住"记什么、记多久、给谁"的方案

分层不是越多越好。 如果你的 Agent 只是个单轮问答机器人,压根不需要跨会话记忆------一个滑动窗口就够了。不要在不需要长期记忆的地方强行搭四层。 向量检索也不是对立面:它可以作为 Archive 层的召回手段,和分层是互补而非二选一。

总结

  • ✅ 记忆的问题不是"记多少",而是"怎么分类、怎么流转"------和 Rules 一样是规模问题。
  • ✅ 分四层:Conversation(易失)→ Working(会话)→ Long(持久)→ Archive(冷藏),越往下越精炼。
  • ✅ 长期记忆必须拆项目和用户------判据是"换个项目还成立吗?",否则必然串味。
  • ✅ 晋升是主动决策(复用≥2 或用户明确要求),不是自动全存。
  • ✅ 没有清理机制的记忆系统,最终都会被噪声拖垮------去重、降级、蒸馏一个都不能少。

参考资料

  • Lost in the Middle 论文(Liu et al., 2023) → 为什么长上下文里中间信息会被忽略,直接决定了"不能全量回灌"的结论
  • MemGPT: Towards LLMs as Operating Systems → 用分层记忆 + 分页调度管理超长上下文,本文四层模型的重要参照
  • Anthropic --- Claude 上下文与记忆管理文档(待补链接)→ 工作记忆与长期记忆分离的工程实践基础
  • Generative Agents (Park et al., 2023) → 记忆的"重要性打分 + 检索 + 反思"机制,启发了本文的晋升与蒸馏设计
  • PARA / Zettelkasten 知识管理法 → 用"归属"而非"时间"组织信息,是项目/用户记忆拆分的方法论来源

系列导航

相关推荐
懂懂笔记1 小时前
老龄化加速下的中国答案:东软用AI思维重构“人生下半场”
人工智能·智慧养老
GitCode官方1 小时前
基于《人工智能 智能体互联》国标的 AIP 开源项目在 AtomGit 正式开源
人工智能·开源·atomgit
万象AI实验室1 小时前
GPT-5.6 正式上线,我们挖到了 3 个隐藏玩法!
人工智能
IpdataCloud1 小时前
AI生成的Avalon恶意框架怎么防?用IP离线库识别模块化C2通信
运维·人工智能·网络协议·tcp/ip·ip
FreeBuf_1 小时前
公开GitHub Issue可诱骗AI泄露私有数据,绕过防护仅需一词
人工智能·github·issue
kiros_wang1 小时前
ExploreYC 新手快速入门与实战指南
大数据·人工智能·物联网
阿里云大数据AI技术1 小时前
Elasticsearch 智能助手:Agent 让运维从经验驱动迈向智能协同
人工智能·elasticsearch·agent
Mark0802032 小时前
人物设定生成器:小说创作中角色塑造的AI工具选择
大数据·人工智能
禾高网络2 小时前
互联网医院|AI 互联网医院成品开发系统
java·大数据·人工智能·小程序