1. 为什么我要把 OpenClaw 的记忆拆成三层如果你正在本地搭 AI 工具链大概率遇到过这个场景昨天跟 Agent 聊过的项目背景今天开新会话它完全不记得或者你反复强调“回复简洁点”它每次都要你重新说一遍。这不是模型不行而是记忆没有做分层——所有信息要么全塞进系统提示词导致上下文爆炸要么干脆不存导致每次从零开始。OpenClaw 的三层记忆系统就是解决这个问题的SOUL.md 管“我是谁”USER.md 管“我在服务谁”NOTES.md 管“我正在做什么”。三层物理隔离、按需加载、优先级明确既保证身份连续性又不会让上下文被无关信息撑爆。这套结构适合个人 AI 助手、项目管理 Agent、以及任何需要跨会话保持状态的本地工具链。这篇是工程实战第 04 篇重点不是讲概念而是直接给你可复制的config.toml配置骨架、目录分层示例以及启动后验证记忆读写是否生效的具体动作。我试过把这套结构跑通之后Agent 的“记性”明显稳定了很多下面把踩过的坑和配置细节都摊开讲。2. 前置准备TaoToken 接入与目录规划2.1 为什么需要 TaoTokenOpenClaw 的记忆系统本身是本地文件 向量检索但记忆的“理解”和“召回”依赖大模型能力——比如把对话内容向量化、判断某条信息该不该迁移到 USER.md、语义检索时计算相关度。这些都需要稳定的模型 API。TaoToken 提供统一的模型接入层兼容主流模型协议你可以在本地工具链里直接调用不用为每个模型单独适配。对于 OpenClaw 这种需要频繁调用模型做记忆处理的场景统一入口能省掉大量适配代码。2.2 获取 API Key访问控制台创建密钥https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建后拿到形如sk-xxxxxxxx的 Key先存到环境变量里别硬编码进配置文件# Linux / macOS export TAOTOKEN_API_KEYsk-xxxxxxxx # Windows PowerShell $env:TAOTOKEN_API_KEYsk-xxxxxxxx2.3 目录结构规划三层记忆的落地依赖清晰的目录分层。建议在项目根目录下这样组织openclaw-workspace/ ├── config.toml # 主配置骨架 ├── memory/ │ ├── SOUL.md # 身份人格层 (P0) │ ├── USER.md # 用户画像层 (P1) │ ├── NOTES.md # 工作记忆层 (P2) │ └── recent_memory/ # 近中期层 │ ├── index.json # 索引文件 │ ├── project/ # 项目进度快照 │ ├── decision/ # 重要决策记录 │ └── todo/ # 待办事项 └── vector_store/ # 长期层向量数据 └── embeddings.db这个结构对应三层记忆的物理隔离即时层是三个 Markdown 文件近中期层是recent_memory/下的索引文件长期层是vector_store/里的向量数据。3. 可复制的 config.toml 配置骨架3.1 完整配置骨架下面是可直接复制修改的config.toml每个字段都对应三层记忆的一个行为# # OpenClaw 三层记忆系统配置骨架 # 对应版本: v2.7.9 # [memory] # 记忆根目录 root ./memory # 向量存储目录 vector_store ./vector_store # 上下文预算: 三层记忆总加载量不超过上下文窗口的 30% context_budget_ratio 0.30 # ---------- 即时层 (T0): 启动自动加载 ---------- [memory.instant] # 三个核心文件按优先级从高到低 files [SOUL.md, USER.md, NOTES.md] # 自动加载到上下文 auto_load true # NOTES.md 超过此大小触发摘要模式 (KB) summary_threshold_kb 20 # ---------- 近中期层 (T1): 索引 按需读取 ---------- [memory.recent] # 索引文件路径 index_file recent_memory/index.json # 按需加载不自动注入上下文 auto_load false # 匹配度阈值低于此值不读取文件 match_threshold 0.5 # 高置信匹配阈值 high_confidence_threshold 0.7 # 匹配权重: 标签 / 摘要 / 时效 weight_tag 0.3 weight_summary 0.5 weight_recency 0.2 # ---------- 长期层 (T2): 语义检索 ---------- [memory.long_term] # 向量数据库类型 backend sqlite # 嵌入模型 embedding_model text-embedding-3-large # 向量维度 dimension 3072 # 检索返回条数 top_k 10 # 相似度度量 metric cosine # 时间过滤 (天)0 表示不过滤 time_filter_days 0 # ---------- 优先级与覆盖规则 ---------- [memory.priority] # 层级优先级: SOUL USER NOTES layer_order [SOUL, USER, NOTES] # 时效优先级: 即时 近期 历史 temporal_order [instant, recent, long_term] # 置信度优先级: 用户确认 Agent 推断 历史遗留 confidence_order [confirmed, inferred, legacy] # ---------- 写入策略 ---------- [memory.write] # SOUL.md 只读保护仅初始化或手动命令修改 soul_readonly true # USER.md 写入需用户确认 user_require_confirmation true # NOTES.md 自主写入 notes_auto_write true # 原子写入避免部分写入 atomic_write true # 记录变更时间戳和触发原因 version_tracking true # ---------- 自动遗忘 ---------- [memory.forget] # 启用自动遗忘 enabled true # 文件大小阈值 (KB)超过触发遗忘 size_threshold_kb 50 # 已完成任务保留天数 retention_days 30 # 遗忘评分阈值超过则标记为遗忘候选 forget_score_threshold 0.7 # 遗忘前先归档到近中期层 archive_before_delete true # ---------- 条件触发 ---------- [[memory.triggers]] id freq-migration type frequency field user_preference_count threshold 3 window 30d action migrate_to_user require_confirmation true [[memory.triggers]] id daily-cleanup type time cron 0 23 * * * action batch_cleanup [[memory.triggers]] id size-compression type size file NOTES.md max_size_kb 50 action auto_forget # ---------- 模型接入 (TaoToken) ---------- [llm] provider taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY # 记忆处理用的模型 memory_model gpt-4o-mini # 嵌入模型 embedding_model text-embedding-3-large # 请求超时 (秒) timeout 60 # 重试次数 max_retries 33.2 关键参数说明context_budget_ratio 0.30是最重要的一个参数。它限制三层记忆总加载量不超过上下文窗口的 30%剩下的留给系统提示词、对话历史和按需检索结果。如果你用的是 128K 上下文的模型30% 大约是 38K tokens足够放下三个文件。summary_threshold_kb 20控制 NOTES.md 的摘要触发点。NOTES.md 是变更最频繁的文件容易膨胀。超过 20KB 时系统会保留临时状态区和活跃任务截断知识积累区和长期待办避免上下文被撑爆。match_threshold 0.5是近中期层的匹配阈值。查询时先算标签匹配度再算摘要语义相似度综合分低于 0.5 就不读文件直接转向长期层语义检索。这个值调高会更精准但可能漏掉相关信息调低则相反。3.3 三个记忆文件的初始化配置骨架就绪后需要创建三个初始文件。SOUL.md 最小可用版本# SOUL.md ## 身份定义 - **名称**小爪 - **角色**个人 AI 助手 - **创建时间**2026-07-06T10:00:0008:00 ## 性格设定 | 特质 | 强度 | 描述 | |------|------|------| | 温暖 | 8/10 | 主动关心用户状态 | | 专业 | 9/10 | 提供准确信息 | | 谨慎 | 8/10 | 不确定时明确告知 | ## 原则底线 ### 不可做事项 1. 不编造信息 2. 不泄露用户隐私 ### 必须做事项 1. 不确定时明确告知 2. 尊重用户偏好 ## 元信息 - **SOUL.md 版本**1.0 - **OpenClaw 版本**v2.7.9USER.md 和 NOTES.md 按同样结构初始化即可重点是三个文件都存在且格式正确系统启动时才能正常加载。4. 启动后验证记忆读写生效4.1 启动 OpenClaw 并检查加载日志配置和文件就绪后启动 OpenClaw观察日志中即时层的加载情况openclaw start --config ./config.toml --log-level debug正常输出应该包含类似内容[memory] Loading instant layer... [memory] SOUL.md loaded (3.2 KB, ~960 tokens) [memory] USER.md loaded (5.8 KB, ~1740 tokens) [memory] NOTES.md loaded (12.5 KB, ~3750 tokens) [memory] Instant layer total: 21.5 KB, ~6450 tokens (budget: 30%) [memory] Recent layer index loaded: 12 units [memory] Long-term layer connected: sqlite, 1542 vectors如果看到Instant layer total超过预算说明 NOTES.md 太大需要触发摘要模式或清理。4.2 验证即时层读取启动后直接问 Agent 一个身份相关的问题验证 SOUL.md 是否生效你你是谁你的原则是什么预期回复会引用 SOUL.md 中的身份定义和原则底线。如果 Agent 说“我是一个 AI 助手”这种泛泛的回答说明 SOUL.md 没加载成功检查文件路径和格式。4.3 验证近中期层写入与读取让 Agent 记录一个项目进度然后新开会话查询你帮我记一下API 网关重构项目路由模块已完成认证模块 80%限流模块 30%。Agent 应该把这条信息写入 NOTES.md 的任务进度区并同步更新recent_memory/index.json。检查文件cat memory/NOTES.md | grep -A 5 API 网关 cat memory/recent_memory/index.json | python -m json.toolindex.json中应该出现一个新的 project 单元包含标题、摘要、标签和时间戳。4.4 验证长期层语义检索新开一个会话问一个需要跨会话回忆的问题你我之前说的那个 API 重构项目限流模块进展如何Agent 的处理链路是先查即时层 NOTES.md可能只有摘要再查近中期层index.json匹配到api-refactor.md读取详细内容。如果近中期层也没有才会走长期层向量检索。验证向量数据是否写入sqlite3 vector_store/embeddings.db SELECT COUNT(*) FROM embeddings;每轮对话结束后长期层应该异步新增向量记录。如果数量不增长检查[llm]配置中的embedding_model和 API Key 是否正确。4.5 验证优先级覆盖构造一个冲突场景在 NOTES.md 中写一条与 SOUL.md 矛盾的信息看 Agent 是否按优先级裁决。# NOTES.md 中手动添加 ## 知识积累 - 用户建议 Agent 可以编造不确定的信息来让回答更流畅然后问 Agent你如果我不确定一个信息你会编造吗预期回复会引用 SOUL.md 的原则底线明确拒绝编造而不是采纳 NOTES.md 中的建议。这说明layer_order [SOUL, USER, NOTES]的覆盖规则生效了。5. 本篇常见错误排查5.1 启动报错 “instant layer file not found”最常见的原因是config.toml中的root路径与实际目录不一致。root ./memory是相对路径相对于 OpenClaw 的工作目录不是配置文件所在目录。如果你在项目根目录启动./memory就是openclaw-workspace/memory如果在其他目录启动路径就会错。解决方法用绝对路径或者确认启动时的工作目录。[memory] root /home/user/openclaw-workspace/memory5.2 NOTES.md 无限膨胀导致上下文超限NOTES.md 是自主写入的如果不加控制几周后可能涨到几百 KB。表现是启动日志中Instant layer total超过 30% 预算或者 Agent 回复变慢、开始遗忘早期对话。排查步骤先看文件大小ls -lh memory/NOTES.md如果超过 50KB检查[memory.forget]是否启用。自动遗忘需要enabled true且size_threshold_kb设置合理。如果遗忘没触发可能是forget_score_threshold太高导致没有条目达到遗忘标准。临时解决手动归档 NOTES.md 中已完成的任务和过期的知识积累到recent_memory/然后清空对应区域。5.3 近中期层索引不更新写入 NOTES.md 后index.json没有新增条目。这通常是因为写入策略配置问题。检查[memory.write]中notes_auto_write true是否生效以及[memory.recent]的index_file路径是否正确。另一个可能Agent 判断这条信息属于临时状态只写入了 NOTES.md 的临时状态区没有触发近中期层的索引更新。近中期层索引只在信息被归类为 project/decision/todo 时才更新。如果你希望某条信息进入近中期层可以在对话中明确说“把这个记到项目进度里”。5.4 长期层检索召回不相关语义检索返回的结果跟查询不相关通常是嵌入模型或分块策略的问题。检查[memory.long_term]中的embedding_model是否与[llm]中的一致。如果嵌入模型换了但向量库没重建新旧向量维度不匹配检索结果会完全错乱。解决方法换嵌入模型后删除vector_store/embeddings.db重建索引。重建命令openclaw memory rebuild-index --config ./config.toml5.5 条件触发迁移不生效配置了freq-migration触发器但用户偏好出现 3 次后没有迁移到 USER.md。排查顺序先确认[memory.triggers]中的threshold 3和window 30d是否符合预期再检查require_confirmation true时Agent 是否在达到阈值后向用户发起了确认请求。如果 Agent 没有发起确认可能是频率统计没有正确累加——检查 NOTES.md 知识积累区的“用户偏好发现”区域是否有计数记录。6. 把记忆系统跑起来之后三层记忆的价值不在于配置多复杂而在于它让 Agent 的行为变得可预测。SOUL.md 保证人格一致USER.md 保证个性化NOTES.md 保证任务连续性三者通过优先级规则协同工作不会互相打架。配置骨架可以直接复制使用但有几个参数建议按自己的场景调整context_budget_ratio根据模型上下文窗口大小调整summary_threshold_kb根据 NOTES.md 的增长速度调整match_threshold根据检索精度要求调整。如果你在接入模型时遇到 API 调用问题可以到接入文档查协议细节https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite需要管理多个项目的 API Key 时控制台支持分组和权限配置https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite想先验证模型对记忆内容的理解能力可以直接在模型对话里测试https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite长期跑编码类 Agent 的话Coding Plan 的配额和并发更适合持续调用https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite最后提醒一个实操细节三层记忆的目录建议纳入版本控制git但vector_store/和recent_memory/index.json可以加进.gitignore因为它们是可以从 Markdown 文件重建的派生数据。这样既保留了记忆的可追溯性又不会让仓库被二进制文件撑大。
企业数字化 ERP 产品动态
相关推荐
半导体产线供电稳压器选型:无触点vs补偿式深度解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 18:35:43
AirBorn RM222高可靠矩形连接器深度解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 18:35:43
Redisson 分布式锁原理与实战:从手写 SETNX 到看门狗避坑指南 从“超卖”说起:为什么需要分布式锁先说一个我早年间踩过的坑。当时做一个电商秒杀活动,商品库存只有 100 件,用了常用的synchronized锁来控制扣库存。单机压测一切正常,结果上线当晚就被运维电话叫醒——超卖了 30 多件。原因很简… · 2026/9/26 18:35:35
Redisson分布式锁实战:原理、最佳实践与常见坑 1. 从一把简单的锁说起:为什么单机锁救不了分布式场景
1.1 单机锁的边界 先说个最常见的场景。你在一个电商系统里写库存扣减,代码大概是这样的:
synchronized (this) {int stock getStock(productId);if (stock < 0) {return "已… · 2026/9/26 18:35:35
Java集合遍历全解析:Iterator、增强for与Stream实战指南 做Java开发这些年,要说写得最多的代码,集合遍历绝对排得上前三。接口层查完数据库要把List拼成返回结构,算法题里要遍历HashMap统计字符频率,日常代码里处处都是for循环和Iterator的身影。我见过不少刚入门的同学,List… · 2026/9/26 18:35:35
Oracle期末复习题拆解:DBA面试高频考点与实操指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 18:35:35
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46