本节摘要:本节给记忆画三层地图。第一层会话内记忆:当前对话的历史,记忆的最小形态,每轮组装进窗口、随轮线性增长,是驱逐(2.1)与压缩(6.1)的主战场。第二层跨会话记忆:用户偏好、长期事实与约定,让下一次会话"认得出人",供给时机在会话开始与关键节点,预算份额小但价值密度最高。第三层知识库:组织级长期知识(产品文档、政策、代码),全量远超任何窗口,只能按需检索供给。三层的判据仍是三问(1.2 节)——谁产生、多久有效、谁负责裁剪——由此澄清一个高频混淆:知识库本体是记忆的仓库形态,但检索结果进入窗口的那一刻,身份是素材而非记忆(口诀:库里的是记忆,窗口里的是素材)。文末给三个混层事故与 LangChain state / store 的翻译练习。记忆机制的实现纵深由 同站教程库记忆系教程承担,本节只管分层决策。
阅读完本节,你应当能够:
对"记忆"只有开关式想象的人,会在这两种事故之间摇摆:
两种事故的公共根因:把"记忆"当成一个东西。实际上窗口里的"之前发生过什么"(记忆成分)是一组生命周期完全不同的信息——当前这轮对话的来龙去脉、关于这个用户的长期事实、关于这个组织的知识,三者的时效、体量、更新频率差着数量级。分层就是按生命周期归类,再给每层配不同的供给策略:会话内靠组装与驱逐,跨会话靠写入与召回,知识库靠检索。
| 层 | 装什么 | 生命周期 | 供给时机 | 预算位置(示意) | 主要治理手段 | 详见 |
|---|---|---|---|---|---|---|
| 会话内 | 对话历史(用户 / 助手 / 工具消息) | 单会话(分钟~小时) | 每轮组装进窗口,随轮线性增长 | 10%~20% | 驱逐顺序(2.1)+ 压缩(6.1) | 第 2、6 章 |
| 跨会话 | 用户偏好、长期事实、约定 | 跨会话(月~年) | 会话开始召回一次 + 关键节点增量 | 1%~5% | 写入门槛 + 过期淘汰(4.2) | 4.2 |
| 知识库 | 产品文档、政策、代码 | 组织级(周~月更新) | 按需检索,当轮进入、当轮消耗 | 计入素材配额 | 检索质量 + 引用约束 | 第 5 章 |
读表三个结论:其一,越往下体量越大——跨会话记忆常常只有几十条(千 token 级,示意),知识库却是百万 token 级(1.1 节量级表),供给方式因此从"全量注入"退化成"按需检索"。其二,越往下更新越慢——历史每轮都在长,偏好按月变,知识库按周~月刷新;更新频率决定治理节奏。其三,只有上面两层是记忆成分的"住户"——知识库检索结果进窗口后按素材对待,这是下一节的辨析重点。
对话历史是记忆的最小形态:messages 数组本身。它的两个特性前文都立过——线性增长、永不自动收缩(1.1 容量推论),以及 pinned 四项与最近 K 轮永不驱逐(2.1)。本层的设计要点只有一句:历史不是神圣的。40 轮里的早期探索、已完成的子任务过程、已经引用化的旧工具结果,都是驱逐顺位表上的对象;真正不可丢的是任务原文与红线,而不是"发生过的一切"。压缩(6.1)则负责把这层结构性压薄。
内容三样:偏好("回复控制在三句话内""我是企业账户")、事实(会员等级、常用收货城市、历史投诉记录摘要)、约定("叫我王工""每次先对账单再谈方案")。特征是量小(几十条)、价值密度高(一条偏好影响之后每一次交互)、写少读多(一次写入,每个会话开头都读)。供给时机有两个:会话开始时一次性召回注入;会话中触及相关实体时增量召回(用户提到新话题,补召回该话题相关条目)。写入端的手艺(什么配进库、何时进、记成什么形态)是 4.2 的主题。
组织级知识——退款政策全文、产品手册、代码仓库。它和跨会话记忆一样"跨会话存在",但体量决定了它永远不能预装(1.1:一部中篇文档 50k~200k,一个代码库百万级起)。供给形态只有一种:按需检索——本轮问题需要哪两条政策,就取哪两条。这一层的全部工程(索引、检索、重排、repo map)是第 5 章的主题,也是《语义代码检索》第 5、6 章的深潜对象(纯文字互引)。
高频混淆:"我们把政策库接了记忆系统,检索结果算长期记忆吧?"——用三问实测一条"退款政策第 3 条":
| 三问 | 知识库里的条文 | 答案指向 |
|---|---|---|
| 谁产生? | 组织撰写,系统索引 | 介于"开发者 / 系统"之间——仓库形态像记忆 |
| 多久有效? | 条文本身按月更新;但进入窗口的这份副本只在当轮有效 | 副本是短时效 |
| 谁负责裁剪? | 进入窗口后由运行时策略裁(用完即逐,驱逐顺位第 1 位) | 运行时裁剪 = 素材的待遇 |
结论写成口诀:**库里的是记忆,窗口里的是素材。**知识库本体是慢变的、组织累积的仓库(记忆的第三层);检索片段一旦进入窗口,就按素材对待——时效最短、总量最大、用完就驱逐(1.2 节素材行的全部属性)。这条边界不清的后果很实际:把检索片段当记忆留在窗口里,就是 2.1 节说的"三天前 grep 到的输出还占着两万 token"。
💡 判别的快捷方式:问"这段内容下一轮还有效吗"。用户偏好下一轮有效(记忆);政策条文的本体长期有效,但本轮取回的这份副本下一轮该重新检索(素材——库存可能变了、文件可能改了)。
| 事故 | 症状 | 根因 | 修正 |
|---|---|---|---|
| 把知识库塞进跨会话记忆 | 记忆库膨胀到几千条;政策改版后模型还在引用旧条文 | 把"组织知识"当成"关于用户的记忆"逐条入库 | 库里只存索引与摘要,条文本体留知识库按需检索 |
| 把会话历史当跨会话记忆 | 新会话首轮就占 20k;模型被上一场的语境带偏 | "记住用户"被实现成"带上全部历史" | 跨会话只带会话摘要 + 抽取事实(几百 token,示意) |
| 把易变状态写进跨会话 | 用户早换了订单,模型还查旧单号 | "当前看的订单 88880"被存成长期事实 | 易变状态留在会话内;确需跨会话的加过期时间 |
三个事故的公共教训:分层不是学术洁癖,是供给策略的分发器——层定错了,后面每一层配的预算、时机、治理手段全部跟着错。
按 1.2 节的结论——读到任何框架文档,先翻译成四成分语言,再套预算恒等式:
| LangGraph 概念(官方口径) | 它是什么 | 三层语言 |
|---|---|---|
| state(thread 内,由 checkpointer 持久化) | 单线程内的会话状态与历史,可断点恢复 | 会话内记忆 |
| store(跨 thread,按命名空间隔离) | 跨会话的持久键值存储 | 跨会话记忆 |
| 检索器 / 外部知识源 | 接入 store 或独立索引的文档库 | 知识库(供给结果为素材) |
这个翻译的价值在于看出框架没替你做的事:state 不会自动驱逐旧消息,store 不会自动判断什么值得写入——分层供给的决策(本章)、驱逐与压缩的参数(第 2、6 章)仍然全部是你的。框架组件的完整对照见 7.1 节与附录 B。
地图画好了。三层里,会话内记忆的治理(驱逐与压缩)已由第 2 章立规、第 6 章收尾;知识库的供给是第 5 章整章的主题——剩下跨会话记忆的两端手艺没人管:什么信息配进库?什么时候写?召回升多少、注到哪?下一节补上这块拼图。