本篇笔记不仅讲了理论还从工程化的角度如何落地进行了展开希望看完有所收获能集成进自己的系统中 主要是网上的文章多从理念出发 不够详细 也没有讲解应用可能有但是还是自己梳理吧 也是无奈之举 有什么不对尽情说 后续会对文章进行更改 都以学习出发注有些系统架构和实现算法中可能会跟openclaw会有些不一样 主要还是针对如何落地去进行记录和设计 其实就没怎么讲openclaw的设计 要看概念设计的话 去找找吧 应该还是很多的一、Memory 的本质LLM 为什么“要有Memory”原生缺陷能力LLM表现长期记忆没有原生LLM无内置长期存储仅依赖当前上下文窗口用户建模没有无法主动记录用户固定特征、偏好等状态连续性没有对话中断后无法恢复之前的交互状态历史理解仅限上下文窗口窗口外的历史对话完全无法感知窗口内也会因长度限制被截断解决不了这个用户是谁”传统未集成memory的RAG侧重外部知识检索无法记录用户动态特征和个性化状态Memory概要维度Memory数据来源用户行为对话、操作、偏好等动态数据时间维度强核心是记录用户状态随时间的演化时间影响记忆权重结构状态结构化/半结构化数据聚焦用户特征和行为状态更新方式动态随用户交互实时/异步更新自动演化总结Memory 用户状态的持续演化系统核心认知记录用户从交互开始到当前的所有关键状态变化动态调整服务于个性化交互二、完整系统架构Memory 生命周期用户行为对话输入、操作反馈等 ↓ 记忆生成Writing→ 筛选、提取、压缩关键信息 ↓ 存储Storage→ 结构化存储到数据库/向量库 ↓ 检索Retrieval→ 结合当前需求,筛选出最有价值的记忆 ↓ 参与推理Injection→ 将记忆融入LLM上下文,动态生成prompt,辅助生成回答 ↓ 被使用Access→ 记忆被LLM调用,用于回答用户问题 ↓ 强化 or 衰减Update / Decay→ 被使用则强化,长期未使用则衰减 ↓ 删除Cleanup→ 衰减到阈值以下或无效记忆,进行清理模块拆解工程视角1. Memory Writing写入→ 负责从用户行为中提取、筛选、压缩可记忆信息 2. Memory Schema结构→ 定义记忆的存储格式保证可检索、可扩展 3. Memory Storage存储→ 负责记忆的持久化存储数据库向量库 4. Memory Retrieval检索→ 根据用户当前需求快速筛选出有效记忆 5. Memory Injection注入→ 将检索到的记忆以合理格式融入LLM上下文 6. Memory Update更新→ 处理记忆冲突、更新记忆内容和权重 7. Memory Decay遗忘→ 模拟人类遗忘机制对长期未使用的记忆进行衰减 8. Memory Cleanup清理→ 清理无效、过期、低权重的记忆降低存储和检索成本三、Memory 分层3.1 为什么所有 memory 都走向量检索 → 成本高 混乱大量低价值、短期记忆占用检索资源导致高价值长期记忆检索效率下降补充分层的核心是“按记忆的生命周期和重要性分类采用不同的存储和检索策略”平衡效率和成本。3.2 三层结构Profile Memory用户画像特征稳定、长期如用户职业、核心偏好、长期目标不会频繁变化存储数据库如MySQL无需向量库结构固定可直接查询检索方式直接加载每次用户提问无需筛选直接加载所有Profile Memory确保回答贴合用户基本特征示例用户是“Python后端开发者”“喜欢简洁的技术文档”“长期目标是掌握云原生”。Episodic Memory事件记忆特征动态、上下文相关如用户近期做的项目、遇到的问题、近期计划随时间变化存储数据库向量库结构化存储属性向量库存储语义向量检索方式检索根据用户当前提问通过多因子评分筛选出最相关的事件记忆示例用户“最近用FastAPI做项目”“遇到Redis连接超时问题”。Working Memory短期工作记忆特征最近对话如当前会话的前3-5轮对话仅在当前会话有效会话结束后可清理或降级为事件记忆存储缓存如Redis无需持久化会话结束后可删除检索方式直接加载当前会话内的短期记忆直接融入上下文保证会话连续性示例用户在当前会话中“问过FastAPI的路由配置”“提到过使用Uvicorn作为服务器”。最终结构根据会话类型动态生成prompt[系统指令] # 固定定义LLM的角色和行为规则 [用户画像] # Profile Memory直接加载所有内容 [动态memory] # Episodic Memory检索出的Top N条高评分记忆 [当前问题] # 用户当前的提问 [短期对话历史] # Working Memory当前会话的最近对话补充Top N的取值建议3-5条过多会占用大量token过少则无法充分利用记忆具体根据项目来定。四、Memory Writing写入机制4.1 写入触发机制错误方式每条对话都写问题噪声爆炸大量无意义对话如“好的”“嗯”被存储干扰有效记忆检索成本高存储成本、后续检索成本、向量计算成本均会大幅上升污染 memory无效信息占用空间导致有效记忆被稀释检索准确率下降方式每轮对话结束 → 尝试写入 → 过滤后少量入库补充 为什么叫做尝试写入呢因为不能保证每一次的对话都有价值所以应该是每次“有效对话”结束后都会触发一次 memory 写入有效对话的判断也可以采用规则门控和LLM两者并行进入看到这个可能会有一个疑惑按照openclaw的记忆架构分层为L1 工作记忆层 (memory/YYYY-MM-DD.md) L2 长期记忆层 (MEMORY.md/USER.md/AGENTS.md) L3 技能记忆层 (skills/) L4 索引层 (新增)所以这一块对应着的是L1层 而它的作用是记录当天事务、临时信息特点: 每日新建文件记录、原始对话和任务、次日自动归档人家是这样干的呀 你这不是冲突了吗 但我要告诉你 这不仅仅不冲突 还是工程上的精妙之处L1 工作记忆 记录对话 任务日志 不压缩 不筛选 本质是日志而长期记忆是筛选后 抽象压缩过后的结构化的数据本质是知识而 L1 的真正作用是用来提供“完整上下文来源”如果你只存 memory你会丢失推理过程、任务上下文、中间状态而且很多系统会支持二次加工夜间任务扫描 L1 再做 memory 提取 这正是工程设计的魅力所在提供了Debug和可解释性并且在长任务的Agent场景中L1可以记录每一步每次尝试每个失败最后防止Memory污染因为如果没有L1那对memory你只有两种选择要么全存爆炸要么强筛丢信息有了之后因为原始信息还在所以memory可以更激进的筛选留下最关键核心的信息。4.2 写入时机用户输入 → LLM回答 → 返回用户立即优先保证交互响应速度 → 异步执行 memory 写入不阻塞用户交互后台完成筛选和存储为什么异步如果同步LLM回答2s Memory提取2s 4s 整个问答前后周期太差补充异步写入可使用后台任务队列如Celery或框架自带的后台任务如FastAPI的background_tasks实现确保不影响主交互链路。4.3 记忆裁判具体实现双层判断机制 规则LLM补充双层判断的核心是“先低成本过滤噪声再高精度筛选价值”平衡效率和准确性。第一层规则过滤cheap低成本、高速度简单例子def should_skip(text): # 过滤过短文本无有效信息 if len(text) 10: return True # 过滤无意义常用语噪声 if text in [好的, 谢谢, 嗯, 哦, 知道了, 收到]: return True # 过滤纯闲聊内容如“今天天气真好”无用户状态相关信息 if is_small_talk(text): return True # 可补充过滤重复内容如用户重复提问同一问题无需重复记录 if is_duplicate(text): return True补充is_small_talk可通过关键词匹配、简单语义模型实现无需复杂LLM降低成本。第二层LLM判断核心高精度、语义级筛选Prompt设计-简单例子请判断以下对话是否值得长期记忆 对话内容 用户{user_message} 助手{assistant_message} 判断标准满足任意1条即可视为值得记忆 1. 用户身份信息如职业、年龄、地域、联系方式等固定特征 2. 用户偏好如喜欢的技术、工具、风格厌恶的事物等 3. 用户长期目标如学习计划、项目目标、职业规划等 4. 用户重要事件如近期要做的事、已经完成的关键事、遇到的重要问题等 输出要求严格按照JSON格式输出不添加任何多余内容便于程序解析 { should_store: true/false, // true表示值得记忆false表示不值得 type: fact | preference | event | identity, // 对应上述判断标准的类型 content: 提取的核心记忆内容简洁不超过50字, // 仅保留关键信息 confidence: 0-1 // 置信度0表示完全不确定1表示完全确定 }精妙点“是否重要”是语义问题 → 只能靠 LLM规则无法判断语义层面的重要性如“我最近在学FastAPI”和“我今天吃了米饭”规则无法区分LLM可精准判断前者有记忆价值4.4 信息压缩Memory Compression为什么要做原始对话我最近在用FastAPI做项目还用到了Redis Streams感觉这两个工具搭配起来很高效不压缩token浪费原始句子包含冗余信息占用更多token增加存储和检索成本检索困难冗余信息会干扰向量相似度计算导致检索时无法精准匹配噪声多无关信息如“感觉很高效”属于主观感受无需长期记忆压缩后{ type: tech_stack, content: 使用FastAPI和Redis Streams做项目, tags: [backend, FastAPI, Redis] // 增加标签提升检索效率 }核心思想Memory 存“知识”不是“句子”核心是提取可复用、可检索的用户状态知识而非完整对话记录补充压缩可通过LLM实现Prompt可设计为“将以下对话中的用户关键信息提取出来压缩为简洁的结构化内容保留核心信息去除冗余”。五、Memory Schema结构设计5.1 设计目标可检索支持语义检索、标签检索、属性检索可排序支持按重要性、时间、访问次数等排序可扩展新增记忆类型时无需大幅修改结构可演化支持记忆内容和权重的动态更新5.2 三种设计方式对比全自由不现实{ anything: ... }问题无法检索无固定结构无法通过属性、标签筛选只能全量遍历不可控记忆格式混乱后续更新、清理难度极大易出现数据不一致全固定不现实{ age: 18, hobby: Python, job: developer }问题扩展性差新增记忆类型如“项目经验”“学习目标”需修改Schema结构LLM受限固定字段无法适配LLM提取的多样化用户信息易造成信息丢失半结构化补充半结构化 固定核心字段保证检索和排序 灵活扩展字段保证扩展性兼顾可控性和灵活性。标准结构{ id: uuid-xxx, // 唯一标识用于更新、删除、查询必填 user_id: user-xxx, // 关联用户实现多用户隔离必填 type: fact | preference | event | identity, // 记忆类型用于分类检索必填 content: 用户使用FastAPI和Redis Streams做项目, // 核心记忆内容必填 tags: [Python, backend, FastAPI], // 标签用于快速筛选可选推荐 embedding: [0.123, 0.456, ...], // 语义向量用于语义检索必填 importance: 0.8, // 重要性权重0-1影响检索优先级必填 confidence: 0.9, // LLM判断的置信度0-1用于筛选低置信度记忆必填 created_at: 2024-05-01 14:30:00, // 创建时间用于时间衰减必填 last_access: 2024-05-03 10:15:00, // 最后访问时间用于强化/衰减必填 access_count: 3, // 访问次数用于强化记忆权重必填 status: active | deprecated, // 状态活跃/过期用于处理冲突可选推荐 extension: {} // 扩展字段用于存储特殊类型的记忆信息可选 }5.3 三元组模型补充三元组模型适用于需要进行知识推理、关联查询的场景可与半结构化模型结合使用如将三元组存储在extension字段中。{ subject: user, // 主体通常为用户 predicate: likes, // 关系如喜欢、使用、擅长、计划 object: Python // 客体如技术、工具、目标 }示例扩展{subject: user, predicate: uses, object: FastAPI}优势可做知识图谱多个三元组可关联形成用户知识图谱如用户→使用→FastAPI用户→使用→Redis可关联出用户的技术栈可推理通过三元组关系推理用户潜在需求如用户喜欢Python→可能需要Python相关的技术支持可结构查询通过主体、谓词、客体组合查询如查询“用户使用的所有技术”六、Memory Retrieval检索机制6.1 检索触发每次用户提问用户发起新的提问时立即触发记忆检索确保回答能结合用户历史状态补充检索时机需与LLM生成回答同步但不阻塞检索结果作为上下文一部分传入LLM。6.2 多因子评分补充多因子评分的核心是“筛选出对当前回答最有价值的记忆”而非仅筛选“最相似”的记忆权重可根据业务场景调整。# 评分公式综合语义相关性、重要性、访问频率、时间衰减 score w1 * similarity # 语义相似度权重推荐w10.4 w2 * importance # 记忆重要性权重推荐w20.3 w3 * log(access_count 1) # 访问频率权重推荐w30.2log避免访问次数过高导致权重失衡 - w4 * time_decay # 时间衰减权重推荐w40.1衰减值越大得分越低补充权重总和建议为1可根据场景调整如用户咨询场景可提高similarity权重用户长期交互场景可提高importance权重。6.3 每个因子解释similarity语义相关性计算方式用户当前提问的embedding与记忆content的embedding的余弦相似度范围0-1补充embedding模型需与写入时保持一致如均使用text-embedding-ada-002确保相似度计算准确。importance由写入时 行为更新写入时由LLM根据信息重要性初始赋值后续被访问时可适当提升冲突时可降低补充初始importance可与LLM判断的confidence正相关如confidence0.9初始importance0.8。access_count被用得越多 → 越重要每次记忆被注入到LLM上下文并使用access_count1补充使用log(access_count 1)是为了避免“访问次数过高”导致权重垄断如访问100次和10次的权重差异不会过大。time_decay时间衰减exp(-λ * Δtime) # λ为衰减系数Δtime为当前时间与last_access的时间差单位天λ取值推荐0.1-0.3λ0.1表示衰减慢λ0.3表示衰减快Δtime当前时间 - last_access如记忆30天未访问Δtime30示例λ0.1Δtime30 → exp(-0.1*30)exp(-3)≈0.05衰减后得分大幅降低几乎不会被检索到。精妙点“最相关” ≠ “最应该被用”如用户当前问“FastAPI怎么用”最相关的记忆是“用户用FastAPI做项目”但如果有“用户是Python新手”的高重要性记忆也需要优先检索辅助给出更基础的教程七、Memory Injection注入补充注入的核心是“让LLM自然地使用记忆而非生硬堆砌”格式设计直接影响LLM的使用效果。错误方式用户记忆 - 喜欢Python - 用FastAPI做项目问题LLM可能无法将记忆与当前问题结合生硬插入回答导致回答不连贯。正确方式你知道以下关于用户的信息请结合这些信息回答用户当前的问题回答要自然不要生硬提及“记忆”“信息”等词汇 [用户偏好] - 喜欢Python偏好简洁、实用的技术方案 [历史行为] - 近期正在使用FastAPI构建项目还用到了Redis Streams - 曾遇到过Redis连接超时的问题 [用户目标] - 长期目标是掌握云原生相关技术精妙点分区 标签 → 提升理解按“偏好、行为、目标”分区LLM可快速识别不同类型的记忆精准结合当前问题使用补充注入时需控制长度避免占用过多token建议注入内容不超过500token优先注入高评分、高相关的记忆。八、Memory Update更新机制补充更新的核心是“保证记忆的准确性和时效性”避免出现“用户状态已变但记忆仍未更新”的人格冲突问题。8.1 冲突问题旧喜欢Python 新转Go用户最新对话中提到“我现在主要用Go开发不再用Python了”补充冲突场景包括“用户偏好变化”“信息修正”“目标更新”等需通过更新机制解决。8.2 解决策略方式1降权推荐保留历史记忆避免信息丢失old.importance * 0.5 # 旧记忆重要性减半新记忆按正常流程写入权重正常 # 补充可同时更新旧记忆的status为deprecated标记为过期适用场景用户偏好渐变如从“喜欢Python”到“主要用Go但也会用Python”。方式2删除慎用仅适用于完全错误、无效的记忆# 当旧记忆完全错误如用户误说“我是前端开发者”后续纠正为“后端开发者” delete_memory(old.id)适用场景用户信息输入错误、记忆提取错误等完全无效的记忆。方式3标记过期推荐兼顾历史和时效性{ id: uuid-xxx, status: deprecated, // 标记为过期检索时可过滤或降权 deprecated_at: 2024-05-10 09:00:00 // 新增过期时间便于后续清理 }适用场景用户状态明确变化如“转Go”后“喜欢Python”的记忆不再适用但可保留历史记录。本质Memory 是“状态机”不是“日志系统”核心是记录用户当前的状态而非所有历史行为需动态更新以匹配用户最新状态九、Decay遗忘机制补充遗忘机制的核心是“模拟人类遗忘规律清理低价值记忆降低存储和检索成本”避免记忆膨胀。9.1 指数衰减核心算法score importance * exp(-λ * Δtime) # 补充这里的score用于检索排序衰减后的score越低被检索到的概率越小9.2 参数设计参数含义推荐取值λ衰减速度λ越大衰减越快λ越小衰减越慢0.1-0.3通用场景取0.2Δtime时间间隔当前时间与last_access的差值单位天实时计算每次检索时计算9.3 访问强化对抗遗忘if used: # 记忆被注入到LLM上下文并使用可通过LLM回答是否引用记忆判断 last_access now # 更新最后访问时间重置衰减计时 access_count 1 # 增加访问次数提升权重 importance min(importance 0.1, 1.0) # 适当提升重要性最大不超过1.0补充“used”的判断可通过LLM回答的语义分析实现如判断回答中是否引用了记忆内容或简单按“注入即视为使用”处理简化实现。十、Cleanup清理补充清理的核心是“去除无效记忆释放存储资源提升检索效率”清理动作需谨慎避免误删有效记忆。条件importance 阈值推荐0.2 AND 很久没访问Δtime 阈值推荐30天 OR status deprecated过期记忆 OR confidence 0.5低置信度记忆可能是LLM判断错误操作删除适用于低重要性、长期未访问、低置信度的记忆合并适用于相似记忆如“用户用FastAPI做项目”和“用户用FastAPI开发后端”可合并为一条减少冗余压缩适用于内容较长但仍有价值的记忆进一步压缩核心信息减少token占用补充清理频率可根据记忆量调整小规模场景每月1次大规模场景每周1次。十一、系统位置补充系统位置的核心是“区分在线和离线任务保证交互响应速度同时实现记忆的长期演化”。在线路径用户交互主链路要求低延迟请求用户提问 → 检索Memory Retrieval加载Profile检索Episodic加载Working → 生成LLM结合记忆生成回答 → 返回立即返回给用户 → 异步写入Memory Writing后台处理写入离线路径长期维护任务不影响用户交互定时 - 清理Cleanup删除/合并/压缩无效记忆 - 合并合并相似记忆减少冗余 - 统计统计记忆使用情况优化权重参数核心原则影响当前回答 → 在线检索、注入需快速响应长期维护 → 离线清理、合并、统计可批量处理十三、Memory 文件化补充文件化的核心是“将记忆相关的规则、配置、模板固化为文件实现可管理、可版本控制避免硬编码”。MEMORY.md内容失败记录、世界观 、长期知识、全局规则写入过滤规则、衰减参数、检索权重、清理条件等USER.md内容用户画像模板、记忆提取模板、注入格式模板等作用规范用户记忆的格式和提取逻辑保证一致性AGENTS.md内容Agent说话风格、能力边界、行为规则如Agent如何使用记忆、如何触发记忆更新、如何处理记忆冲突等作用规范Agent与Memory系统的交互逻辑避免行为混乱本质Prompt → 可管理资产将原本硬编码的Prompt、规则转化为可版本控制、可修改的文件降低维护成本