上下文一长就忘事?万字长文教你构建Agent“工作台便签+档案柜”记忆系统
03 记忆系统怎么分层作者利威尔xu | CSDN 专栏《Agent 工程方法论》你好我是利威尔xu。咱们继续《Agent 工程方法论》这个专栏。前两篇讲了循环怎么跑、工具调用怎么不乱路线也再帮你捋一遍循环怎么跑 → 工具调用怎么不乱 → 记忆怎么分层 → 规划与任务分解 → 多智能体协作 → 可观测性与评估番外做面试突击。六篇正文走完Agent 从能动起来到手脚听使唤再到脑子里有账最后能看得见、评得出。上一篇把工具箱配好了参数有人验权限有人管失败还能重试。手脚听使唤了接下来得让它记事。工具稳了下一个翻车点就是记性上下文一长就忘事重要信息留不住垃圾信息又舍不得扔。你要是正在转型 AI 应用开发或者准备大厂 AI 岗位面试这一篇一定别跳。觉得这条路线对你有用欢迎点赞、收藏、关注利威尔xu咱们一篇一篇把工程细节啃下来。工作台上的便签短期记忆怎么管你在工作台上干活眼前通常会贴几张便签客户刚交代的要求、这一步算出来的数字、马上要用的电话号码。便签离眼睛最近拿起来快但桌面不能无限贴。贴满以后你要么撕掉没用的要么把重要内容抄进档案柜不然新便签没地方放。Agent 的短期记忆就是这张工作台。当前对话、最近几轮 Thought、Action、Observation、正在处理的目标都属于短期上下文。它的优势是读取快、格式简单缺点是受上下文窗口限制。模型不是记得越多越聪明塞进一大堆历史聊天反而会把真正重要的要求埋掉。上下文窗口管理核心不是机械地从前往后截断而是先给内容分层。用户当前目标和硬约束要留着最近几步工具结果要留着已经完成且不会再影响决策的内容可以压成摘要更早的闲聊直接淘汰。你还可以给每条记忆加重要度和过期时间让系统知道哪些便签是今天必须盯着的哪些明天就能扔。面试官可能追问什么上下文窗口快满了你会怎么处理可以回答保留目标、约束和最近状态对历史轨迹做结构化摘要把可恢复的原文放到长期存储再按需取回。别只说截断截断是止血不是记忆管理。档案柜里的文件长期记忆存什么工作台便签解决眼前的活儿档案柜解决跨天、跨周还要用的东西。比如客户喜欢什么格式、某个项目已经做过哪些决策、团队约定的发布流程这些内容今天不用过几天还可能派上用场。把所有聊天全文塞进柜子也不行柜子会很快变成杂物间真正有用的档案反而找不到。长期记忆存的不是“聊过什么”而是经过提炼、未来可能复用的事实。用户偏好、稳定身份信息、项目决策、任务经验、失败教训都可以存一次性的寒暄、没有验证过的猜测、临时计算过程就别急着归档。写入前要做提取和判断读出时还要带来源、时间和可信度。在工程上状态持久化是 harness 的职责记忆系统是 harness 里最容易被低估的模块。它不只是接一个数据库而是要管记忆什么时候写、写成什么格式、什么时候失效、被哪次任务引用过。存储只是柜子规则才是档案管理员。面试官可能追问什么什么信息适合进入长期记忆你可以按稳定性、复用价值、用户授权三个条件回答。稳定且未来可能影响决策的信息值得存临时内容和未经确认的推断不该直接沉淀还要考虑删除和纠错入口。归档和取档记忆的读写策略档案管理员不会把所有文件每天抄一遍也不会用户每说一句话就往柜子里塞一张纸。比较稳的方式是写入和读取分开设计。写入侧监听重要事件在一轮任务结束、用户明确表达偏好、系统确认关键决策时提取记忆读取侧围绕当前目标检索只拿和这次活儿相关的几条。读取也不能太贪。你去档案柜找“本项目上次的接口约定”不需要把客户三年前的午餐偏好一并抱出来。每条候选记忆可以按语义相关度、时间新鲜度、来源可信度和任务重要度打分超过阈值才注入当前上下文。注入之后还要告诉模型这些内容来自哪里避免它把旧偏好当成用户刚刚说的话。recent context.load_recent(limitwindow_budget) important memory.extract_stable_facts(recent) for item in important: if item.authorized and item.confidence 0.8: memory.upsert(item.key, item.value, item.source) query state.goal state.constraints candidates memory.search(query, top_k8) ranked rank(candidates, freshnessTrue, trustTrue) selected ranked.filter(lambda item: item.score 0.7) state.inject_memory(selected, labelretrieved_memory) state.trim_context(keep[goal, constraints, recent_state]) state.persist()这段伪代码里写入不是每句话都存读取也不是把柜子搬空。upsert负责同一件事别反复建档rank负责挑相关内容inject_memory给模型打标签trim_context再给工作台腾空间。读写策略一旦混在 Agent 主循环里后面很容易变成一团谁都不敢改的逻辑。工作台快贴满的时候裁剪也得有个固定动作大概长这样budget context.measure_budget(window_limit) must_keep context.keep([goal, constraints]) older context.take_older_trajectory(count6) summary summarize(older, keep[decisions, limits, todos]) ref_id memory.archive(older, summarysummary) context.rebuild(headmust_keep, tailrecent_steps) context.attach_summary(summary, refref_id) context.enforce_budget(budget) state.persist()算预算、留目标、压摘要、存原文、重拼上下文这几步连起来短期记忆才不会一满就硬截断。面试官可能追问什么记忆应该在什么时候写入别答“每轮都写”。更稳的回答是围绕稳定事实、用户明确偏好和已确认决策触发写入低置信度内容先进入候选区经过后续确认再升级成正式记忆。便签满了怎么办淘汰机制工作台每天都会产生新便签旧便签不能全留。最简单的淘汰是按时间扔最容易出问题因为一年前的合同约束可能比昨天的闲聊重要得多。更靠谱的做法是综合看最后访问时间、访问次数、重要度、过期时间和当前任务相关性。短期上下文可以采用滑动窗口加摘要最近几轮保留原文较早内容压成一份状态摘要长期记忆则可以做分层淘汰临时记忆过期自动清理低频且低价值的记忆降级冲突或过时的内容标记失效而不是直接物理删除。这样出了问题还能追溯知道模型为什么拿到了那条旧信息。这里有个坑摘要不是越短越好。把“客户要求周五前上线但不接受周末发布”压成“客户有上线要求”关键约束就丢了。摘要必须保留目标、限制、决定和未完成事项不能只追求字数少。面试官可能追问什么你会用什么淘汰策略可以说短期用窗口加摘要长期按重要度、时效、访问频率和任务相关性综合打分再配合过期和失效标记。要补一句删除前保留可追溯记录方便排查记忆污染。柜子里的索引向量检索怎么接档案柜文件一多光靠文件名找不够。你记得“上次那个支付超时的处理办法”却未必记得文档标题这时就需要索引。向量检索做的就是把问题和记忆变成能比较的表示再找语义上相近的内容。不过向量相近不等于真的该拿出来。用户问“这次退款能不能做”检索结果可能找到旧项目的退款规则但旧规则已经失效或者根本不是同一个租户。向量检索负责召回权限过滤、时间过滤、来源校验和重排负责把关。别把向量数据库当成记忆系统本身它只是档案柜里的一种查找手段。向量检索接入 Agent 时查询词也不能只拿用户原话。可以把当前目标、最近状态、实体范围、时间范围拼成检索请求再过滤租户和权限召回后重排最后只注入少量高相关结果。检索不到时要允许返回空不要为了填满上下文硬塞相似内容。面试官可能追问什么记忆检索和 RAG 有什么区别RAG 主要面向外部知识库目标是给当前问题找证据记忆主要面向 Agent 或用户在任务过程中的历史状态和个性化事实。两者都能用向量检索但数据生命周期、权限、写入来源和更新方式不一样不能混成一个池子。两张便签打架记忆冲突怎么处理档案柜里可能有两份文件一份写着客户喜欢 Markdown另一份写着客户最近要求用 Excel。别让师傅随便拿一份就开干要看时间、来源和适用范围。记忆冲突处理也是这个道理旧信息和新信息打架时不能只看相似度。冲突处理可以按来源可信度、时间新鲜度、作用范围和明确程度排序。用户刚刚明确说的偏好通常比半年前从聊天里推测出的偏好优先同一项目的规则通常比另一个项目的经验优先系统确认过的事实通常比模型猜出来的事实优先。实在判断不了就把冲突暴露给模型或用户确认别替用户拍板。记忆更新最好保留版本和失效关系而不是直接覆盖。比如把旧偏好标成 superseded记录新偏好的来源和时间。这样既能避免旧内容继续被召回也能在用户改口时知道该修哪条。面试官可能追问什么新旧记忆冲突时你怎么选按来源、时间、范围、置信度做排序优先使用用户明确确认且更近的内容无法判断时请求澄清并把旧记忆标记失效不要静默覆盖。记忆和上下文怎么配合便签和档案柜不是两套互不相干的东西。便签是当前工作区档案柜是可检索的外部记忆。每次接单时先把用户目标和约束放到工作台再从档案柜取少量相关资料任务推进过程中新的决定先留在便签上等确认稳定之后再归档。这样模型既不会忘掉眼前的活儿也不会被历史资料压住。真正送进模型的上下文可以拆成几层系统规则、用户当前目标、当前任务状态、最近工具轨迹、检索到的记忆。每层都要有明确标签和预算记忆不能覆盖当前用户的直接指令旧档案不能绕过权限也不能把猜测包装成事实。上下文管理的本质是让模型在有限窗口里拿到当前决策真正需要的信息。便签和档案柜配合得好干活时眼前清爽、要用时随手能取配合不好就是桌上堆满杂物、柜子却锁着找不到钥匙。你可能会问记忆越多是不是 Agent 越聪明不是。记忆的价值不在于存得多而在于关键时刻取对。存错、取错、冲突不处理比没有记忆更危险因为模型会把错误历史当成自己的经验继续放大。面试官可能追问什么如果记忆注入后影响了用户当前指令怎么办当前明确指令优先记忆只能作为参考所有注入内容要有来源和标签必要时让模型说明依据并在评估里专门测记忆污染和错误召回。聊到这儿第三篇的活儿就干完了。你现在知道了短期记忆不是无脑堆上下文长期记忆也不是接个向量库就结束。工作台要有预算档案柜要有索引归档要有门槛取档要有权限冲突还得有人裁决。下一篇咱们讲规划与任务分解。记性有了工具也稳了遇到一个大活儿还不能一头扎进去得知道怎么拆、怎么排、哪一步失败后换路线。到时候咱们把 Agent 从“能干活”继续推到“会安排活”。整个专栏的核心价值还是那句话让 Agent 从 demo 跑起来到线上稳下来再到面试时讲明白。我是利威尔xu如果你正在补 Agent 工程能力点赞收藏一下顺手关注下一篇咱们继续把这条路线往前推。 本章面试要点记忆分层短期记忆服务当前任务长期记忆保存稳定事实和可复用经验别把所有聊天全文都当记忆。淘汰策略短期用窗口加摘要长期综合重要度、时效、访问频率和任务相关性并保留失效记录。检索与注入向量检索负责召回权限、时间、来源和重排负责把关注入模型时要带标签和来源。记忆冲突处理按来源、时间、适用范围和置信度判断无法确认就澄清旧内容标失效而不是静默覆盖。记忆和上下文配合当前目标和明确指令优先记忆只做参考工作台保留当前状态档案柜按需取回。记忆和 RAG 的区别RAG 偏外部知识证据记忆偏历史状态和个性化事实生命周期、权限和写入来源都不同。