第九章 记忆与上下文工程¶
导读¶
LLM 上下文窗口有限(GPT-4 是 128K,Claude 3 是 200K,再大也不是无限),Agent 跑多步任务时上下文会爆——历史 Thought/Action/Observation 累积、工具返回结果累积、用户多轮对话累积,几步下来 token 就超。Agent 必须有记忆系统——把"现在用不上的信息"挪出 context window,需要时再调回。本章建立 Agent 记忆系统的三层心智模型:短期记忆(context window 里的当前对话与工具历史)、工作记忆(中间摘要与正在推理的子问题)、长期记忆(向量库 / 数据库 / 知识图谱存储的历史交互与业务数据)。回引第 5 章 RAG:长期记忆的主要实现就是向量库 RAG,本质是把第 5 章建的 RAG 流水线(chunking / embedding / 检索 / 重排)当成 Agent 的"长期记忆"工具调用。本章还会讲 MemGPT 把"OS 虚拟内存"思想搬到 LLM 上下文管理,最后给选型建议。读完本章你能为不同场景的 Agent 选对记忆架构。
9.1 短期记忆¶
短期记忆是 Agent 当前上下文 window 里能直接看见的所有信息——包括用户对话、工具调用历史、模型生成的 Thought。短期记忆的"短期"是指它受 max_seq_len 约束,超过窗口就要被截断或压缩。
短期记忆的三个组成¶
短期记忆由三部分组成。第一,当前对话历史:用户与 Agent 的多轮对话——user message / assistant message / tool message。这是 Agent 推理的"现场上下文"。第二,工具调用历史:本轮任务中已经调过的工具及返回结果(Observation)——这是 ReAct / Function Calling 循环累积的痕迹。第三,模型生成的中间产物:Thought 文本、计划 JSON、推理 chain——这些中间状态也要保留在上下文里供后续步骤参考。
max_seq_len 约束¶
短期记忆的边界是模型的 max_seq_len(最大序列长度)。GPT-4 是 128K token,Claude 3 是 200K,Llama 3 是 128K。看起来很大,但 Agent 任务很容易超出——一次 Observation 可能几千 token(搜索返回 3 段网页摘要),5 步 ReAct 累积 1-2 万 token,10 步就 2-4 万——再多就逼近窗口上限。超出窗口模型会直接拒绝服务(OpenAI 返回 context length exceeded 错误),或自动从头部截断(早期模型行为,会丢失最旧的 user message)。
Window 管理¶
最简单的短期记忆管理是 sliding window——只保留最近 N 轮对话 / 最近 K 个工具调用,更老的直接丢弃。如保留最近 5 轮对话 + 最近 10 个 Observation。优点是简单稳定,缺点是丢失早期重要信息(如任务最初的目标可能被丢)。Window 大小要按任务调——客服 Agent 短对话 window=5 轮够;长程任务 Agent window 要大或上摘要。
Window 管理的几个变种¶
Window 管理有几个变种。第一,纯滑动窗口:FIFO 丢弃最旧——简单但丢早期目标。第二,带摘要的窗口:被丢弃的部分压缩成一段摘要保留在头部——保留要点但摘要质量靠 LLM。第三,重要性加权保留:让 LLM 评"这条消息的重要性",重要的不丢——但 LLM 评估不稳定。第四,token 预算管理:按 token 数而非消息数管理(保留最近 8000 token)——更精确但实现复杂。生产大多用纯滑动 + 摘要混合:常规消息按 FIFO 滑动,关键节点(用户提了新需求 / Agent 做了关键决策)触发摘要压缩。
短期记忆的工程实现要点¶
短期记忆工程实现几个要点。第一,token 计数要准:用 tokenizer 精确计数,不能用 len(text) 粗估——中文字符数与 token 数比例约 1:1.5-2,估错会爆 context。第二,消息切分单位:按"用户消息 + Agent 响应 + 工具调用"为一个切分单位,不能在 Agent 响应中间切——会破坏上下文连贯。第三,系统提示词永不动:system message 永远在最前面不被滑动——它是 Agent 行为基线,不能丢。第四,工具结果特殊处理:Observation 可能很长(搜索返回几段摘要),可以单独管理——超阈值就摘要或截断,不让单条 Observation 占满 budget。第五,多用户隔离:每个用户会话独立 context list,不能跨用户串读——这是基本合规要求。第六,会话持久化:长会话可以序列化存盘,下次用户回来时恢复——但要序列化整个 context list,包括工具调用历史。
9.2 长期记忆¶
本节复用第 5 章的 RAG 基础——向量库 RAG 在 Agent 记忆中是同一技术,只是被 Agent 当作"长期记忆"工具调用。第 5 章详细讲了 RAG 的建库(chunking / embedding / 入库)与查询(向量检索 / 重排 / 上下文组装)流水线——这些技术原封不动就是 Agent 长期记忆的实现。区别在于用法:RAG 是"用户问 → 系统检索 → 拼答案"的产品形态;Agent 长期记忆是"Agent 推理时主动调用 retrieve_memory 工具拉相关历史"的工具调用形态。
长期记忆的 4 种实现¶
| 方式 | 思路 | 优势 | 劣势 |
|---|---|---|---|
| 向量库 RAG | 历史交互 chunk + embedding + 向量检索召回 | 通用、语义模糊查询强、可与第 5 章 RAG 流水线复用 | 召回有噪声、依赖 embedding 质量 |
| 摘要树 | 层级摘要:顶层一句概括 + 细节层分多段 | token 省、层级清晰 | 摘要损失细节、需要定期重摘要 |
| 知识图谱 | 提取实体 + 关系,结构化存储 | 查询精确、可推理关系 | 建图贵、图谱 schema 要早定 |
| 数据库 | 显式存表,Agent 用 SQL 查 | 严格结构化、ACID 保证 | 仅适合结构化业务数据,非结构化对话历史不适用 |
向量库 RAG 在 Agent 记忆中的角色¶
向量库 RAG 在 Agent 记忆系统中的角色是"长期记忆工具"——Agent 调用 retrieve_memory(query) 工具时,向量库返回与 query 相关的历史交互 chunk。具体流程完全复用第 5 章 RAG 流水线:1. 建库阶段(离线):把过去所有对话历史 / 任务经验 / 用户偏好 chunking → embedding → 入向量库。2. 查询阶段(实时):Agent 推理时调 retrieve_memory("用户上次问过什么") 工具,工具内部走 RAG 流水线(embedding query → 向量检索 top-K → 重排 → 返回 top-3 chunk)。3. 塞回 prompt:检索结果作为 Observation 塞回 Agent 上下文,Agent 基于历史信息继续推理。
技术与第 5 章完全一致——chunking 策略(递归 + 父子分块)、embedding 模型(bge-large-zh)、向量库(FAISS / Milvus)、重排(cross-encoder)——这些都能复用第 5 章的代码与基础设施。区别是 Agent 把 RAG 包装成 retrieve_memory 工具暴露给上层 Agent,输入是 query(如"用户偏好的还款方式"),输出是相关历史片段。
摘要树¶
摘要树是层级摘要——把长历史压缩成几个层级:顶层一句话概括整体(如"用户过去 30 天与客服讨论了 5 次退款问题,主要诉求是延迟还款"),中层每段几句话概括每个事件,底层是原始对话。Agent 推理时先看顶层确定方向,需要细节时调 get_summary(level=2) 拿中层摘要,再需要时调 get_raw_dialog(timestamp) 拿原始对话。优点是 token 省(顶层只几十 token)、层级清晰;缺点是摘要损失细节,且需要定期重摘要(每天 / 每周跑一次摘要任务)。
知识图谱¶
知识图谱是结构化记忆——把历史交互提取成 (entity, relation, entity) 三元组(如 (用户A, 偏好, 信用卡还款)),存到 Neo4j 这类图数据库。Agent 查询时用图查询语言(Cypher / SPARQL)精确查"用户 A 的还款偏好"——返回精确结果,无 RAG 的召回噪声。优势是查询精确、可推理关系(如"用户 A 的朋友用户 B 偏好什么"通过图遍历可得);劣势是建图贵(要 LLM 抽取实体 + 人工校验)、schema 要早定(后期加关系类型要重建)。
数据库¶
数据库是最传统的"长期记忆"——把结构化业务数据存到 PostgreSQL / MySQL,Agent 用 SQL 查。如客服 Agent 查"用户 A 的订单状态"用 SELECT status FROM orders WHERE user_id = A。优势是严格结构化、ACID 保证、可写可改;劣势是仅适合结构化业务数据——非结构化对话历史、偏好这类信息不适合塞表。生产 Agent 大多用"数据库 + 向量库"双轨——结构化业务数据用 DB 查,非结构化对话历史用向量库 RAG 查。
长期记忆选型的工程决策树¶
工程师选长期记忆实现时按几个维度决策。第一,数据是否结构化?结构化(订单、用户、产品)用数据库;非结构化(对话历史、文档)用向量库 RAG。第二,是否有强关系查询需求?是 → 知识图谱(如"用户的朋友的偏好"这种图遍历);否 → 向量库或数据库。第三,召回精度要求?要求精确无噪声 → 数据库 / 知识图谱;容忍模糊召回 → 向量库 RAG。第四,建图成本预算?建图贵——预算有限先用向量库 RAG,预算充足且高价值场景再上知识图谱。第五,是否需要持久跨会话?是 → 必须有外部存储(向量库 / 数据库 / 图谱),不能只靠 context window。第六,合规要求?敏感数据要存数据库(有权限隔离 / 审计 / 加密),不能存向量库(向量库的 metadata 难做严格权限)。
9.3 MemGPT¶
MemGPT 是 Packer et al. 2023 提出的 Agent 记忆架构(arXiv:2310.08560),核心思想是"仿 OS 虚拟内存"——把 LLM context window 当作主存(RAM),把向量库当作辅存(Disk),自动 page in/out 让 Agent 感觉到"上下文无限大"。
OS 虚拟内存类比¶
OS 虚拟内存的核心机制:物理 RAM 容量有限(如 8GB),但进程可以"看到"远超 RAM 的虚拟地址空间(如 64GB)——OS 自动把不常用的内存页 page out 到 Disk,进程访问到不在 RAM 的地址时触发 page fault,OS 把对应页从 Disk page in 回 RAM。进程感觉"内存无限大",实际是 OS 在背后做 page in/out 调度。
MemGPT 的对应¶
MemGPT 把这个思想搬到 LLM 上下文管理。主存 = context window:LLM 当前能直接看见的所有 token(如 128K)。辅存 = 向量库:所有历史交互与业务数据存向量库,容量无限。Page Out:context window 快满时,MemGPT 把最旧 / 最不相关的消息压缩或移到向量库,腾出空间。Page In:Agent 推理时需要某段被 page out 的历史,调 retrieve_memory 工具把对应内容 page in 回 context window。Page Fault:Agent 引用了上下文里没有的内容(如"我上次说的还款方案"),系统触发 retrieve 自动 page in。
MemGPT 的核心创新¶
MemGPT 的核心创新是让 LLM 自己决定 page in/out——LLM 通过函数调用控制自己的记忆。MemGPT 给 LLM 暴露几个工具:recall_memory(query) 从向量库拉相关历史、archival_memory_insert(content) 把内容存到向量库、archival_memory_search(query) 检索向量库、message_chat_summary() 触发当前对话压缩。LLM 推理时主动调这些工具管理自己的记忆——这是"Agent 自我管理记忆"的范式。对比传统 RAG 把检索做成"系统级"操作(用户问就检索),MemGPT 把检索做成"Agent 主动调用"——Agent 自己决定何时该查记忆、查什么。
MemGPT 的"系统提示词"角色¶
MemGPT 还引入"系统提示词"角色——一个特殊的 system message 持续监督 context 状态,当快满时主动触发 page out。这相当于 OS 的"内存管理器"——LLM 是进程,系统提示词是 OS,进程感觉内存无限,OS 在背后做调度。这个思路让 Agent 处理"超长上下文任务"(如长篇小说写作、长程客服对话)成为可能——传统 RAG 要靠人工设计何时检索,MemGPT 让 Agent 自己管理。
MemGPT 的工程价值¶
MemGPT 的工程价值在于:1. Agent 不再受 context window 限制——可以处理"几个月的对话历史"或"几百兆的文档"。2. 检索自动化——Agent 自己决定何时检索,不需要人工设计触发逻辑。3. 记忆压缩可解释——page in/out 都有日志,工程师能追溯"Agent 为什么这时候检索这段历史"。但 MemGPT 也有缺点:1. 复杂度高——LLM 自己管理记忆要训练或 prompt 教会模型"何时该检索",不稳定的模型会瞎调工具。2. 延迟波动——page in 是向量库检索,单次几百毫秒,比直接读 context 慢。3. 记忆碎片化——频繁 page in/out 让上下文里信息碎片化,模型推理可能不一致。
MemGPT 的"自我意识"哲学¶
MemGPT 让 LLM "自我管理记忆"在哲学层面是新的尝试——传统 RAG 把检索做成"系统级"操作(用户问就检索),MemGPT 把检索做成"Agent 主动调用"(Agent 自己决定何时查记忆)。这相当于让 LLM 具备了"记忆自我意识"——Agent 知道"我现在需要什么记忆"、"什么记忆该挪出去"。这种自我管理对长程任务(写小说、做研究、长客服)是必要的——传统 RAG 靠人工设计触发逻辑撑不住几个月的任务。但 MemGPT 也带来新的不确定性——LLM 的"自我意识"可能不稳定,模型可能瞎调 retrieve 工具或不调该调的工具。生产用 MemGPT 要严格测试 retrieve 调用频率与时机,监控 Agent 是否在合理时机检索。
MemGPT 的开源实现¶
MemGPT 有开源实现(github.com/cpacker/memgpt),提供 Python SDK 与 SaaS 服务。开发者可以 pip install memgpt 后用几行代码起一个 MemGPT Agent,自动管理记忆。生产用 MemGPT 要注意几个工程点:1. retrieve 工具的 description 要写清楚——让 LLM 知道何时该调(如"当用户引用过去的对话时调本工具")。2. page out 阈值——context 用到 70% 触发压缩,不要等到 100% 才动。3. 压缩 prompt——压缩历史的 prompt 要写清楚"保留关键事实与决策,丢弃寒暄与废话"。4. 记忆审计——记录每次 page in/out 的内容,便于事后追溯 Agent 行为。
9.4 上下文压缩¶
短期 / 长期记忆之外,第三种技术是**上下文压缩**——把当前 context window 里的冗长信息压缩成更短的形式,腾出 token 空间。压缩与长期记忆(page out 到外部存储)不同——压缩是把信息留在 context window 里但用更少 token 表示。
摘要压缩¶
最简单的压缩是摘要——让 LLM 把一段长历史 / 长工具结果压缩成一段摘要。如"过去 5 轮对话压缩成:用户问 X,Agent 调 Y 工具返回 Z,最终答案 W"——10 token 代替 1000 token。摘要质量靠 LLM,一般用便宜模型(GPT-4o-mini)做摘要,主模型(GPT-4)做推理。摘要压缩的时机很关键——太早摘要会丢失推理中间状态,太晚摘要已经爆 context。生产大多在"对话每 5 轮"或"工具结果每 2000 token"触发一次摘要。
KV Cache 重写¶
更进阶的压缩是 KV Cache 重写——把长历史的 KV cache 压缩成更少的 KV 向量。HuggingGPT 类方法(如 LLMLingua / LongLLMLingua)用一个小模型评估每个 token 的"重要性",丢弃低重要性 token 的 KV。这种方式不改 prompt 文本但改 KV,模型"看不到"被丢弃的细节但保留主要语义。优势是模型无感知(不像摘要会让模型看到"这是摘要"),劣势是工程复杂(要改推理引擎)且对小模型效果有限。
Token 预算管理¶
Token 预算管理是压缩的工程化框架——给每类上下文分配预算:用户对话 50%、工具结果 30%、系统提示 5%、模型输出 15%。预算超了就触发对应类型的压缩(如工具结果超预算就摘要最旧的)。这种"预算制"让压缩有秩序——不会出现"工具结果挤爆预算挤掉用户对话"这种问题。生产 Agent 应该有显式的 token budget 配置,每条消息进入 context 前先过预算检查。
何时压缩的 trigger¶
何时触发压缩有几个 trigger。第一,绝对阈值:context 用到 80% 触发——简单稳定。第二,增量阈值:新增 N token 触发一次——避免单次压缩太多影响推理。第三,重要性触发:检测到某段历史"不再被后续推理引用"时压缩——智能但难评估。第四,对话边界触发:每完成一轮对话触发一次——时机明确。生产大多用"绝对阈值 80% + 增量阈值 2000 token"双 trigger——既不会等爆才动也不会频繁压缩影响推理。
压缩质量与可观测性¶
压缩质量直接决定 Agent 推理质量——压缩丢信息会让模型推理基于残缺上下文出错。第一,压缩前后对比:生产环境应记录压缩前与压缩后的 token 数,看压缩比是否合理(一般 5-10 倍)。第二,压缩质量评测:定期评测压缩保留的关键事实是否正确——人工抽查或 LLM-as-Judge 评"压缩是否丢失关键信息"。第三,压缩漂移监控:同一对话多次压缩后,最早的内容被多次摘要可能漂移到完全失真——要监控深层压缩的内容质量。第四,可回滚:压缩前的原始内容应该存档(向量库或 DB),出问题能回查——不要只存压缩后摘要。第五,压缩 prompt 优化:压缩 prompt 要写清楚"保留关键事实与决策、丢弃寒暄与废话",多次迭代优化。
9.5 记忆系统实战选型¶
不同场景的 Agent 记忆系统选型不同——没有"一刀切"的最优解。下面给一个选型矩阵。
| 场景 | 短期记忆 | 长期记忆 | 压缩 |
|---|---|---|---|
| 短对话客服 Agent | sliding window (5 轮) | 不需要 | 不需要 |
| 长会话咨询 Agent | sliding window + 摘要 | 向量库 RAG | 摘要每 5 轮触发 |
| 业务数据处理 Agent | 工具调用历史 | 数据库 SQL | 工具结果摘要 |
| 个性化记忆 Agent | sliding window + 偏好缓存 | 向量库 RAG + 用户画像表 | 偏好定期摘要 |
| 长程任务 Agent | MemGPT 自动管理 | MemGPT archival memory | MemGPT 自动 page out |
| 多 Agent 协作 | 各 Agent 独立 window | 共享向量库 + 共享数据库 | 共享记忆定期摘要 |
短对话客服 Agent¶
短对话客服 Agent(如电商客服、外卖客服)记忆需求简单——单轮对话 3-5 条消息解决用户问题,window 5 轮够用。不需要长期记忆——每个会话独立,不跨会话引用。不需要压缩——短对话不会爆 context。这是最简单的记忆场景,纯 sliding window 即可。
长会话咨询 Agent¶
长会话咨询 Agent(如法律咨询、医疗问诊)会话可能持续几小时甚至跨天——用户问"上次我们聊的 X 怎么样了"很常见。短期 sliding window + 摘要;长期向量库存所有历史对话,按需 retrieve_memory 调用;摘要每 5 轮触发一次防止 context 爆。这种场景是 RAG-based 长期记忆的典型应用——第 5 章的 RAG 流水线原封不动拿来用。
业务数据处理 Agent¶
业务数据处理 Agent(如 BI 助手、报表生成)处理结构化业务数据——记忆主要是数据库 SQL 查询历史。短期工具调用历史;长期数据库 SQL 查结构化业务数据;工具结果摘要(如查 1000 条订单压缩成"1000 条订单,总金额 X,最近日期 Y")。这种场景数据库是主长期记忆,向量库是辅助(存非结构化的用户偏好与历史 query)。
个性化记忆 Agent¶
个性化记忆 Agent(如个人助理、AI 伴侣)核心需求是"记住用户的偏好与历史"——用户说"我喜欢早起"应该被记下来,下次主动用上。短期 sliding window + 偏好缓存(结构化的偏好键值对);长期向量库存对话历史 + 用户画像表(结构化的偏好);偏好定期摘要(如每周把对话里的偏好提取到画像表)。这种场景是 RAG + 数据库双轨——向量库存非结构化历史,数据库存结构化偏好。
长程任务 Agent¶
长程任务 Agent(如 Devin 这类代码 Agent 跑几天任务)记忆需求最复杂——上下文要装下几天的推理历史与工具调用。短期 MemGPT 自动管理(Agent 自己决定 page in/out);长期 MemGPT archival memory(向量库);MemGPT 自动 page out。这是 MemGPT 范式的典型应用——传统 RAG 撑不住,必须靠 Agent 自管理记忆。
多 Agent 协作记忆¶
多 Agent 协作(第 11 章展开)记忆要解决"多个 Agent 共享记忆"——一个 Agent 学到的知识要让其他 Agent 也能用。各 Agent 独立 short window(避免互相干扰);共享向量库 + 共享数据库(让知识沉淀);共享记忆定期摘要(把各 Agent 的临时结论合并成共识)。这种场景记忆架构要设计"读写权限"——哪些 Agent 能写哪些只能读,避免记忆被污染。
记忆系统的可观测性¶
记忆系统生产化要可观测——工程师要能看到 Agent 在记忆层面做了什么。第一,每次 retrieve 调用记日志:记录 (caller, query, top_K results, timestamps),便于追溯"Agent 为什么这时候检索这段历史"。第二,每次 page in/out 记日志:记录压缩前 token 数 / 压缩后 token 数 / 哪些消息被压出去 / 哪些被摘要保留——压缩质量事后能查。第三,记忆库统计:向量库总量 / 每日新增量 / 热点 chunk(被多次 retrieve 的)——发现冷热数据分布。第四,记忆命中率:retrieve 调用后是否真被 LLM 用上——拉回来但 LLM 没引用说明检索不准。第五,异常检测:单 Agent 短时间内频繁 retrieve 同一 query——可能是循环或检索失效。这些可观测性是生产记忆系统的基础——没有可观测性 Agent 行为不可控。
代码片段:简化 MemGPT 风格的记忆管理¶
下面这段代码(约 25 行)实现简化版 MemGPT 风格记忆管理——维护 context list,超 budget 时 page out 旧消息到 archival,retrieve 时 page in 回来。
class SimpleMemGPT:
def __init__(self, budget_tokens=8000, llm=llm_call, vectorstore=vs):
self.context = [] # 当前 context window 里的消息列表
self.budget = budget_tokens
self.llm = llm
self.archival = vectorstore # 长期记忆(向量库)
def add_message(self, msg):
self.context.append(msg)
if self._token_count() > self.budget * 0.8:
self._page_out() # 超阈值触发压缩
def _page_out(self):
# 把最旧的几条消息压缩成摘要,原文存 archival
old_msgs = self.context[:3]
summary = self.llm(f"压缩成 100 token 摘要:{old_msgs}")
for m in old_msgs:
self.archival.add_texts([m], metadatas=[{"role": m.get("role", "?")}])
self.context = [{"role": "system", "content": f"[历史摘要]: {summary}"}] + self.context[3:]
def retrieve(self, query, k=3):
# Agent 主动调本工具:从 archival 拉相关历史 page in 回 context
docs = self.archival.similarity_search(query, k=k)
return "\n".join([d.page_content for d in docs])
def _token_count(self):
return sum(len(m.get("content", "")) // 2 for m in self.context) # 粗估 1 中文≈2 token
# 用法
agent = SimpleMemGPT(budget_tokens=8000)
agent.add_message({"role": "user", "content": "用户问 X..."})
# Agent 推理时主动调 retrieve 工具拉相关历史
historical = agent.retrieve("用户偏好的还款方式")
这段代码示范了 MemGPT 的核心机制:超 80% budget 触发 page out(旧消息摘要 + 原文存向量库),Agent 主动调 retrieve 工具 page in 相关历史。生产 MemGPT 还要加:摘要 prompt 精细化、retrieve 工具的 description 写清楚让 LLM 知道何时调、page in/out 审计日志、多 Agent 共享 archival 时的并发控制。
工程实战要点¶
- 短期靠 window、长期靠 RAG:短期记忆 sliding window 管理当前对话,长期记忆向量库 RAG 管理历史——技术栈分层,短期靠 prompt window,长期靠第 5 章 RAG 流水线复用。
- 压缩要在阈值前触发:context 用到 70-80% 触发摘要压缩,不要等到 100% 才动——到 100% 模型会拒绝服务或自动截断丢信息。绝对阈值 + 增量阈值双 trigger 最稳。
- 记忆系统要可观测:每次 page in/out / retrieve 调用都落审计日志——Agent 为什么这时候检索这段历史、压缩保留了哪些信息、丢弃了哪些,事后能追溯。
- 知识图谱比 RAG 准但建图贵:结构化业务数据用知识图谱查询精确无噪声,但建图要 LLM 抽实体 + 人工校验 + schema 早定——成本是 RAG 的 5-10 倍,仅适合高价值场景。
- 不要把所有上下文都塞进 prompt——做检索:Agent 推理时只塞"当前需要的"上下文,其他都靠 retrieve 工具按需拉——这是 RAG 与 MemGPT 的共同教训,"按需检索"比"全部塞进"更省 token 也更准。
小结¶
- 短期记忆 = context window 里的当前对话 + 工具调用历史 + 中间产物;受 max_seq_len 约束;window 管理(纯滑动 / 带摘要 / 重要性加权 / token 预算)是核心工程。
- 长期记忆 4 种实现:向量库 RAG(复用第 5 章技术)、摘要树(层级压缩)、知识图谱(结构化精确)、数据库(结构化业务数据);Agent 把 retrieve_memory 工具化是 RAG 在记忆系统的形态。
- MemGPT(arXiv:2310.08560)仿 OS 虚拟内存:context window = 主存、向量库 = 辅存、Agent 自己调工具 page in/out;让 Agent 处理超长上下文成为可能。
- 上下文压缩 3 种:摘要压缩(LLM 摘要长文本)、KV Cache 重写(小模型评估丢低重要性 KV)、token 预算管理(每类上下文分预算);trigger 用 80% 绝对阈值 + 增量阈值双触。
- 选型:短对话纯 window、长会话 window + RAG、业务数据 DB + 向量库、个性化 RAG + 画像表、长程任务 MemGPT 自管理、多 Agent 共享向量库 + DB。
- 不要全塞 prompt——按需检索是 RAG 与 MemGPT 的共同教训。
练习题¶
- Agent 短期记忆与长期记忆的本质区别?
- 向量库 RAG 在 Agent 记忆系统中的角色是什么?
- MemGPT 的"虚拟内存"类比如何对应到 OS 概念?
- 何时触发上下文压缩?
- 知识图谱相比向量库 RAG 的优劣?
- 一个客服 Agent 的记忆系统该怎么选型?
参考答案¶
第 1 题答案
短期记忆与长期记忆的本质区别是"存储位置"与"访问方式"。**短期记忆**:存在 LLM context window 里(即模型推理时直接能看见的所有 token),包括当前对话历史、工具调用历史、模型生成的中间产物(Thought / 计划)。受 max_seq_len 约束(GPT-4 128K / Claude 3 200K),超过窗口要被截断或压缩。访问方式是"模型直接读"——无需任何额外调用,模型推理时上下文就在 prompt 里。**长期记忆**:存在 context window 之外(向量库 / 数据库 / 知识图谱),不受 max_seq_len 限制,容量无限。访问方式是"模型主动调工具"——Agent 要调 `retrieve_memory(query)` 工具才能把长期记忆里的相关内容拉回 context window。本质:短期记忆是"在眼前的",长期记忆是"在档案柜里的,要去找"。Agent 的记忆系统设计本质是"哪些信息该放在眼前(短期)、哪些该放档案柜(长期)、何时该去档案柜找(retrieve)"。第 2 题答案
复用第 5 章 RAG 的同一技术——chunking/embedding/检索/重排——但被 Agent 当作"长期记忆"工具调用。具体角色:Agent 把 `retrieve_memory(query)` 包装成一个工具暴露给上层 Agent,输入是 query(如"用户偏好的还款方式"),输出是相关历史片段。工具内部走完整 RAG 流水线:embedding query → 向量库 ANN 检索 top-K → cross-encoder 重排 → 返回 top-3 chunk。Agent 推理时主动调本工具把相关历史拉回 context window(page in)。技术与第 5 章完全一致——chunking 策略(递归 + 父子分块)、embedding 模型(bge-large-zh)、向量库(FAISS / Milvus)、重排(cross-encoder)都能复用第 5 章的代码与基础设施。区别是 RAG 作为产品形态是"用户问 → 系统检索 → 拼答案"被动模式,作为 Agent 记忆工具是"Agent 推理时主动调用"主动模式——Agent 自己决定何时该查记忆、查什么。第 3 题答案
MemGPT 的"虚拟内存"类比对应 OS 概念如下。**主存(RAM)= context window**:LLM 当前能直接看见的所有 token(如 128K),相当于 OS 进程的物理 RAM。**辅存(Disk)= 向量库**:所有历史交互与业务数据存向量库,容量无限,相当于 OS 进程的 Disk 存储。**Page Out**:context window 快满时(如 80% 阈值),MemGPT 把最旧 / 最不相关的消息压缩或移到向量库,相当于 OS 把不常用内存页 page out 到 Disk。**Page In**:Agent 推理时需要某段被 page out 的历史,调 `retrieve_memory` 工具把对应内容 page in 回 context window,相当于 OS 进程访问到不在 RAM 的地址时把对应页从 Disk 加载回 RAM。**Page Fault**:Agent 引用了上下文里没有的内容(如"我上次说的还款方案")触发 retrieve 自动 page in,相当于 OS 的 page fault 中断。核心创新是让 LLM 自己决定 page in/out——LLM 通过函数调用控制自己的记忆,相当于进程自己管理虚拟内存(不像传统 OS 由内核管理)。第 4 题答案
触发上下文压缩的几个 trigger。第一,**绝对阈值**:context 用到 80% 触发——简单稳定,最常用。第二,**增量阈值**:新增 N token(如 2000)触发一次——避免单次压缩太多影响推理。第三,**重要性触发**:检测到某段历史"不再被后续推理引用"时压缩——智能但难评估,生产少用。第四,**对话边界触发**:每完成一轮对话触发一次——时机明确但可能压缩过早。生产大多用"绝对阈值 80% + 增量阈值 2000 token"双 trigger——既不会等爆才动(绝对阈值兜底)也不会频繁压缩影响推理(增量阈值控制频率)。要注意不能等到 100% 才触发——那时模型会拒绝服务(context length exceeded 错误)或自动从头部截断丢信息。生产 Agent 应有显式的 token budget 监控与压缩 trigger 配置。第 5 题答案
知识图谱相比向量库 RAG 的优劣。**优势**:第一,查询精确无噪声——图谱用 (entity, relation, entity) 三元组结构化存储,查询用 Cypher / SPARQL 精确匹配(如 `MATCH (u:User {id: A})-[:PREFERS]->(p) RETURN p`),返回精确结果,无 RAG 的召回噪声。第二,可推理关系——通过图遍历可推理"用户 A 的朋友用户 B 偏好什么"这种隐式关系,RAG 做不到。第三,更新精确——某个事实变了直接改三元组,RAG 要重新 chunking + embedding + 入库。**劣势**:第一,建图贵——要 LLM 抽取实体 + 人工校验,成本是 RAG 的 5-10 倍。第二,schema 要早定——后期加关系类型要重建图谱,灵活性差。第三,非结构化信息塞不进——自由对话里的微妙语气、上下文情感这类信息图谱表达不了,只能用 RAG。生产大多用"图谱 + RAG"双轨——结构化事实用图谱查(精确),非结构化历史用 RAG 查(灵活)。第 6 题答案
客服 Agent 的记忆系统选型要按业务场景细分。**短对话客服**(电商、外卖,单轮 3-5 条消息解决):纯 sliding window 5-10 轮即可,不需要长期记忆、不需要压缩——简单场景不要过度设计。**长会话咨询客服**(法律、医疗,会话跨小时跨天):短期 sliding window + 摘要(每 5 轮摘要防 context 爆);长期向量库存所有历史对话(用第 5 章 RAG 流水线,Agent 调 `retrieve_memory` 工具按需拉历史);用户说"上次我们聊的 X"时 Agent 主动检索。**个性化客服**(高端会员、AI 伴侣):短期 window + 偏好缓存;长期向量库存对话历史 + 用户画像表(结构化偏好如"喜欢早上联系、偏好信用卡还款");偏好定期摘要(每周从对话提取到画像表)。**业务数据处理客服**(BI 助手、报表):短期工具调用历史;长期数据库 SQL 查结构化业务数据(订单、用户、产品);向量库辅助存非结构化 query 历史。**多 Agent 客服**(Supervisor + 多专业子 Agent):各 Agent 独立 short window;共享向量库 + 共享数据库;共享记忆定期摘要。选型核心:先看会话长度(短对话纯 window,长会话加 RAG),再看业务数据结构化程度(高用 DB,低用向量库)。下一章:第十章 MCP:工具协议标准化