AI Agent记忆系统技术深度解析短期记忆、长期记忆与RAG的协作机制为什么Claude Code能记住你10分钟前改过的文件名为什么Agent运行1小时后开始遗忘之前的决策为什么同样一段代码有时Agent能回忆起来有时却像第一次看到记忆系统是Agent从玩具走向工具的关键基础设施。本文分析Agent记忆系统的四种核心类型、它们的实现原理和协作机制。一、Agent为什么需要记忆系统1.1 没有记忆的Agent是什么样当前大多数Agent的运行模式是会话式的——每次对话是一个独立的上下文窗口Agent只看到当前会话中的信息。用户帮我重构UserService.java这个文件 Agent好的我来看一下... 读取UserService.java ​ 用户现在重构LoginService.java Agent好的我来看一下... 读取LoginService.java完全忘记刚才的UserService ​ 用户UserService里也做同样的重构 Agent什么UserService我要重新读一遍...这不是模型能力的问题是记忆机制的问题。每次对话开始时Agent的上下文是空的它不记得任何之前发生过的事。1.2 记忆系统的分类Agent记忆系统通常分为四种类型每种的特性不同记忆类型存储位置生命周期容量检索方式典型应用短期记忆上下文窗口内存对话上下文一个会话8K-1M token顺序访问当前任务上下文工作记忆Agent运行时内存临时存储一个子任务有限结构化引用中间计算结果长期记忆持久存储文件/向量数据库跨会话几乎无限语义检索用户偏好、项目知识情景记忆会话记录数据库跨会话大时间语义历史决策回溯二、短期记忆上下文窗口的管理2.1 上下文窗口的物理限制短期记忆的本质是LLM的上下文窗口。当前主流的上下文窗口大小模型上下文窗口可容纳的对话轮次估算可容纳的代码量GPT-4o128K~300-500轮~50,000行Claude Opus 4.8200K~500-800轮~80,000行DeepSeek V41M~2500-4000轮~400,000行GLM-5.21M~2500-4000轮~400,000行但物理容量和有效容量是两回事。研究发现在长上下文中模型对中间位置的信息检索准确率显著下降——称为lost in the middle效应Liu et al., 2024。在一个1M token的上下文中模型对开头和结尾的信息几乎可以准确回忆但对中间的信息回忆准确率可能不到50%。2.2 上下文压缩为了让有限的窗口容纳更多有效信息需要进行上下文压缩。消息摘要将早期的对话轮次压缩为摘要。不是每轮对话都保留完整内容而是每经过N轮或上下文达到某个阈值时对前面的内容做一次总结。class ContextManager: def __init__(self, max_tokens128000): self.max_tokens max_tokens self.summary # 压缩后的摘要 self.active_messages [] # 最近的消息完整保留 ​ def add_message(self, message): self.active_messages.append(message) if self._total_tokens() self.max_tokens * 0.7: self._compress() ​ def _compress(self): # 将最早的一半消息压缩为摘要 old_messages self.active_messages[:len(self.active_messages)//2] new_summary self._summarize_messages(old_messages) ​ # 合并摘要 self.summary self._merge_summaries(self.summary, new_summary) ​ # 移除已压缩的消息 self.active_messages self.active_messages[len(self.active_messages)//2:]一个关键问题摘要本身也会消耗token。摘要的摘要的摘要...最终摘要会变得过于抽象丢失细节。比较好的做法是将摘要限制在不超过总上下文的10%即128K窗口中摘要不超过12K token。选择性保留不是所有消息都同等重要。工具调用的结果可能很大和用户的原始输入重要性完全不同。def select_messages_for_retention(messages, importance_fn): 根据消息的重要性选择性保留而非全部压缩 scored [(msg, importance_fn(msg)) for msg in messages] scored.sort(keylambda x: x[1], reverseTrue) return [msg for msg, score in scored[:KEEP_COUNT]]什么消息更重要经验规则用户明确要求的修改把这个函数的参数改为可选→ 高重要性Agent做出的决策和选择我选择使用二分查找→ 中高重要性Agent执行的结果总结重构完成通过全部测试→ 中重要性错误的工具调用和重试 → 低重要性完整的工具输出大量中间数据→ 低重要性可被摘要替代2.3 窗口滑动策略滑动窗口策略决定了当上下文满时哪些内容被丢弃哪些被保留。FIFO策略先进先出丢弃最早的消息。简单但不聪明——如果最早的消息包含了关键决策信息丢弃它会导致Agent失去上下文。重要性策略根据消息的重要性分数丢弃。比FIFO好但需要额外计算重要性分数。每轮对话都计算会增加约5-10%的推理成本。混合策略保留开头系统提示、用户需求和结尾当前正在做的丢弃中间。这是实践中最常用的策略因为它利用了lost in the middle的特点——即使完整保留中间部分模型也回忆不准。不如直接丢弃用摘要替代。三、工作记忆运行时数据的结构化管理3.1 工作记忆的定位短期记忆存储发生了什么工作记忆存储当前正在处理什么。两者的区别短期记忆用户要求重构UserService.java → 我读取了文件 → 我开始修改第42行 → 修改完成 ​ 工作记忆Agent运行时状态 { current_task: 重构UserService.java, file_path: /src/UserService.java, current_line: 42, modification_type: rename_method, dependencies: [UserRepository.java], validation_results: {syntax: pass, tests: pending} }工作记忆是结构化数据不是自然语言。它保存在Agent的运行环境中每次工具调用前后都会被读取和更新。3.2 结构化工作记忆的实现工作记忆通常是一个JSON对象Agent可以读取和修改它# Agent工作记忆的结构 working_memory { task_id: task_001, task_description: 给项目的用户模型添加邮箱验证字段, current_step: 3, total_steps: 5, active_files: [/src/models/user.py, /src/migrations/001_add_email.py], decisions: [ { step: 2, decision: 使用Django的EmailField而非自定义验证, reason: Django内置验证已经满足需求不需要重复造轮子 } ], pending_decisions: [ { question: 验证邮件发送方式, options: [SMTP直发, 使用SendGrid API, 使用阿里云邮件], status: waiting } ], errors: [], timestamps: { started_at: 2026-06-15T10:00:00Z, last_activity: 2026-06-15T10:15:30Z } }工作记忆的关键设计它需要被编码到上下文中但又不能占用太多token。一种做法是只保留工作记忆中最关键的部分到上下文中完整的工作记忆存储在文件系统中。3.3 工作记忆的持久化当Agent运行时间超过1小时工作记忆需要定期保存到持久化存储。保存频率def should_persist_working_memory(wm): 判断是否需要持久化当前工作记忆 reasons [] elapsed time.time() - wm[timestamps][last_persist] if elapsed 300: # 5分钟没有持久化 reasons.append(超过5分钟未持久化) if len(wm.get(decisions, [])) ! last_persisted_decisions: reasons.append(有新的决策记录) if wm.get(current_step) ! last_persisted_step: reasons.append(步骤有更新) return reasons持久化的不是整个对话上下文只有工作记忆JSON。恢复时Agent读取工作记忆JSON不需要重放所有对话记录就能知道当前任务的状态。四、长期记忆跨会话的知识保持4.1 长期记忆存储什么长期记忆是Agent在不同会话之间共享的知识。和短期记忆不同长期记忆是持久化的不随会话结束而消失。长期记忆存储的数据类型数据类型示例存储方式更新频率用户偏好用户喜欢清晰的代码注释键值存储低用户主动设置编码规范项目使用4空格缩进文件低项目初始化时工具使用模式用户常用search_files搜日志向量数据库中每次使用更新频率错误解决记录上次数据库连接失败是因为密码过期向量数据库中每次解决更新项目领域知识这个项目的用户模型有email字段向量数据库高每次代码变更更新4.2 向量数据库的检索策略长期记忆通过语义检索获取相关记忆。向量数据库的检索策略直接决定了长期记忆的质量。Top-K检索返回相似度最高的K条记忆。简单但问题很多——如果K太小可能漏掉重要信息。如果K太大检索到的无关信息会稀释有效信息。MMR最大边际相关性检索在相关性和多样性之间取平衡。返回的记忆不仅和查询相似而且彼此之间不重复。def mmr_search(query_embedding, memory_store, top_k5, lambda_param0.5): MMR: lambda_param1时完全是相关性0时完全是多样性 candidates memory_store.get_all_embeddings() selected [] remaining list(range(len(candidates))) ​ for _ in range(top_k): if not remaining: break scores [] for idx in remaining: # 相关性和查询的余弦相似度 relevance cosine_sim(query_embedding, candidates[idx][embedding]) # 多样性和已选记忆的最大相似度 if selected: diversity max(cosine_sim(candidates[idx][embedding], candidates[s][embedding]) for s in selected) else: diversity 0 # MMR分数 mmr_score lambda_param * relevance - (1 - lambda_param) * diversity scores.append((idx, mmr_score)) # 选择MMR分数最高的 best_idx max(scores, keylambda x: x[1])[0] selected.append(best_idx) remaining.remove(best_idx) ​ return [memory_store[idx] for idx in selected]MMR的lambda_param控制相关性和多样性的权重。对于Agent记忆检索建议lambda_param设为0.6-0.7相关性为主多样性为辅。因为记忆检索的目标是找到有用的信息不是最大化信息覆盖。时间加权检索在语义相似度的基础上叠加时间衰减。越近的记忆权重越高。def time_weighted_search(query_embedding, memory_store, top_k5, time_decay0.01): time_decay时间衰减系数。越大表示越看重近期记忆。 candidates memory_store.get_all_embeddings() scored [] now time.time() for candidate in candidates: relevance cosine_sim(query_embedding, candidate[embedding]) age_hours (now - candidate[timestamp]) / 3600 time_weight math.exp(-time_decay * age_hours) combined_score relevance * time_weight scored.append((candidate, combined_score)) scored.sort(keylambda x: x[1], reverseTrue) return [c for c, _ in scored[:top_k]]时间加权检索的一个重要参数是time_decay。0.01的衰减意味着24小时后记忆权重衰减到约79%168小时7天后衰减到约20%。适用于编码规范、项目知识等不需要长期保留的记忆。对于用户偏好等长期不变的记忆time_decay应该设得更小如0.001。4.3 记忆的选择性写入不是所有信息都值得写入长期记忆。写入太多无关信息会让检索时噪声过大。选择性写入的判断规则def should_write_to_long_term(context, memory_store): 判断一个信息是否值得写入长期记忆 # 规则1信息是否和已有记忆高度重复 similar memory_store.search(context[key], top_k1) if similar and similar[0][similarity] 0.95: return False # 几乎相同的信息不写 ​ # 规则2信息是否可被重新发现 if context.get(rediscoverable, True): # 如果这个信息可以通过代码分析再次获得如函数签名不写 return False ​ # 规则3信息是否具有长期价值 if context.get(temporary, False): # 临时性信息如当前在第42行不写 return False ​ # 规则4信息的置信度 if context.get(confidence, 0) 0.7: # 低于70%置信度的信息不写 return False ​ return True记忆写入的门控是长期记忆质量的关键。写入太松导致噪声写入太紧导致信息缺失。一个实用的策略宁可宽松写入但要给每条记忆附加置信度分数。检索时可以根据置信度过滤。4.4 记忆的更新和冲突解决当新知识和已有记忆冲突时不是简单覆盖而是需要解决冲突。def resolve_memory_conflict(new_fact, old_fact): 解决新知识和已有记忆的冲突 ​ # 情况1: 新知识更稳定来自用户明确声明 if new_fact[source] user_explicit: replace(old_fact, new_fact) return replaced ​ # 情况2: 新知识来自最近的观察 if new_fact[timestamp] old_fact[timestamp] 86400: # 新知识的时效性显著更新但保留旧知识作为备选 add_as_alternative(old_fact, new_fact) return added_alternative ​ # 情况3: 两个知识都有可靠来源 if new_fact[confidence] 0.9 and old_fact[confidence] 0.9: # 两个都保留标记为冲突下次检索时让Agent决定 mark_as_conflict(new_fact, old_fact) return marked_conflict ​ # 情况4: 默认保留置信度更高的 if new_fact[confidence] old_fact[confidence]: replace(old_fact, new_fact) return replaced_by_confidence else: return kept_old冲突标记后检索时返回两个互相矛盾的知识Agent在推理时决定信哪个。这种方式比硬性覆盖更安全——如果Agent发现矛盾可以主动向用户确认。用户看到Agent问您之前说用PostgreSQL现在又提到MySQL应该用哪个会觉得Agent很聪明而不是觉得它记忆混乱。五、情景记忆决策回溯和错误学习5.1 情景记忆vs长期记忆维度长期记忆情景记忆存储内容提取后的知识去除了时间上下文完整的事件记录包含时间、前因后果检索方式语义相似度时间语义用途当前任务的知识支持回溯决策、错误分析容量大可以存储大量知识碎片大但需要压缩精度高提取后更精确低原始记录包含噪声一个例子长期记忆存储项目使用PostgreSQL 15数据库名agent_db 情景记忆存储2026-06-15 10:30用户说数据库用PostgreSQL 15数据库名叫agent_db密码在.env文件里长期记忆提取了知识丢失了上下文。情景记忆保留了原始过程让Agent可以回溯用户当时为什么选PostgreSQL。5.2 会话摘要Episode Summary情景记忆的核心是会话摘要。每个Agent会话结束后生成一个结构化的摘要episode_summary { session_id: ses_20260615_001, user_goal: 添加用户登录功能, completed_tasks: [ 创建User模型, 实现注册接口, 实现登录接口, 添加JWT验证 ], key_decisions: [ { context: 选择密码加密方案, decision: 使用bcrypt而非SHA256, reason: bcrypt自带salt更安全 } ], errors: [ { error: 数据库连接失败, cause: 密码中含有特殊字符未转义, solution: 使用URL编码处理密码 } ], unfinished: [ 忘记添加密码重置功能 ], files_changed: [/src/models/user.py, /src/auth/login.py], tools_used: [read_file, write_file, terminal, web_search] }这个摘要的每个字段都有不同的用途user_goal用于搜索相关情景completed_tasks快速了解已做的工作key_decisions在Agent遇到类似决策时参考errors错误学习的重要来源unfinished提醒还有未完成的工作files_changed用于Agent判断哪些文件有修改历史5.3 错误学习情景记忆的一个重要功能是从错误中学习。当Agent犯了一个错误如选错了工具、产生了错误的代码、忘记了依赖关系错误记录会被保存。下次Agent遇到类似场景时系统会自动检索相关的错误记录附带到上下文中当前上下文 [系统] 以下是过去相似的场景中发生过的问题 - 错误记录2026-06-10使用write_file覆盖了已有的配置文件导致数据丢失。解决方法先read_file确认内容再决定是否覆盖。 - 错误记录2026-06-12忘记安装依赖包就运行测试。解决方法运行测试前先检查requirements.txt。 ​ 用户把这个配置文件更新一下 Agent读取了错误记录让我先看一下当前文件的内容再决定怎么更新...错误学习的两个关键设计错误特征的提取不是保存整个错误场景太大了而是提取特征——当时Agent在执行什么任务、遇到了什么错误、正确的做法是什么。特征的粒度是足够类似场景触发即可不需要完全匹配。相似度阈值当前场景和错误记录的相似度超过某个阈值时才触发。阈值设得太低如0.7会被大量错误记录淹没增加上下文负担。阈值设得太高如0.95类似错误会再次发生。推荐阈值约0.85。六、四种记忆的协作机制一个完整的Agent任务示例6.1 多轮对话中的记忆流转以一个重构用户管理模块的任务为例展示四种记忆的协作第1轮用户说帮我重构UserService.java 工作记忆写入当前任务重构UserService.java 长期记忆检索这个项目的编码规范4空格缩进、TypeScript、JSDoc 情景记忆检索这个文件的历史修改记录 短期记忆用户的输入写入上下文 ​ 第10轮重构完成开始写测试 短期记忆已有10轮对话接近上下文窗口上限 工作记忆更新为写UserService的测试 长期记忆检索项目的测试框架配置Jest、覆盖率要求 ​ 第15轮上下文即将溢出 短期记忆触发压缩前10轮的消息压缩为摘要 工作记忆重新保存到持久化存储 情景记忆如果发生了值得记录的错误或决策写入情景记忆 ​ 第20轮用户关闭会话 情景记忆生成完整的会话摘要 长期记忆提取有价值的持久信息 工作记忆保存到长期记忆作为未完成任务的特殊标记 ​ 第2天新会话用户说继续昨天的UserService重构 情景记忆检索昨日会话找到UserService重构的未完成任务 长期记忆检索项目编码规范 工作记忆从昨日的工作记忆中恢复任务状态 短期记忆将昨日摘要和新输入加载到上下文6.2 信息流转图用户输入 │ ▼ 短期记忆上下文窗口 │ ├── 到达容量阈值 → 压缩 → 摘要加入上下文原始消息丢弃 │ ├── 需要当前状态 → 读取工作记忆 → 加入上下文 │ ├── 需要领域知识 → 检索长期记忆 → 向量搜索 → 加入上下文 │ └── 需要历史参考 → 检索情景记忆 → 时间语义搜索 → 加入上下文 │ ▼ Agent生成回复 │ ▼ 执行工具 → 结果反馈 → 加入上下文 │ ▼ 更新工作记忆 → 如果达到持久化条件写入持久化存储 │ ▼ 如果值得长期记住 → 写入长期记忆向量数据库 │ ▼ 如果值得情景记录 → 写入情景记忆会话摘要更新这个流转每轮对话都在发生。用户看到的是Agent在正常对话背后是四种记忆系统的持续读写。一个运行1小时的Agent任务工作记忆可能被更新50次长期记忆检索10次情景记忆检索2-3次短期记忆压缩2-4次。七、2026年的技术现状与局限7.1 各项目的记忆系统现状项目短期记忆工作记忆长期记忆情景记忆错误学习Claude Code上下文管理无文件系统项目记忆会话记录无Codex CLI基础上下文无无会话记录无OpenAI o3长上下文无用户设置无无MemGPT/Letta上下文压缩有结构化向量数据库会话摘要有限AutoGPT 2.0上下文管理有限向量数据库会话记录有限Hermes Agent上下文管理有记忆系统会话索引通过技能OpenHands上下文管理有限文件系统无无MemGPTLetta在长期记忆和情景记忆上做得最好——它专门为Agent-用户对话设计了记忆系统。Claude Code没有显式的长期记忆系统但通过文件系统间接实现了跨会话的知识保持。Codex CLI在记忆系统上几乎没有投入——每次会话是独立的。7.2 当前局限记忆检索的准确率长期记忆的检索准确率受embedding模型限制。在代码相关的检索上通用embedding模型如text-embedding-3-small的效果不如代码专用模型如code-embedding。但代码专用模型的生态还不够成熟。语义检索在代码场景下容易出现语义接近但逻辑不相关的误匹配。记忆冲突的自动化处理当长期记忆和情景记忆中的信息冲突时目前的Agent无法自动解决。少数项目会标记冲突并让用户决定多数项目简单用新覆盖旧。记忆的遗忘机制目前所有项目的记忆系统都是只增不删的。长期记忆随着使用时间线性增长没有主动遗忘机制。一个运行半年的Agent长期记忆可能有数百万条记录检索噪声显著增加。主动遗忘删除过时、错误、不再相关的记忆是2026年尚未解决的问题。八、总结Agent记忆系统分为四类短期记忆上下文窗口、工作记忆运行时状态、长期记忆持久知识、情景记忆历史记录短期记忆的有效容量远小于物理容量lost in the middle效应需要上下文压缩消息摘要保留不超过总上下文的10%选择性保留按重要性排序工作记忆是结构化JSON每5分钟或无变化5步后持久化长期记忆通过向量数据库检索MMR检索lambda0.6-0.7优于简单Top-K时间加权检索的衰减系数短期知识0.01长期知识0.001选择性写入四规则不重复、不可重新发现、非临时、置信度0.7记忆冲突用标记替代覆盖让Agent在推理时决定情景记忆存储完整事件上下文含时间、前因后果错误学习是重要应用错误学习的触发阈值推荐0.85特征提取比完整场景更实用四种记忆每轮对话都在流转运行1小时的任务约60次记忆读写2026年主要局限代码场景检索准确率不足、冲突无自动解决、无主动遗忘机制