尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Agent 记忆系统设计:上下文窗口装不下的长期项目,什么该记住、什么该忘掉
Agent 记忆系统设计上下文窗口装不下的长期项目什么该记住、什么该忘掉前言上一篇聊部署形态结尾留了个钩子会话跨天之后记忆怎么设计。这篇把它补上。先摆一个做 Agent 绕不开的场景项目持续三周用户周一说数据库用 PostgreSQL,别用 ORM,周三的会话里 Agent 又推荐了 Prisma。它不是故意忘的——上下文窗口只保留当前对话前几天的会话早就被截断了。用户视角这叫失忆工程视角这是没有记忆层。先把两个概念切开上下文(context)这次对话的内存模型推理时真正能看到的全部内容会话结束(或截断)就没了记忆(memory)跨会话的磁盘昨天存的东西今天还在需要主动决定写什么、读什么、什么时候删。记忆系统设计的全部问题就是往这块磁盘写什么、怎么组织、什么时候读、什么时候扔。这篇文章讲我落地的分层方案从最简的 Markdown 文件到检索式记忆库再到最难的部分——写入策略。代码是 TypeScript。一、先分清三种记住不是所有记住都是同一种东西混着设计必然做砸会话内记忆。当前对话的上下文模型天然记得。要处理的只是装不下怎么办截断、压缩、摘要——这是上下文管理不是记忆系统这篇不展开工作记忆(项目状态)。跨会话但要持续更新的内容:当前进行到哪、做过什么决策、下一步是什么。特征是每条记忆都有半衰期上周的状态这周可能就作废长期记忆(稳定事实)。用户的偏好、项目的技术栈约束、踩过的坑。特征是低频写、高频读写下去基本不改。三种记住对应三种完全不同的存储和淘汰策略。工作记忆适合一个文件整体覆盖更新长期记忆适合逐条积累 检索。最常见的失败是把工作记忆塞进长期记忆库——三个月后检索回来一堆过期进度比没有记忆更糟。二、最简可用方案一个 Markdown 文件可能就够了动手上向量库之前先看看需求的真实规模。单项目、单用户的 Agent有价值的跨会话记忆通常不超过十几条技术栈约束、几个关键决策、当前进度、几条教训。这个量级一个结构化的 Markdown 文件就是最优解:# 项目记忆 ## 技术约束 - 数据库:PostgreSQL 16,禁用 ORM,统一用 Kysely - 部署:Docker Compose,单机,无 K8s ## 关键决策 - [10-12] 认证选了 session 而不是 JWT:理由是同域部署,不需要跨服务鉴权 - [10-14] 放弃微服务拆分:三人团队,拆了没法维护 ## 当前进度 - 支付回调联调中,沙箱环境返回签名偶尔校验失败(待排查) ## 教训 - 直接改 DB 数据不写迁移脚本,下次部署会丢——已经踩过一次使用方式同样简单会话开始时整个注入 system prompt,会话结束(或每完成一个里程碑)时让 Agent 输出更新后的版本整体覆盖:async function loadMemory(): Promisestring { try { return await fs.readFile(MEMORY_PATH, utf8); } catch { return 暂无项目记忆; } } async function saveMemory(content: string): Promisevoid { // 整体覆盖,不 append——过期状态靠这次写入自然消失 await fs.writeFile(MEMORY_PATH, content, utf8); }整体覆盖而不是追加是关键设计过期信息的退出机制靠重写实现不需要任何删除逻辑。Agent 每次更新时自然会把支付回调联调中替换成新状态旧的进度不会堆积。这个方案的边界也很清楚记忆条目多到全量注入会挤占上下文(经验值大约超过 4-8KB),或者多项目共享同一个记忆库需要隔离就到了换方案的临界点。三、检索式记忆什么时候该上向量库当记忆条目超出全量注入的规模——比如 Agent 服务多个项目、或者要积累用户在长期使用中的碎片事实——就该按需检索了。套路和 RAG 一样写入时嵌入查询时 top-k:interface MemoryEntry { id: string; content: string; embedding: number[]; createdAt: number; kind: fact | decision | lesson | preference; } async function recall(query: string, topK 5): PromiseMemoryEntry[] { const [qv] await embed([query]); const all await store.all(); return all .map(e ({ e, score: cosine(qv, e.embedding) })) .sort((a, b) b.score - a.score) .slice(0, topK) .map(x x.e); }但检索式记忆有三个 RAG 场景没有的坑最相似的往往不是最该用的。用户问数据库怎么连接检索召回三条连接相关的旧记忆但上周刚做过连接池从 10 调到 50的决策可能排在第五。所以排序要叠加时间权重同分近邻里新的优先甚至最近 N 天内的事实直接保送碎片事实会互相矛盾。记忆库里同时存在用户在用 Vite(三个月前)和用户迁到 webpack 了(上周)两条都高度相似。不处理冲突检索等于随机翻旧账每轮都检索是浪费。很多问题根本不涉及历史记忆。先用轻量判断(这轮对话是否涉及用户偏好/历史决策)决定要不要查而不是无脑每轮 top-5 注入——那是在用上下文预算给记忆库交税。四、写入策略比读取难一个量级读取顶多是排序问题写入是什么值得记住的判断问题这才是记忆系统的成败点。按价值分三档必记用户显式要求记住的(记住我用 pnpm)纠正性反馈(不要用 var,项目统一 const)——这类不记下个会话必然重犯值得记稳定的约束和事实(技术选型及理由、部署环境)踩坑教训(成因和规避方法都成立的)别记过程性内容(尝试了什么失败了什么)、一次性任务细节、可以被代码和文档直接查到的信息。记忆库里最没价值的就是我们讨论过 X这种会议纪要式条目。两个落地规则其一冲突用覆盖不用追加。新事实和旧事实矛盾时旧的那条必须删除或标记作废而不是两条并存。实现上给写入加一步相似检索 冲突消解新条目写入前先查 top-3,语义冲突(同一主体、相反断言)就替换。用户搬家了记忆库里只能有一个地址。其二遗忘要有机制不能靠自觉。最简单的两种:createdAt超过 TTL 且未被检索命中的条目定期清理每过一段时间(或条目超阈值时)跑一次蒸馏——让模型把几十条碎片合并成几条结构化事实比如二十条关于部署的零散记录合并成部署环境一节。蒸馏和第二节的整体覆盖是同一件事在检索式存储上的翻版给记忆一个收敛机制否则它只会单调膨胀。五、务实的分层三种存储各管一段把上面的方案叠成分层结构按记忆的性质路由| 层 | 存储 | 内容 | 读法 | 写法 | | --- | --- | --- | --- | --- | | L1 | 会话上下文 | 当前对话 | 自动 | 自动 | | L2 | 项目记忆文件 | 约束/决策/进度/教训 | 每次会话全量注入 | 里程碑时整体覆盖 | | L3 | 向量记忆库 | 碎片事实/偏好/长尾细节 | 相关时 top-k 检索 | 逐条写入冲突消解 |路由规则一句话结构化的、每次都该看的知识进 L2;零散的、按需才相关的进 L3。团队共享的项目约束写成文档和 L2 注入用户个人的使用偏好进 L3 检索——混在一起两边都做不好。一个容易忽略的点给用户看记忆、让用户改记忆。记忆错了(过期的偏好、错误的教训)比没有记忆更伤因为它会固执地影响每次会话。一个/memory命令让用户查看和编辑当前记忆是信任问题也是调试问题——记忆系统出问题时你总得有个地方看它到底记了什么。写在最后清单版总结先分清会话内/工作记忆/长期记忆,三者存储和淘汰策略完全不同;单项目先上 Markdown 文件整体覆盖,超出 4-8KB 再考虑向量库——不要一上来就 RAG;检索式记忆叠加时间权重,同分近邻新的优先;每轮检索前先判断这轮需不需要记忆;写入按三档过滤:显式指令和纠正反馈必记,过程性内容别记;冲突覆盖不追加;遗忘靠 TTL 定期蒸馏;L2 进度状态、L3 碎片偏好,分层路由;给用户一个查看和编辑记忆的入口。记忆系统做好之后你会发现下一个瓶颈是上下文本身长会话里早期内容被截断Agent 行为就开始变形——下一篇文章可能聊聊会话内的上下文管理压缩时机、摘要策略以及什么内容永远不该被压缩掉。
RELATED

