1. 项目概述从“分层记忆”到智能体记忆系统的工程实践最近在折腾智能体Agent相关的项目发现一个绕不开的核心难题记忆管理。无论是构建一个能持续对话的聊天机器人还是一个能自主完成复杂任务的自动化助手如何让它记住过去发生的事情并根据上下文做出合理决策是决定其智能程度的关键。这让我想起了开源项目Cat-tj/hierarchical-memory它直译过来就是“分层记忆”。这个名字本身就充满了吸引力它暗示了一种结构化的、非扁平的记忆处理方式就像我们人类大脑处理信息一样有短期、长期有重要、次要之分。这个项目本质上是一个为智能体设计的记忆管理系统。它试图解决传统智能体开发中记忆要么是简单的对话历史堆砌很快超出上下文窗口要么是粗暴地全部存入向量数据库检索效率低且无关信息干扰大的痛点。其核心思想是模仿人类的记忆机制构建一个多层次的记忆结构让智能体能够更高效、更智能地利用历史信息。对于任何正在开发具有长期交互或复杂任务执行能力的AI应用开发者来说理解和实现一套好的记忆系统是项目从“玩具”走向“可用”甚至“好用”的关键一步。2. 核心设计思路为何“分层”是更优解在深入代码之前我们必须先理解“分层记忆”背后的设计哲学。为什么简单的“全部记住”或者“只记最后几句”不行想象一下你正在和一个朋友策划一场为期一周的旅行。你们的对话会涉及很多信息最终确定的航班日期关键事实、讨论过的但被否决的酒店选项次要背景、你随口提了一句讨厌吃香菜个人偏好、以及每天琐碎的“明天几点出发”的确认短期操作。如果把这些信息不加区分地全部塞进每次对话的上下文不仅会浪费宝贵的Token对于大模型而言就是成本和性能还会让模型在需要做决策时比如推荐餐厅被大量无关信息干扰。hierarchical-memory的思路就是对这些信息进行分类和分级处理。通常一个分层记忆系统会包含以下几个层次感官记忆/工作记忆相当于模型的当前上下文窗口。它容量极小但处理速度极快存放着正在被直接处理和使用的信息比如当前一轮对话的查询和刚刚生成的回答。短期记忆保存近期发生的、可能还需要被频繁访问的信息。例如在当前任务会话中提到的用户目标、刚刚执行过的几个步骤及其结果。这部分记忆需要有较高的检索优先级但也会随着时间或会话结束而逐渐淡化或转移。长期记忆存储重要的、需要持久化的知识、用户事实、任务结果等。比如用户的姓名、偏好、已完成的重要任务的核心结论。这部分记忆容量大但检索成本相对高需要借助向量检索等技术从海量信息中精准召回。元记忆这是更高级的一层用于管理记忆本身。例如记忆的优先级、关联性、访问频率、甚至“遗忘”机制。它决定哪些信息从短期记忆沉淀到长期记忆哪些信息应该被衰减或删除。项目的设计正是基于这样的认知架构。它不是简单地将所有对话历史存入向量数据库而是先对记忆进行“重要性”或“相关性”打分然后决定其存储的层级和生命周期。这样当智能体需要回忆时它可以先快速扫描工作记忆和短期记忆如果没有找到再去长期记忆中进行更耗资源的精确检索从而在响应速度和记忆深度之间取得最佳平衡。2.1 记忆的表示与编码如何将一段非结构化的自然语言对话或事件转化为可以被系统存储和处理的“记忆单元”这是第一个工程挑战。常见的做法是进行结构化提取。一种实用的方法是利用大模型本身的信息提取能力。例如当智能体完成一次交互后我们可以将这段交互文本包括用户输入和智能体响应发送给一个大模型并要求其提取关键信息格式化为一个结构化的记忆对象。这个对象可能包含以下字段{ “memory_id”: “uuid”, “content”: “用户表示他更喜欢在晚上工作因为白天比较吵。”, “embedding”: [0.12, -0.05, …, 0.78], // 文本内容的向量表示 “type”: “user_preference”, // 记忆类型事实、任务、事件、偏好等 “importance”: 0.7, // 重要性评分0-1 “timestamp”: “2023-10-27T14:30:00Z”, “entities”: {“user”: “true”, “time”: “night”}, // 涉及的实体 “access_count”: 5, “last_accessed”: “2023-10-28T09:15:00Z” }其中embedding字段至关重要它是后续进行语义相似度检索的基础。importance字段可以由规则如是否包含关键词、是否来自特定类型的任务或另一个评分模型来生成它直接决定了这条记忆初始应被放入短期记忆池还是长期记忆池。注意让大模型为每段交互生成记忆摘要本身会产生额外的API调用成本和延迟。在实际工程中需要权衡实时性和成本。一种折中方案是异步处理或者仅对满足特定条件如对话轮次结束、任务关键节点的交互进行记忆提取。2.2 分层存储的介质选择不同的记忆层级对存储介质的读写速度、查询方式和成本要求不同。工作记忆通常直接保存在应用程序的内存RAM中作为会话状态的一部分。查询就是直接访问变量速度极快。短期记忆可以放在内存缓存里如 Redis 或 Memcached。它们提供比纯内存更结构化的存储和一定的持久化能力防止应用重启丢失并且支持设置过期时间TTL非常适合存放需要存活一段时间但非永久的信息。长期记忆这里是向量数据库的主场。如 Pinecone、Weaviate、Qdrant 或开源的 Chroma、Milvus。它们专门为高维向量即我们的embedding的快速相似性搜索而优化。同时为了支持按元数据如type,timestamp过滤所选用的向量数据库最好也支持标量过滤。hierarchical-memory项目的价值之一可能就是提供了一套抽象接口让开发者可以灵活地为每一层配置不同的存储后端而不必关心底层细节。3. 核心流程拆解记忆的写入、读取与更新理解了设计思路和数据结构后我们来看一个记忆在系统中完整的生命周期是如何运转的。这主要包括三个核心操作记忆的写入编码与存储、记忆的读取检索与召回、记忆的更新强化与遗忘。3.1 记忆写入流程当智能体产生一段需要记住的经历后例如完成一轮对话或一个任务步骤写入流程便启动了。原始信息收集系统收集上下文信息通常包括用户查询、智能体回复、工具调用结果、环境状态等。记忆提取与编码调用记忆提取器通常是一个提示词工程或微调的小模型从原始信息中抽取出结构化的记忆对象。同时使用文本嵌入模型如text-embedding-3-small、bge-m3或本地部署的all-MiniLM-L6-v2为记忆的content生成向量。重要性评估根据预定义的规则或模型为记忆对象打分。规则可能包括是否包含用户明确指令高分、是否属于闲聊低分、是否来自成功的关键任务步骤高分等。层级路由根据重要性分数、记忆类型等决定其初始存储层级。高分且类型为user_preference或critical_fact的记忆可能直接存入长期记忆。中等分数、与当前会话强相关的记忆存入短期记忆。低分或临时性信息可能仅保留在工作记忆中随会话结束而丢弃。存储执行将记忆对象包括元数据和向量存入对应层级的存储后端。这个流程中异步化是关键优化点。记忆提取和向量编码可能是计算密集型或IO密集型的不应阻塞智能体的主响应链路。我们可以将这些操作放入任务队列如 Celery、RabbitMQ由后台工作进程异步处理。3.2 记忆读取检索流程当智能体需要根据当前上下文做出决策或回应时它需要从记忆中寻找相关信息。检索不是简单地从长期记忆里做向量搜索而是分层、分步进行的。检索键生成基于当前对话或任务状态生成检索查询。这通常包括查询文本当前用户的问题或任务的描述。查询向量将查询文本编码为向量。过滤条件如时间范围只检索最近一周的记忆、记忆类型、关联的实体等。分层检索第一层工作记忆直接检查当前会话状态中是否有直接相关的信息。这一步最快几乎是零延迟。第二层短期记忆在缓存中根据记忆的键如session_id:user_id或简单的关键词进行查找。由于数据量小速度也很快。第三层长期记忆如果前两层没有找到足够相关或充分的信息则启动对向量数据库的查询。使用查询向量进行相似度搜索如余弦相似度并结合元数据过滤召回最相关的 K 条记忆。结果融合与重排序将从不同层级检索到的记忆片段合并。这里可能会出现重复或冲突的信息例如短期记忆和长期记忆都有关于用户喜好的记录但数值不同。需要一个融合策略比如优先采用更高重要性分数的记忆或时间更近的记忆或者将冲突信息都提供给大模型让它自行判断。上下文构建将最终筛选和排序后的记忆以自然语言的形式重新组织插入到发给大模型的提示词Prompt的特定位置如“以下是相关的历史信息”部分作为模型生成回答的参考。实操心得检索的top K值设置和相似度分数阈值需要仔细调优。K值太大会引入噪声太小可能遗漏关键信息。相似度阈值太低会召回大量不相关记忆太高则可能空手而归。建议根据实际场景进行AB测试观察不同参数下智能体回答的质量和相关性。3.3 记忆的更新与遗忘记忆不是一成不变的。一套好的系统必须能模拟记忆的强化和遗忘。强化当一条记忆被频繁访问access_count增加其重要性分数可以适当提升。当来自不同时间、不同会话的记忆都指向同一个事实时例如多次提到“喜欢咖啡”该事实的记忆可以被合并和强化重要性变得极高。遗忘/降级这是分层记忆系统的精髓。基于时间的遗忘短期记忆中的项目如果超过一定时间未被访问其重要性分数会衰减。当分数低于某个阈值时它会被从短期记忆中移除。它可以被彻底删除也可以被转移到长期记忆的“低优先级”区域。基于空间的遗忘当短期记忆池已满时需要根据某种策略如最近最少使用LRU、重要性最低优先淘汰旧记忆为新记忆腾出空间。主动遗忘系统可以设定规则定期清理长期记忆中重要性极低、且很久未被访问的记忆。或者当用户明确表示某个信息已过时“我搬家了旧地址不对了”系统应能定位并更新或删除对应的旧记忆。实现一个动态衰减函数是常见的做法例如重要性分数每天衰减0.05每次被访问则增加0.1这样活跃的记忆会保持高分而不活跃的记忆会慢慢“沉入”底层或被清理。4. 工程实现要点与避坑指南理解了理论我们来看看在代码层面实现一个分层记忆系统需要注意什么。虽然Cat-tj/hierarchical-memory的具体实现需要看其源码但我们可以勾勒出核心模块和常见陷阱。4.1 模块化设计一个良好的系统应该高度模块化便于更换底层组件。记忆提取器接口定义extract_memory(raw_text: str) - List[Memory]方法。可以实现基于规则正则匹配关键词、基于模板固定句式或基于模型调用LLM的不同提取器。存储后端接口为每一层定义统一的存储接口如save(memory),search(query_embedding, filters),delete(memory_id)。这样短期记忆可以从 Redis 切换到 Memcached长期记忆可以从 Pinecone 切换到 Chroma而核心业务逻辑无需改动。路由策略接口定义route(memory: Memory) - StorageLevel方法。可以实现基于固定分数阈值的路由也可以实现一个轻量级分类模型来决策。4.2 向量模型的选择与优化长期记忆的检索质量严重依赖于文本嵌入模型。选择通用场景下OpenAI 的text-embedding-3系列效果很好但需付费。开源模型中BAAI/bge-m3、intfloat/multilingual-e5-large都是强有力的竞争者。选择时需考虑支持的语言、上下文长度、向量维度影响存储和检索成本、速度和精度。优化本地缓存对相同的文本内容其向量编码结果应该被缓存起来避免重复计算。批量编码异步处理记忆写入时应积攒一定数量的记忆后再批量调用嵌入模型API或本地模型推理以提高吞吐量。维度缩减一些向量数据库支持降维存储。如果选用高维模型如1536维可以评估在存储前进行PCA降维是否在可接受的精度损失下大幅提升性能。4.3 确保记忆的一致性这是分布式、异步系统中的一个经典难题。例如用户说“我的名字是Alice”系统异步提取并存储了这条记忆。紧接着用户问“我叫什么”如果检索操作在记忆写入完成之前执行就会找不到答案。写后读一致性对于短期记忆可以利用缓存数据库的原子操作特性来保证。对于长期记忆一种方案是采用“双写”策略先将记忆写入一个快速的、一致性容易保证的临时存储如消息队列或数据库的待处理表并标记为“处理中”。检索时既要查正式的向量库也要查这个临时存储。后台进程异步完成向量化和写入向量库后再从临时存储中移除该项。记忆冲突处理当新旧记忆冲突时如“喜欢咖啡” vs “现在不喜欢咖啡了”除了前面提到的基于时间和重要性的策略更复杂的方法可以引入“记忆版本链”或依赖大模型进行冲突消解。4.4 性能与成本监控记忆系统会成为智能体应用的新性能瓶颈和成本中心必须加以监控。关键指标写入延迟从信息产生到记忆可用可被检索到的时间。检索延迟95分位和99分位的检索耗时。检索命中率从工作/短期记忆中找到答案的比例 vs 需要查询长期记忆的比例。记忆增长量每天新增的记忆条数和存储容量。API成本调用嵌入模型和LLM进行记忆提取所产生的费用。成本控制设定记忆提取的采样率并非每一轮对话都必须提取记忆。定期清理低价值记忆控制向量数据库的索引大小。对于内部使用的智能体可以考虑使用更小、更快的本地嵌入模型。5. 进阶思考与应用场景拓展实现基础的分层记忆后我们可以思考更高级的功能和更广泛的应用场景。5.1 记忆之间的关联与推理单纯的“提问-检索”模式还不够智能。更高级的系统可以建立记忆之间的关联图。例如记忆A“用户完成了项目X的部署”和记忆B“项目X使用了技术栈Y”可以自动关联。当用户后来询问“我们之前用技术栈Y做过什么”时系统不仅能通过向量相似度找到B还能通过关联找到A从而给出更完整的答案“您曾将其用于项目X的部署”。这需要在对记忆进行编码时额外进行实体和关系抽取并利用图数据库进行存储和查询。5.2 应用于复杂任务执行对于需要多步骤、长时间运行的任务型智能体如自动编写代码、分析数据、操作软件分层记忆系统能发挥巨大作用。短期记忆存放当前任务的具体规划、已执行的步骤及其结果、当前步骤的上下文。长期记忆存放任务的目标、从历史类似任务中学习到的通用经验“遇到这种错误通常可以检查网络连接”、以及最终的任务成果总结。工作记忆就是当前正在思考的这一步动作。这样的设计使得智能体在执行长任务时不会迷失能够记住目标并从过去的成功或失败中学习。5.3 个性化与用户画像构建通过长期记忆持续积累用户偏好、习惯和事实系统可以逐渐构建起精细化的用户画像。这些画像本身可以作为更高阶的“记忆”用于个性化推荐、调整对话风格、甚至预测用户需求。例如系统发现用户总是在周一早上询问一周的工作安排那么可以在周一早上主动推送相关的汇总信息。这里的挑战在于隐私和安全需要明确告知用户并获取同意并对存储的敏感信息进行加密处理。构建一个像Cat-tj/hierarchical-memory这样的分层记忆系统是一个典型的从理论到工程的落地过程。它没有使用什么高深莫测的算法更多的是对现有组件缓存、向量数据库、嵌入模型、任务队列的巧妙整合和基于业务逻辑的规则设计。其价值不在于技术的独创性而在于为解决AI智能体“记性差”这个普遍问题提供了一个清晰、可扩展、高效的架构蓝图。在实际开发中你可能不需要完全照搬但理解其分层的思想并根据自己项目的具体需求数据量、实时性要求、成本预算进行裁剪和实现无疑能让你构建的智能体变得更加“聪明”和“善解人意”。