1. 项目背景与核心价值
在AI助手领域,记忆系统是构建真正智能化Agent的关键基础设施。OpenClaw及其轻量级实现Nanobot通过创新的双层存储架构,解决了传统AI助手面临的三大核心痛点:
- 跨会话失忆问题:普通AI对话结束后即丢失上下文,而OpenClaw的记忆系统能永久保存关键信息
- 上下文窗口限制:通过智能压缩和分层存储,突破了大模型有限的token约束
- 知识沉淀难题:将碎片化对话自动提炼为结构化知识,实现经验的持续积累
这套系统最初由香港大学数据科学实验室(HKUDS)在Nanobot项目中实现,后被整合到OpenClaw生态。其设计哲学可概括为"文件即真相"(File-First),所有记忆以纯Markdown文件存储,既保证人类可读可编辑,又便于版本控制。
2. 架构设计与核心组件
2.1 双层存储模型
记忆系统的核心是分层治理策略,将信息按时效性和重要性分级存储:
| 存储层级 | 文件位置 | 内容类型 | 加载策略 |
|---|---|---|---|
| 短期记忆 | memory/YYYY-MM-DD.md | 日常对话、临时上下文 | 自动加载当天+昨日日志 |
| 长期记忆 | MEMORY.md | 用户偏好、关键决策、持久事实 | 主会话启动时加载 |
| 历史日志 | HISTORY.md | 完整交互记录(不可变) | 按需检索 |
这种设计实现了"热-温-冷"三级数据管理,既保证常用信息快速访问,又避免无关历史污染上下文。
2.2 关键工作流程
记忆系统的运作遵循严格的写入规则和触发机制:
-
写入判定树:
- 用户显式指令(如"记住这个")→ 强制写入MEMORY.md
- 模型识别到关键信息(偏好/决策等)→ 建议写入MEMORY.md
- 常规对话内容 → 自动写入当日日志文件
- 工具执行结果 → 同时写入日志和HISTORY.md
-
自动压缩机制:
当会话消息达到阈值(默认50条)时触发:python复制if len(session.messages) - last_consolidated >= memory_window: await memory_store.consolidate()压缩过程采用LLM辅助的摘要技术,将冗余对话提炼为结构化知识。
2.3 核心代码模块
记忆系统主要由以下Python类实现:
python复制class MemoryStore:
"""管理MEMORY.md和HISTORY.md的双层存储"""
def __init__(self, workspace: Path):
self.memory_file = workspace/"memory"/"MEMORY.md"
self.history_file = workspace/"memory"/"HISTORY.md"
async def consolidate(self, session: Session, llm: LLMProvider):
"""核心压缩逻辑"""
old_messages = self._extract_old_messages(session)
prompt = self._build_consolidation_prompt(old_messages)
response = await llm.chat(prompt, tools=_SAVE_MEMORY_TOOL)
self._process_llm_response(response)
class Session:
"""管理会话状态"""
def __init__(self):
self.messages: List[Dict] = [] # 原始消息记录
self.last_consolidated = 0 # 最后压缩位置指针
3. 关键技术实现细节
3.1 混合检索系统
记忆检索采用多模态搜索策略,组合以下技术:
- 向量搜索:使用OpenAI/Gemini等嵌入模型构建语义索引
- 关键词检索:基于TF-IDF和BM25算法实现精确匹配
- 时间衰减:
score *= exp(-0.1 * days_ago)加权新近记忆 - MMR多样性:
λ*相似度 - (1-λ)*重复度避免结果同质化
检索管道的工作流程:
code复制用户查询 → 向量搜索(top10) → 关键词搜索(top10) → 合并排序 →
时间衰减加权 → MMR重排序 → 返回最终结果
3.2 自动记忆注入
每次LLM调用前自动执行上下文增强:
python复制def _auto_recall(query: str) -> str:
results = memory_store.search(query, top_k=3)
return "\n".join(f"- {r['snippet']}" for r in results)
# 在系统提示中追加记忆上下文
system_prompt = f"""
{base_prompt}
## 相关记忆
{_auto_recall(user_input)}
"""
3.3 记忆压缩算法
当会话过长时触发的智能压缩流程:
python复制def compact_history(messages: List) -> List:
keep_count = max(4, int(len(messages)*0.2)) # 保留20%原始消息
old_text = serialize_for_summary(messages[:-keep_count])
summary = llm.generate(
system="你是一个专业的对话摘要助手",
prompt=f"请用3句话总结以下对话:\n{old_text}"
)
return [
{"role": "system", "content": f"[历史摘要] {summary}"},
*messages[-keep_count:] # 保留最新消息
]
4. 实操指南与避坑经验
4.1 典型配置示例
在~/.openclaw/config.yaml中建议设置:
yaml复制memory:
window_size: 50 # 触发压缩的消息阈值
search_provider: voyage # 向量搜索服务商
auto_recall: true # 启用自动记忆召回
retention_days: 30 # 日志保留天数
4.2 常见问题排查
-
记忆未被正确加载:
- 检查MEMORY.md文件权限(需644)
- 验证工作目录路径(默认
~/.openclaw/workspace) - 查看会话初始化日志确认加载过程
-
检索结果不准确:
bash复制# 调试搜索管道 openclaw debug-search "查询词" --verbose- 调整vector_weight/text_weight比例(默认0.7/0.3)
- 检查嵌入模型是否支持中文
-
压缩导致信息丢失:
- 降低memory_window值(最小可设20)
- 在重要对话前使用
/nocompact命令临时禁用压缩
4.3 性能优化技巧
-
文件IO优化:
python复制# 使用内存缓存减少磁盘读取 @lru_cache(maxsize=100) def read_memory_file(path: str) -> str: return path.read_text() -
索引预构建:
bash复制# 定期重建搜索索引 openclaw rebuild-index --full -
分层存储策略:
- 将HISTORY.md按月份分片存储
- 使用zstd压缩历史日志(可节省70%空间)
5. 高级应用场景
5.1 多Agent记忆共享
通过符号链接实现工作区共享:
bash复制ln -s ~/team_workspace ~/.openclaw/workspace
需注意并发写入问题,建议配合文件锁使用。
5.2 记忆版本控制
集成Git实现变更追踪:
python复制def git_commit(message: str):
subprocess.run([
"git", "-C", workspace,
"add", "memory/*.md"
])
subprocess.run([
"git", "-C", workspace,
"commit", "-m", message
])
5.3 自定义记忆类型
扩展MemoryStore支持新存储后端:
python复制class DatabaseMemory(MemoryStore):
def __init__(self, conn_str: str):
self.engine = create_engine(conn_str)
def write_long_term(self, content: str):
self.engine.execute(
"INSERT INTO memories VALUES (?, ?)",
[datetime.now(), content]
)
这套记忆系统在实际使用中展现出了惊人的鲁棒性。有个特别深刻的体会:当MEMORY.md积累到300+条关键记录后,AI助手的响应质量会有质的飞跃,因为它开始真正"了解"你的工作习惯和偏好。建议定期用grep -vE '^#|^$' MEMORY.md | wc -l检查记忆条目数,保持活跃记忆在200-500条之间效果最佳。
