OpenClaw 记忆系统:三层记忆架构与 Daily Notes 机制
标签 :OpenClaw、记忆架构、RAG、Embedding、上下文管理、长期记忆
前言:记忆是 Agent 的"状态壁垒"
在构建生产级 AI Agent 时,一个常被低估的架构难题是状态持久化。无状态的 LLM 调用虽然简单,但无法形成累积性的用户理解;而粗暴的全量历史拼接又很快会触达 Token 上限。OpenClaw 的记忆系统通过分层存储架构与智能归档机制,在上下文窗口限制与长期记忆能力之间建立了工程化的平衡。
本文将从架构实现角度,拆解 OpenClaw 的三层记忆模型、Daily Notes 持久化机制、语义检索配置策略以及多会话隔离原则,帮助开发者设计出既具备持续学习能力、又符合隐私合规要求的记忆方案。
一、三层记忆模型:分层存储的工程哲学
OpenClaw 采用分层越界(Tiered Overflow)设计,将记忆按时间维度与重要性维度划分为三个层级,分别对应不同的存储介质与检索策略。
1.1 架构总览
md
┌─────────────────────────────────────────────────────────────┐
│ L1 工作记忆 (Working Memory) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 存储位置:LLM 上下文窗口 (Context Window) │ │
│ │ 内容形态:原始对话历史 + 系统提示词 │ │
│ │ 生命周期:单个会话 (Session) │ │
│ │ 容量限制:受限于模型 Max Tokens (通常 4k-128k) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ 溢出 (Overflow) │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 压缩/摘要 ◄── Pre-compaction Flush │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
└──────────────────────────┼──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ L2 短期记忆 (Daily Notes) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 存储位置:~/.openclaw/workspace/<ws>/memory/ │ │
│ │ YYYY-MM-DD.md │ │
│ │ 内容形态:Markdown 格式的每日会话摘要 │ │
│ │ 更新频率:实时追加 + 每日归档 │ │
│ │ 保留策略:默认 30 天可配置 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ 语义提取 (Semantic Extraction) │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Embedding 向量化 ◄── 关键事实抽取 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
└──────────────────────────┼──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ L3 长期记忆 (Episodic Memory) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 存储位置:~/.openclaw/workspace/<ws>/agents/ │ │
│ │ <agentId>/MEMORY.md │ │
│ │ 内容形态:结构化事实库 + 用户画像标签 │ │
│ │ 持久周期:永久(除非手动清理) │ │
│ │ 加载时机:Agent 初始化时注入系统提示词 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
1.2 各层技术细节
L1 工作记忆:热上下文管理
OpenClaw 在内存中维护一个双端队列(Deque)结构,存储当前会话的原始消息。当检测到 Token 消耗超过阈值(默认 80% 的上下文窗口)时,触发智能裁剪:
- 保留最近的 N 轮对话(保证对话连贯性)
- 对早期消息进行语义压缩,生成摘要后移入 L2
L2 短期记忆:Daily Notes 机制
以自然日为单位的 Markdown 文件,采用追加写(Append-only)模式:
md
# 2026-03-09 Session Log
## 10:23 - Project Discussion
User asked about microservices migration strategy. Key points:
- Current monolith uses Python/Django
- Target: Kubernetes + Go microservices
- Concern: Data consistency during migration
## 14:15 - Code Review
Reviewed PR #234: Added circuit breaker pattern to payment service.
L3 长期记忆:事实萃取库
经过人工审核或高频访问验证的事实,以结构化键值对形式存储:
md
## User Preferences
- code_style: "PEP8 with type hints"
- preferred_languages: ["Python", "Rust"]
- infrastructure: "AWS EKS, Terraform"
## Project Context
- current_project: "Payment Gateway v2"
- tech_stack: "Go, gRPC, PostgreSQL"
- constraints: ["PCI-DSS compliance", "99.99% SLA"]
二、记忆写入机制:从被动记录到主动归档
2.1 Agent 主动写入
开发者可通过 SDK 显式控制记忆写入时机,避免自动机制带来的噪声:
python
from openclaw import Agent, MemoryLevel
agent = Agent("assistant")
# 显式写入长期记忆(重要事实)
await agent.memory.commit(
level=MemoryLevel.L3,
content="User is allergic to shellfish", # 关键医疗信息
tags=["health", "constraints"]
)
# 批量写入短期记忆(日常上下文)
await agent.memory.extend([
"Discussed Q2 roadmap priorities",
"Agreed on microservices split strategy"
])
写入冲突解决:
当并发写入同一记忆文件时,OpenClaw 采用文件级锁(flock)与乐观锁(版本号)结合的策略:
短时间尺度(同一进程内):内存队列缓冲,批量 flush
跨进程并发:基于 inode 的 advisory locking,失败时退避重试
2.2 Pre-compaction Flush 自动归档
L1 向 L2 的溢流由压缩守护进程自动处理,触发条件包括:
md
触发条件检查(每轮对话后)
│
▼
┌──────────────────────┐
│ Token 使用率 > 80% ? │──Yes──► 启动 Compaction
└──────────┬───────────┘
│ No
▼
┌──────────────────────┐
│ 会话空闲 > 5分钟 ? │──Yes──► 启动 Compaction
└──────────┬───────────┘
│ No
▼
保持 L1 现状
压缩算法流程:
md
原始对话历史 (L1)
│
▼
┌─────────────────────────┐
│ 1. 语义分块 │
│ - 按主题边界切分对话 │
│ - 识别独立的事实单元 │
└──────────┬──────────────┘
│
▼
┌─────────────────────────┐
│ 2. 重要性评分 │
│ - 用户显式强调 (+2) │
│ - 包含决策/结论 (+1) │
│ - 闲聊/过渡 (-1) │
└──────────┬──────────────┘
│
▼
┌─────────────────────────┐
│ 3. 摘要生成 │
│ - 高重要性:保留原文 │
│ - 中重要性:生成摘要 │
│ - 低重要性:丢弃 │
└──────────┬──────────────┘
│
▼
写入 L2 (Daily Notes)
三、语义搜索配置:向量检索的工程化实践
OpenClaw 的记忆检索并非简单的关键词匹配,而是基于Embedding 向量的语义相似度搜索。架构师需在精度、成本与隐私之间做权衡。
3.1 Provider 选型矩阵
memorySearch.provider 支持多种后端,适用场景各异:
| Provider | 模型能力 | 数据隐私 | 成本 | 适用场景 |
|---|---|---|---|---|
| OpenAI | text-embedding-3-large (3072d) | 数据出境 | $0.13/1M tokens | 高精度通用场景 |
| Gemini | embedding-001 | 数据出境 | 免费额度高 | 多语言混合场景 |
| Voyage | voyage-2 (1024d) | 数据出境 | $0.10/1M tokens | 代码/技术文档专用 |
| Ollama | nomic-embed-text (768d) | 本地计算 | 仅硬件成本 | 离线/隐私敏感环境 |
| Local | ONNX 运行时加载自定义模型 | 本地计算 | 硬件成本 | 定制化领域模型 |
配置示例:
json
{
"memorySearch": {
"provider": "ollama",
"model": "nomic-embed-text:latest",
"baseUrl": "http://localhost:11434",
"dimensions": 768,
"metric": "cosine",
"topK": 5,
"threshold": 0.72
}
}
3.2 嵌入策略与分块优化
文本分块(Chunking)策略直接影响检索精度:
md
Daily Notes (Markdown)
│
▼
┌──────────────────────────────┐
│ 按标题层级分块 (H2/H3 边界) │
│ - 保持语义完整性 │
│ - 块大小:256-512 tokens │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 重叠窗口 (Overlap: 50 tokens) │
│ - 防止上下文截断 │
│ - 保证跨边界语义连贯 │
└──────────┬───────────────────┘
│
▼
生成向量索引 (Chroma/FAISS)
混合检索(Hybrid Search):
OpenClaw 默认结合向量相似度与关键词 BM25 分数,通过 RRF(Reciprocal Rank Fusion)重排序:
python
# 内部实现逻辑
vector_results = vector_search(query_embedding, top_k=10)
keyword_results = bm25_search(query_text, top_k=10)
# RRF 融合
final_scores = {}
for rank, doc in enumerate(vector_results):
final_scores[doc.id] += 1.0 / (k + rank)
for rank, doc in enumerate(keyword_results):
final_scores[doc.id] += 1.0 / (k + rank)
四、记忆加载规则:会话隔离与安全边界
OpenClaw 对记忆的访问实施最小权限原则,不同会话类型具有不同的记忆可见性。
4.1 Main Session 与 Group Session 隔离模型
md
Workspace 记忆存储
│
├──► Main Session (1:1 专属会话)
│ │
│ ├──► 加载 MEMORY.md (L3 长期记忆)
│ │ - 用户画像
│ │ - 项目上下文
│ │
│ ├──► 加载本周 Daily Notes (L2)
│ │ - 近期上下文
│ │
│ └──► 实时对话历史 (L1)
│
└──► Group Session (1:N 群组会话)
│
├──► 不加载 MEMORY.md
│ - 防止隐私泄露给其他参与者
│
├──► 仅加载 Session 创建后的对话历史
│
└──► 可选:共享白板 (Shared Context)
- 显式授权的知识库
安全隔离原理:
- Main Session:假设用户与 Agent 建立信任关系,可访问完整个人历史
- Group Session:多参与者环境,默认零记忆启动,避免:
- 用户 A 的隐私信息被用户 B 通过 Agent 获取
- 跨项目的敏感数据混用
4.2 显式记忆共享机制
当需要在 Group Session 中引入背景知识时,采用显式授权模式:
python
# 创建群组会话时注入特定记忆片段
group_session = await openclaw.create_group_session(
participants=["user1", "user2", "agent"],
shared_context=[
"project_requirements_v2.md", # 仅项目相关文档
"api_design_spec.md"
],
exclude_personal_memory=True # 严格隔离个人 L3 记忆
)
五、记忆故障排查:生产环境诊断指南
记忆系统故障往往表现为"Agent 健忘"或"回答 hallucination",以下是系统性排查路径。
5.1 Workspace 写入权限故障
症状:Agent 表现出"金鱼记忆",每次对话都像是初次见面。
诊断流程:
md
检查记忆持久化
│
▼
┌──────────────────────────────┐
│ 1. 检查目录权限 │
│ ls -la ~/.openclaw/ │
│ - 应为 700 (drwx------) │
│ - 属主应为运行用户 │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 2. 检查磁盘空间 │
│ df -h │
│ - 内存目录剩余空间 < 10% │
│ - 触发只读保护模式 │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 3. 检查文件锁竞争 │
│ lsof +D ~/.openclaw/ │
│ - 多实例并发写入冲突 │
│ - 解决方案:改用 Redis 后端 │
└──────────────────────────────┘
修复命令:
bash
# 自动修复权限
openclaw doctor --fix-permissions
# 验证写入能力
openclaw memory test-write --workspace default
# 应返回:Successfully wrote test chunk to L2 memory
5.2 Token 上限导致的记忆遗忘
症状:Agent 在长对话中后期开始重复询问已确认的信息。
根因分析:
当 L1 工作记忆达到模型上下文上限时,即使 L2/L3 存在历史记录,也可能因检索失败或注入位置错误导致记忆"未激活"。
排查步骤:
md
对话中断/重复询问
│
▼
┌──────────────────────────────┐
│ 检查当前上下文占用 │
│ openclaw session inspect │
│ - current_tokens: 15234/16384│
│ - 使用率:93% │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 检查记忆检索结果 │
│ - 是否触发 RAG? │
│ - topK 返回是否为空? │
│ ├── 空:向量数据库未构建 │
│ │ 运行:openclaw index rebuild
│ └── 有结果但未被采用 │
│ 检查 prompt 模板 │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 优化策略 │
│ 1. 增大 topK (5→10) │
│ 2. 降低 threshold (0.75→0.65) │
│ 3. 启用重排序 (Reranker) │
│ 4. 摘要压缩早期对话 │
└──────────────────────────────┘
配置调优:
json
{
"memory": {
"contextManagement": {
"reserveTokens": 2000, // 为检索结果预留空间
"compressionThreshold": 0.8,
"summarizationModel": "gpt-4o-mini" // 专用轻量模型做摘要
},
"retrieval": {
"topK": 7,
"threshold": 0.68,
"rerank": true,
"rerankModel": "cohere-rerank-v3"
}
}
}
5.3 向量索引损坏修复
症状:语义搜索返回无关内容,或抛出 Index out of range 异常。
重建索引:
bash
# 备份现有记忆
cp -r ~/.openclaw/workspace/default/memory ./memory_backup
# 重建向量索引(保留原始文本,仅重建 Embedding)
openclaw memory rebuild-index --workspace default --provider ollama
# 验证相似度搜索
openclaw memory search "What was the database choice last week?" --verbose
六、架构设计建议与最佳实践
6.1 记忆分层策略
高频变更数据(如临时变量、中间计算结果):
- 仅保留在 L1,不持久化
- 使用 session_state 临时存储
业务上下文(如当前项目技术栈): - 写入 L3 MEMORY.md
- 在 Agent systemPrompt 中通过模板变量注入:
md
Current project: {{memory.project_name}}
Tech stack: {{memory.tech_stack}}
历史记录(如昨日讨论结论):
- 依赖 L2 Daily Notes + RAG 检索
- 定期(每周)将高频访问的 L2 内容升格至 L3
6.2 隐私与合规
敏感信息过滤:
在写入 L2/L3 前,通过实体识别(NER)自动检测并脱敏:
python
# 配置示例
{
"memory": {
"privacy": {
"detectPII": true,
"redactPatterns": [
"\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b", # 信用卡
"\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b" # 邮箱
]
}
}
}
记忆遗忘权(Right to be Forgotten):
bash
# 删除特定用户所有记忆
openclaw memory purge --user user_123 --all-levels
# 删除特定会话痕迹
openclaw memory purge --session sess_abc --level L1
结语
OpenClaw 的记忆系统通过 L1/L2/L3 的分层架构,巧妙地解决了大模型上下文限制与长期记忆需求之间的矛盾。作为架构师,理解 Daily Notes 的持久化机制、语义检索的向量配置以及会话隔离的安全模型,是构建可靠 Agent 应用的基础。
在实际部署中,建议建立记忆健康度监控(记忆命中率、检索延迟、存储增长率),并定期进行记忆质量审计(清理过期 L2 数据、优化 L3 结构)。只有将记忆系统视为与模型选型同等重要的基础设施,才能构建出真正具备持续学习能力的智能应用。
本文章基于OpenClaw官方文档学习撰写。仅供学习参考,请勿用于商业用途。