你是否有过这样的经历智能体跑一个长任务开始时思路清晰、步骤正确但执行到第 30 步时突然像“失忆”一样忘记了前面已经完成的子目标开始重复劳动甚至决策逻辑完全走样。传统做法是拼命加大上下文窗口或者每次把全量历史塞给模型可结果要么是成本爆炸要么是长期记忆与当前任务互相干扰长程智能体始终无法稳定完成复杂工作流。Recuris 提出的双记忆机制正是针对这个痛点的一种新思路。它不做“上下文无限扩大”而是把记忆拆成工作记忆和长期记忆两个系统用一个显式的记忆管理协议让智能体知道“现在该记什么、该忘什么、该从长期记忆中调取什么”。从实际效果看这种设计路径能显著降低长程任务的中断率和状态漂移大幅提升任务成功率。这篇文章会从问题出发讲清楚 Recuris 双记忆机制的原理、架构、核心流程并给出一个可以运行的最小示例代码以及工程落地中的常见问题与最佳实践。无论你是做 AI Agent、RAG 应用还是研究 LLM 长程推理都可以在本文中找到一套可复用的思路。1. 长程智能体的困境与 Recuris 的价值1.1 为什么长程任务会失败大语言模型本身是无状态的。你每次调用 API模型都像是在“第一次见到你”。为了让智能体具备连续工作的能力工程上通常会把对话历史、工具调用记录、中间结果拼接到提示词中。这种方案在短任务里没问题但一旦任务步骤变多就会暴露出三个致命问题上下文污染早期步骤的信息占用了大量上下文空间还可能包含大量噪声模型被无关历史干扰越来越难聚焦当前目标。关键信息遗忘超过上下文窗口后最早的关键决策会被截断。智能体可能不记得用户最初的需求或者忘记已经完成的子目标。状态漂移模型在长序列中容易注意力涣散对当前状态的判断前后不一致同一件事在不同步骤给出相反的结论。这些问题的根源不是模型不够强而是记忆管理方式太粗糙。直接把所有历史塞给模型本质上等于让人一边办公一边背诵过去一个月所有邮件的全文既浪费精力又容易抓不住重点。1.2 传统方案的局限性为了解决长程记忆问题业界已经有不少尝试。上下文压缩对早期历史做摘要再把摘要注入提示词。问题在于摘要会丢失细节且摘要本身也是模型生成的存在错误传播。向量检索增强RAG把历史片段向量化存入向量库需要时检索。问题在于只解决“找什么”不解决“记什么”而且检索噪声会让模型更混乱。外部数据库把结构化信息存入数据库由代码逻辑决定读写。问题在于数据库 schema 设计复杂且缺乏与模型决策的动态耦合。这些方案都有一个共同盲区它们只考虑了“记忆的存储”没有考虑“记忆如何参与智能体的实时决策”。Recuris 的双记忆机制正是从这里切入。1.3 Recuris 的双记忆机制到底是什么Recuris 的核心思想并不复杂将智能体的记忆系统分为工作记忆Working Memory和长期记忆Long-term Memory两个独立子系统并建立二者之间的流转协议。工作记忆用于存放当前任务执行过程中正在被关注的短期信息容量有限相当于人类大脑的“工作台”。任务完成后工作记忆可以清空或部分归档。长期记忆用于存放跨任务稳定的知识与事实容量近乎无限相当于人类大脑的“长期存储区”。需要时通过检索将其相关内容装载回工作记忆。更巧妙的是Recuris 内部还进一步区分了显式记忆和隐式记忆。显式记忆是可以用自然语言或结构化数据明确表达的比如“用户偏好蓝色主题”隐式记忆则是从行为模式中自动归纳出来的比如“当用户提到首页加载慢时后续排查方向通常先看接口耗时”。两者共同构成长期记忆使得智能体既能记住事实又能积累经验。这种设计带来的直接好处是智能体不再把所有历史当作同一种信息处理而是按“当前任务关联度”动态组织记忆既能保证当前步骤拿到准确上下文又能让历史经验沉淀下来。1.4 这篇文章的读者与收获如果你正在做以下工作这篇文章会非常有用开发多步骤任务的 AI Agent比如自动写报告、数据清洗、代码重构工具。做 RAG 应用希望从简单的“检索增补”升级为“记忆增强”。研究 LLM 的评测与推理需要一套可复用的长任务成功率提升方案。读完本文你会理解 Recuris 双记忆机制的设计原理掌握一个最小实现的完整链路并了解实际工程落地时需要避开的坑。2. 双记忆机制的核心概念与原理2.1 长程智能体与“记忆周期”要理解 Recuris先得建立一个“记忆周期”的视角。一个长程智能体的生命周期通常包含以下环节接收任务指令。拆解子目标。调用工具或模型完成子步骤。汇总中间结果。输出最终结果。在这个过程中记忆应该围绕任务生命周期动态变化。任务刚开始时工作记忆需要装载任务目标每完成一步工作记忆要更新状态遇到新知识时应该写入长期记忆任务结束后工作记忆应当被释放或压缩避免影响下一任务。很多智能体失败正是因为缺少这个“记忆周期”的管理。没有“何时记、记什么、丢什么”的规则所有信息只能在提示词里堆积。2.2 双记忆机制的两层设计Recuris 将记忆分为两层。第一层是工作记忆Working Memory对应“当下”。它保存的是当前任务轮的上下文包括用户目标。当前子任务。最近几步的执行结果。临时决策依据。工作记忆容量有限通常为核心任务的上下文窗口或者一个固定大小的缓存。当上下文超过限制时旧信息会被主动压缩或归档而不是简单地截断。第二层是长期记忆Long-term Memory对应“过去”。它保存两种内容显式记忆事实、偏好、已完成的关键事件。隐式记忆从历史行为中总结出的模式和策略。长期记忆不直接参与当前推理而是通过检索机制将最相关的片段装载到工作记忆再提供给模型。一次完整的决策过程是模型读取工作记忆 → 判断是否需要更多背景 → 从长期记忆中检索相关内容 → 将检索结果写入工作记忆 → 模型基于新的工作记忆生成输出 → 任务状态更新。2.3 显式记忆与隐式记忆的分工显式记忆很容易理解它是可查询的、可验证的。例如{ user_preference: dark_theme, project_language: Python, completed_steps: [parse_data, train_model] }这些信息可以直接存入 JSON、SQLite 或 KV 存储需要时精确读取。隐式记忆则更有趣。它不是用户或系统显式给出的而是通过分析历史任务行为自动形成的。例如智能体发现“当错误日志中出现 OOM 时下一步执行free -m和df -h的步骤成功率更高”于是把这个“经验模式”存入记忆库。下次再遇到 OOM即使当前日志没有明确提示智能体也能从隐式记忆中提取出可能的排查路线。隐式记忆的存储可以是向量化的“行为片段”也可以是一组带权重的规则。Recuris 的常见做法是采用“摘要向量”的混合格式既能做语义匹配又能保证关键细节不丢失。2.4 双记忆机制与传统 RAG 的区别很多人会把双记忆机制误认为“升级版 RAG”实际上两者的关注点不同。维度传统 RAGRecuris 双记忆机制存储对象外部知识文档智能体自身运行状态、任务历史、行为经验检索时机用户查询时触发任务过程中按记忆管理协议动态触发写入策略知识库离线更新或在线写入与决策解耦与决策耦合任务中新信息会被主动记忆遗忘机制无或简单过滤有明确的工作记忆刷新 / 长期归档策略目标增强模型事实回答能力增强智能体长程连续决策能力简而言之RAG 解决的是“知识进肚子”双记忆机制解决的是“智能体别失忆”。两者可以共存但定位不同。2.5 为什么双记忆能提升成功率支撑双记忆机制有效性的核心逻辑有三个降低干扰把当前任务从全量历史中隔离出来减少无关上下文对推理的干扰。保证连续性关键任务状态被结构化存储下次调用时能精确恢复而不是靠模型从大段文本中“找”出来。利用经验长期记忆中的隐式模型能让智能体在新任务中复用历史教训避免重复犯同一个错误。这可能就是 Recuris 在长程智能体任务上表现更好的原因它把原本“混沌的无状态模型 无限历史”变成了“有状态的管理器 按需调度记忆”从而让模型真正把注意力放在决策上。3. Recuris 架构设计与技术选型理解了原理我们来看一个可落地的架构设计。这里以 Recuris 框架为例给出核心模块划分和推荐的技术选型。3.1 核心模块Recuris 双记忆机制的参考架构包含以下模块Agent Core负责任务拆解、工具调用、模型调用。Working Memory Buffer工作记忆缓冲区保存当前上下文和任务状态。Long-term Memory Vault长期记忆存储层支持显式记忆和隐式记忆。Memory Encoder将文本/事件编码为可存储的格式如向量、JSON。Retrieval Engine从长期记忆中检索相关片段。Memory Forecaster判断哪些信息需要进入长期记忆、哪些可以清理。这些模块可以嵌在一个 Python 类中也可以拆成微服务。对于中小型项目单进程实现足够了。3.2 技术选型建议针对不同部分推荐以下技术选型组件推荐选择说明工作记忆缓冲区Python 内的 deque / list容量小读快不需要持久化显式长期记忆SQLite / PostgreSQL存储结构化 JSON便于精确查询隐式长期记忆向量数据库例如 Chroma、Milvus、Qdrant存向量化后的行为片段向量编码模型开源 embedding 模型统一使用支持中文的 embedding 模型记忆调度逻辑自定义 Python 规则基于 token 数量和时间戳做优先级管理这里不对具体产品做绑定。实际项目中可以根据团队已有的存储设施灵活调整。3.3 一个简化架构图虽然没有 Mermaid 支持但我们用文字描述架构流程用户请求 - Agent Core | v Working Memory Buffer --- 检索结果: Retrieval Engine | ^ | | v | LLM 决策 ---------------------- | v 工具调用/执行结果 | v Memory Encoder - 长期记忆 Vault显式 隐式 | v Memory Forecaster判断新记忆、清理旧记忆在这条链路中工作记忆是模型的“眼前”长期记忆是模型的“书架”记忆管理协议就是“图书管理员”。4. 环境准备与前置条件下面进入实操环节。我们用一个最小 Python 实现来演示 Recuris 双记忆机制的运行逻辑。所有代码基于通用 Python 技术栈不依赖某个特定的商业框架。4.1 运行环境建议环境如下操作系统Windows 10/11、macOS、Linux 均可。Python 版本3.9 及以上。安装依赖openai或兼容 OpenAI 协议的 SDK、chromadb用于向量检索、pydantic用于数据模型。如果只是跑通流程不调用真实大模型也可以用固定的模拟输出来验证记忆管理逻辑。因为 Recuris 的核心在于记忆机制而不是模型本身。4.2 安装依赖创建一个项目目录recuris_demo然后新建requirements.txt# 文件路径requirements.txt openai1.30.0 chromadb0.5.0 pydantic2.7.0 python-dotenv1.0.1执行安装pip install -r requirements.txt注意以上版本号只是示例请以实际项目当前可用版本为准。如果安装较慢可以使用国内镜像源。4.3 准备 LLM API KeyRecuris 本身不消耗 API但最终决策需要使用大模型。建议配置环境变量export OPENAI_API_KEYyour-api-key如果你使用的是兼容 OpenAI 协议的其他模型服务也可以通过环境变量单独配置LLM_BASE_URL。5. 核心流程拆解在落地双记忆机制时最关键的是四个流程记忆写入、记忆组织、记忆检索、记忆遗忘。5.1 记忆写入记忆写入有两个入口显式记忆写入当任务状态发生重要变化时把结构化信息写入长期记忆。例如“用户指定了输出格式”。隐式记忆写入当完成任务后对执行过程做摘要并把摘要向量化后写入长期记忆。建议在智能体每次工具调用后自动触发一次“记忆评估”而不是每步都写。判定维度包括这个信息是否对后续步骤有用这个信息是长期稳定的事实还是临时状态如果不写入任务中断后能否恢复5.2 记忆组织记忆组织是指将新旧记忆按主题或时间线归档。显式记忆可以使用标签tag和命名空间namespace隐式记忆可以通过聚类算法或人工定义类别。示例结构namespace: user_project - key: preferred_theme value: dark - key: completed_step value: [data_load, preprocess] namespace: experience - vector: [0.12, 0.33, ...] text: 当输入数据包含空值时优先使用 fillna(unknown) 处理5.3 记忆检索记忆检索是在当前任务上下文中从长期记忆库中召回与当前状态最相关的历史片段。检索触发时机有两种明确触发Agent Core 发现需要背景知识。自动触发当工作记忆容量超过阈值自动从长期记忆中检索关键信息来替代旧上下文。检索结果需要做相关性排序并控制召回数量避免一次召回过多的噪声。5.4 记忆遗忘遗忘机制是 Recuris 最容易被忽略的部分。没有遗忘长期记忆也会变成垃圾场。遗忘策略常见有三种时间衰减超过一定时间的记忆降低优先级。空间替换工作记忆满了最旧的弱关联记忆被移出。主动归档任务完成后将临时状态清空只保留摘要。遗忘不是删除而是“降级”。对于长期记忆可以平滑地将不常用的旧记忆标记为archive并不参与常规检索。6. 完整示例代码实现下面我们实现一个简化版 RecurisAgent。它不是生产级代码但展示了双记忆机制的核心可运行逻辑。6.1 基础数据结构定义# 文件路径recuris_demo/models.py from dataclasses import dataclass, field from typing import Any, Dict, Optional dataclass class MemoryItem: 单条记忆项 content: str memory_type: str # short 工作记忆, long 长期记忆 importance: float 0.0 metadata: Dict[str, Any] field(default_factorydict) timestamp: float 0.0 dataclass class WorkingMemory: 工作记忆缓冲区 capacity: int 6 items: list[MemoryItem] field(default_factorylist) def add(self, item: MemoryItem): self.items.append(item) if len(self.items) self.capacity: # 简单淘汰最旧或重要度最低的 self.items.sort(keylambda x: (x.importance, x.timestamp)) removed self.items.pop(0) return removed return None def snapshot(self) - str: return \n.join([i.content for i in self.items])6.2 双记忆管理核心类# 文件路径recuris_demo/agent.py import json import sqlite3 import time from typing import List, Optional from models import WorkingMemory, MemoryItem class LongTermMemoryStore: 用 SQLite 存储显式记忆用内存列表模拟向量索引 def __init__(self, db_path: str memory.db): self.conn sqlite3.connect(db_path) self._init_table() # 简化版向量索引实际项目可用 Chroma 等向量库 self._vector_items [] def _init_table(self): self.conn.execute( CREATE TABLE IF NOT EXISTS long_term_memory ( id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT, value TEXT, importance REAL, timestamp REAL ) ) self.conn.commit() def save_explicit(self, key: str, value: str, importance: float 0.5): self.conn.execute( INSERT INTO long_term_memory (key, value, importance, timestamp) VALUES (?,?,?,?), (key, value, importance, time.time()) ) self.conn.commit() def retrieve_explicit(self, key: str) - Optional[str]: cursor self.conn.execute( SELECT value FROM long_term_memory WHERE key ? ORDER BY timestamp DESC LIMIT 1, (key,) ) row cursor.fetchone() return row[0] if row else None def save_implicit(self, text: str, embedding: List[float], importance: float 0.5): self._vector_items.append({ text: text, embedding: embedding, importance: importance, timestamp: time.time() }) def retrieve_implicit(self, query_embedding: List[float], top_k: int 2) - List[str]: if not self._vector_items: return [] # 简化相似度计算内积 scored [] for item in self._vector_items: score sum(a * b for a, b in zip(query_embedding, item[embedding])) scored.append((score, item[text])) scored.sort(reverseTrue, keylambda x: x[0]) return [text for _, text in scored[:top_k]] class RecurisAgent: def __init__(self, llm_call_func, capacity: int 6): self.working_memory WorkingMemory(capacitycapacity) self.long_term_memory LongTermMemoryStore() self.llm_call llm_call_func # 实际项目中传入调用 LLM 的函数 self.step_count 0 def act(self, observation: str) - str: 执行一步决策观察 - 记忆读取 - LLM决策 - 更新记忆 self.step_count 1 timestamp time.time() # 1. 将当前观察写入工作记忆 working_item MemoryItem( contentfStep {self.step_count}: {observation}, memory_typeshort, importance0.3, timestamptimestamp ) removed self.working_memory.add(working_item) # 2. 从长期记忆中检索相关事实显式 user_pref self.long_term_memory.retrieve_explicit(user_preference) if user_pref: self.working_memory.add(MemoryItem( contentfUser preference: {user_pref}, memory_typeshort, importance0.7, timestamptimestamp )) # 3. 构建给 LLM 的上下文 context self.working_memory.snapshot() # 4. 调用 LLM decision self.llm_call(context) # 5. 决策后将新信息写入长期记忆 self.long_term_memory.save_explicit(last_decision, decision, importance0.6) if removed: # 工作记忆淘汰的旧信息可以把重要性较高的摘要沉淀到长期记忆 self.long_term_memory.save_explicit( archived_memory, removed.content, importance0.1 ) return decision6.3 模拟长程任务执行的示例为了演示双记忆机制如何提升长程任务成功率我们模拟一个 3 步的长任务其中第 2 步需要临时“遗忘”第 1 步的细节但能从长期记忆中恢复关键偏好。# 文件路径recuris_demo/run_demo.py from agent import RecurisAgent def make_llm(steps): 用预设步骤模拟 LLM 输出 step_index {step: 0} def call(context: str): # 实际项目应替换为真实 LLM 调用 print( 当前工作记忆 ) print(context) print( 决策过程 ) result steps[step_index[step]] step_index[step] 1 return result return call if __name__ __main__: # 模拟一个长任务分析数据 - 生成代码 - 总结报告 steps [ 已分析数据发现空值率 5%, 生成清洗代码使用 fillna 处理空值, 报告生成完毕建议使用 dark 主题展示 ] agent RecurisAgent(llm_call_funcmake_llm(steps)) # 先写入一个长期偏好 agent.long_term_memory.save_explicit(user_preference, dark_theme, importance1.0) for i, obs in enumerate([开始分析, 准备清洗, 生成总结]): print(f\n--- 第 {i1} 步 ---) decision agent.act(obs) print(fAgent 决策: {decision})在这个示例中可以看到每一步工作记忆都在更新同时长期记忆保存了用户偏好和归档信息。这模拟了双记忆之间的流转。6.4 引入向量的隐式记忆检索示例上面的代码刻意没有引入真正的向量检索因为那会增加依赖复杂度。实际项目中你可以使用 Chroma 等库替换_vector_items。下面给出一个接入 Chroma 的示例片段# 文件路径recuris_demo/vector_retrieval.py import chromadb from chromadb.utils import embedding_functions client chromadb.Client() collection client.get_or_create_collection( implicit_memory, embedding_functionembedding_functions.DefaultEmbeddingFunction() ) # 写入一条隐式记忆 collection.add( documents[遇到 OOM 时先检查数据量再考虑扩容], ids[exp_001], metadatas[{importance: high}] ) # 检索 results collection.query( query_texts[内存不足如何排查], n_results1 ) print(results[documents])这一段显示了隐式记忆的向量化检索流程。Recuris 的优势在于这些检索结果会被写回工作记忆参与后续每一步决策。7. 运行结果与效果验证7.1 运行上面的示例在项目目录执行python run_demo.py预期输出--- 第 1 步 --- 当前工作记忆 Step 1: 开始分析 User preference: dark_theme 决策过程 Agent 决策: 已分析数据发现空值率 5% --- 第 2 步 --- 当前工作记忆 Step 1: 开始分析 User preference: dark_theme Step 2: 准备清洗 Agent 决策: 生成清洗代码使用 fillna 处理空值 ...从输出可以看到用户偏好dark_theme一直存在于工作记忆中说明长期记忆成功参与决策。步骤越多这种优势越明显。7.2 如何判断成功验证双记忆机制是否有效建议从四个指标观察指标判断标准步骤中断率长任务执行中出现明显逻辑断裂的比例降低关键信息恢复率任务后期能否准确引用早期的重要偏好/结论上下文 token 消耗在相同任务下是否比“全量历史拼接”消耗更少最终任务成功率任务完成度、结果准确性是否提升特别是“关键信息恢复率”这一项是双记忆机制区别于普通上下文截断的核心指标。7.3 失败时先看哪里如果示例运行报错优先检查Python 版本是否符合要求。依赖是否安装完整。数据库文件是否可写。如果调用真实 LLM API检查网络和 Key。8. 常见问题与排查思路在工程中落地 Recuris 双记忆机制大家通常会遇到以下问题。这里整理成排查表。问题现象可能原因排查方式解决方案工作记忆频繁溢出容量设置太小或记忆写入策略过于激进打印工作记忆快照统计单步 token 占用适当增大容量降低低重要性记忆的写入频率长期记忆检索结果与当前任务无关向量检索阈值太低或者索引中没有合适数据检查检索相似度分数手动查询测试提高阈值使用混合检索关键词向量关键偏好没有被装载回来偏好存储在长期记忆但检索逻辑没有关联到当前 context检查检索触发条件打印召回结果将高频偏好设置为 always_load显式加入工作记忆任务完成后工作记忆释放不干净没有实现主动清理逻辑检查任务结束时是否调用 reset 方法增加任务完成后的 memory reset隐式记忆噪音太多对执行过程做摘要时没有过滤无效信息检查隐式记忆内容看是否有重复和无关文本增加摘要模板引导模型输出结构化经验引入向量库后性能下降检索调用频率过高或 embedding 模型耗时过大记录每个环节耗时增加缓存降低检索频率异步预检索9. 最佳实践与工程建议理论适合代码能跑但要真正让 Recuris 双记忆机制在生产中发挥作用还需要注意工程细节。9.1 记忆条目要设计“重要性”和“生命周期”每条记忆建议至少包含三个字段importance重要程度用于决定是否进入长期记忆。timestamp时间戳用于时间衰减。ttl生存时间超过后自动归档。没有生命周期的记忆是一条“脏数据”。长程智能体的记忆库需要定期清理或合并。9.2 显式记忆优先于隐式记忆在决策链路中显式记忆如用户偏好、任务约束应优先被加载。隐式记忆只作为补充。避免把概率性的经验当成确定的事实参与推理。9.3 记录每次记忆调度日志生产环境中要能看到“哪一步从长期记忆中检索了什么、为何被遗忘”。建议在 Memory Forecaster 中增加结构化日志格式类似{ event: memory_write, mem_type: long, key: user_preference, importance: 0.8, task_id: task_20250101_001 }这样不仅方便排查问题也能为后续策略优化提供数据。9.4 双记忆机制与 RAG 可以共存如果你的智能体除了任务记忆还需要外部知识库可以同时部署两个检索通道一个从 Recuris 长期记忆检索历史经验一个从知识库 RAG 检索领域知识。两者结果写入工作记忆时要打上不同的 source 标签。9.5 安全边界记忆库中不要存敏感信息长程智能体的记忆库可能包含用户对话内容、业务数据。如果记忆库直接以明文存储一旦泄露风险极高。建议对敏感字段加密存储。对记忆检索结果做脱敏处理。不把 API Key、密码、个人隐私写入长期记忆。9.6 评估体系要专门设计不要只用“最终成功率”来判断记忆机制好坏。建议设计两类评估单步决策准确率每一步决策是否正确。跨步骤一致性第 N 步的结论是否和第 N-5 步的已知前提冲突。后者是长程智能体特有的指标也是双记忆机制最想优化的目标。10. 总结与后续学习方向Recuris 双记忆机制的价值不在于提出一个全新的 AI 理论而在于把“记忆管理”从隐性的提示词工程变成了显式的系统设计。它用工作记忆保证当前任务的聚焦用长期记忆沉淀跨任务的经验通过一套可执行的协议让智能体知道什么时候记、什么时候取、什么时候丢。这种设计对长程智能体的成功率提升具有直接且可度量的作用。我建议你从本文第六节的代码开始先跑通一个 5 到 10 步的任务然后逐步把真实 LLM 调用接进来。你会发现当你给智能体配上一套双记忆系统后它的“翻车”概率会明显下降。下一步可以继续深入研究向量检索的混合召回策略。隐式记忆的自动摘要与经验挖掘。多智能体间的记忆共享与权限隔离。记忆压缩与遗忘的替换策略。这些方向都值得在 Recuris 的双记忆框架之上继续探索。如果你正在做长程 Agent 应用希望本文能成为你记忆系统设计的第一份参考。