相关推荐

AI生成PPT工具的几种使用路径与体验记录

AI生成PPT工具的几种使用路径与体验记录

我在处理PPT相关任务时,按公开入口体验了百度文库、Gamma和Kimi,记录不同工具在流程中的位置。以下仅为个人使用记录,不构成选择建议,产品功能以官方页面为准。 一、百度文库:素材整理与PPT生成流程记录 (一…

📅 2026/10/27 2:06:20
别让错题本变成抄题本:我给孩子用的 AI 错题本开源了

别让错题本变成抄题本:我给孩子用的 AI 错题本开源了

错题本最容易完成的一步,是把题目抄进去。最容易掉链子的一步,是过几天再拿出来,确认孩子真的会做了。 题干要抄,图要画,答案要整理;好不容易收拾干净,下次复习又得翻半天。要是同一道题再次做…

📅 2026/10/27 2:01:20
酒店客房WiFi覆盖方案怎么做?勘测、布点与验收判据

酒店客房WiFi覆盖方案怎么做?勘测、布点与验收判据

客房 WiFi 做得好不好,验收时不是看信号格数,而是看点位复测的数值和高峰期是否仍然可用。很多项目入住以后才发现问题,根子都在第一阶段:没做勘测就按经验布点,墙还没砌完就定了 AP 数量。 一、第一步:勘测…

📅 2026/10/27 2:01:20
MORE NEWS

更多资讯

📰

Kubernetes Pod Not Found报错排查:命名空间、上下文与标签选择器实战

1. 这个报错到底在说什么:从一次真实的排查现场说起Error: Pods pod-name Not Found这个提示,几乎每个跟 Kubernetes 打过交道的人都见过。它不像 CrashLoopBackOff 那样有一堆日志可以翻,也不像 ImagePullBackOff 那样指向明确,它…

📰

PostgreSQL主从流复制与pgpool-II高可用部署实战

简介:PostgreSQL 主从流复制与 pgpool-II 高可用部署文档,面向数据库运维工程师与 DBA,解决主备数据实时同步、读写分离与主库故障自动切换的问题。内容从方案综述入手,讲清主库 WAL 日志经 walsender 推送至备库 walreceiver 落盘…

📰

Java数据结构与算法分析:递归、复杂度与链表指针精解

简介:面向使用《数据结构与算法分析(Java语言描述)》第三版的学生与自学者,这份习题答案文档可用于课后对照、期末复习及算法基础查漏补缺,适合正在巩固Java数据结构、递归思想和复杂度分析的读者。压缩包内仅含1个doc…

📰

高效调试方法论:从基础工具到AI辅助的BUG终结术

1. 项目概述:为什么我们需要"BUG终结者"?在软件开发领域,BUG就像影子一样伴随着每个程序员。我见过太多团队在调试上浪费的时间甚至超过实际开发时间。最近一个统计显示,开发者平均花费25%的工作时间在调试上&#xff0…

📰

Linux标准IO库:原理、优化与实战应用

1. 为什么标准IO在Linux编程中如此重要?在Linux系统编程中,输入输出(IO)操作是最基础也是最频繁的操作之一。标准IO库(stdio)作为C语言标准库的一部分,提供了一套高效、可移植的文件和终端操作接…

📰

跨平台扫码功能实现方案与技术解析

1. 项目概述扫码功能在现代移动应用中几乎成为标配,但不同平台的技术实现差异巨大。最近我在一个跨平台项目中,需要同时在常规H5页面、微信H5、微信小程序和原生App中实现扫码功能,踩了不少坑也积累了一些经验。本文将分享四种场景下的完整实…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