1. OpenClaw 记忆系统概述
OpenClaw(Moltbot/clawdbot)作为当前最受关注的个人AI助手之一,其核心创新点在于突破了传统AI助手的"无记忆"瓶颈。与市面上大多数仅依赖上下文窗口的AI应用不同,OpenClaw构建了一套完整的双源记忆架构,实现了从"临时工具"到"长期伙伴"的进化。
1.1 传统AI助手的记忆困境
当前AI应用普遍面临三大记忆挑战:
-
上下文窗口限制:即使是性能最强的GPT-4-128K模型,其上下文窗口也只能容纳约10万汉字的内容。当对话超过这个限制,早期信息就会被丢弃。
-
成本问题:每次请求都需要重新传输和计算整个上下文,长时间对话的token消耗会呈指数级增长。根据实测数据,一个持续72小时的自动化任务,传统方案可能触发20次以上的会话重置。
-
信息检索效率低:简单的上下文堆叠无法实现精准的信息检索,用户需要反复重复相同信息。
1.2 OpenClaw的创新解决方案
OpenClaw通过以下设计解决了这些痛点:
- 持久化存储:将记忆与上下文分离,所有记忆数据存储在本地磁盘
- 分层管理:采用动态记忆(会话日志)和静态记忆(长期知识)的双层结构
- 智能检索:结合语义搜索和关键词搜索的混合检索机制
- 按需加载:只在需要时检索相关记忆片段,保持上下文轻量化
这种架构使得OpenClaw可以7×24小时不间断地积累知识,同时保持每次交互的上下文简洁高效。
2. 记忆系统的核心架构
2.1 双源记忆设计
OpenClaw将记忆分为两种类型,模拟人类大脑的记忆机制:
| 记忆类型 | 存储格式 | 存储路径 | 产生方式 | 类比人类记忆 |
|---|---|---|---|---|
| 动态记忆 | JSONL | ~/.openclaw/agents/{agentId}/sessions/*.jsonl | 自动记录 | 短期记忆,如当天的琐事 |
| 静态记忆 | Markdown | ~/.openclaw/workspace/MEMORY.md和memory/*.md | 手动+自动生成 | 长期记忆,如重要事件和经验 |
2.1.1 动态记忆实现细节
每次用户交互都会被实时记录为JSONL格式,示例结构如下:
json复制{"type":"message","message":{"role":"user","content":"帮我写一个Python爬虫"}}
{"type":"message","message":{"role":"assistant","content":"好的,我来帮你写..."}}
{"type":"tool_call","tool":"bash","input":{"command":"python crawler.py"}}
关键实现代码:
typescript复制export async function buildSessionEntry(absPath: string) {
const raw = await fs.readFile(absPath, "utf-8");
const lines = raw.split("\n");
const collected: string[] = [];
for (const line of lines) {
const record = JSON.parse(line);
if (message.role === "user" || message.role === "assistant") {
const label = message.role === "user" ? "User" : "Assistant";
collected.push(`${label}: ${text}`);
}
}
return {
path: sessionPathForFile(absPath),
hash: hashText(content),
content // "User: 帮我写... \n Assistant: 好的..."
};
}
2.1.2 静态记忆生成机制
静态记忆通过三种途径产生:
- 手动创建:用户直接编辑MEMORY.md文件
- 会话转换:使用/new命令时自动将最近15条对话转换为Markdown
- 记忆刷新:当上下文接近token限制时触发自动保存
记忆刷新是核心机制,其工作流程如下:
- 系统检测到上下文即将溢出
- 触发特殊Agent回合,提示"存储持久记忆"
- Agent判断需要保存的信息并写入Markdown文件
- 系统对剩余上下文进行有损压缩
2.2 记忆索引与检索系统
2.2.1 索引构建流程
OpenClaw采用轻量级索引方案,全部基于SQLite实现:
- 文件分块:将Markdown文件按400 tokens为单位分块,块间重叠80 tokens
- 向量化:为每个文本块生成embedding(支持OpenAI/Gemini/本地模型)
- 双索引构建:
- 向量索引:使用sqlite-vec扩展存储embedding
- 全文索引:使用FTS5实现关键词搜索
核心数据库schema设计:
sql复制-- 文件元数据表
CREATE TABLE files (
path TEXT PRIMARY KEY, -- 'memory/projects.md'
source TEXT NOT NULL, -- 'memory' | 'sessions'
hash TEXT NOT NULL, -- SHA256
mtime INTEGER NOT NULL,
size INTEGER NOT NULL
);
-- 文本块表
CREATE TABLE chunks (
id TEXT PRIMARY KEY, -- UUID
path TEXT NOT NULL, -- 来源文件
source TEXT NOT NULL, -- 'memory' | 'sessions'
start_line INTEGER,
end_line INTEGER,
hash TEXT NOT NULL,
model TEXT NOT NULL, -- 'text-embedding-3-small'
text TEXT NOT NULL, -- 原文
embedding TEXT NOT NULL, -- JSON数组[0.1, 0.2,...]
updated_at INTEGER
);
-- 向量索引
CREATE VIRTUAL TABLE chunks_vec USING vec0(...);
-- 全文索引
CREATE VIRTUAL TABLE chunks_fts USING fts5(
path, source, model, text,
tokenize='porter unicode61'
);
2.2.2 混合检索算法
OpenClaw采用70%向量相似度+30%关键词相关度的混合搜索:
typescript复制async search(query: string, opts?: { maxResults?: number; minScore?: number }) {
// 1. 关键词搜索 (BM25)
const keywordResults = await this.searchKeyword(cleaned, candidates);
// 2. 向量搜索
const queryVec = await this.embedQueryWithTimeout(cleaned);
const vectorResults = await this.searchVector(queryVec, candidates);
// 3. 混合排序(70%向量+30%关键词)
const merged = this.mergeHybridResults({
vector: vectorResults,
keyword: keywordResults,
vectorWeight: 0.7,
textWeight: 0.3
});
return merged.filter(r => r.score >= minScore).slice(0, maxResults);
}
这种混合方案在内部测试中达到了89%的召回率,显著优于单一搜索方式。
3. 核心交互流程解析
3.1 记忆写入流程
当用户说"请记住我喜欢的颜色是蓝色"时:
- Agent判断这是需要长期记忆的信息
- 调用write工具写入memory/YYYY-MM-DD.md文件
- 文件系统监控触发索引更新
- 新内容被分块、向量化并存入SQLite
3.2 记忆检索流程
当用户询问"我之前说过喜欢什么颜色?"时:
- Agent自动调用memory_search("喜欢的颜色")
- 系统执行混合搜索,返回相关记忆片段
- Agent选择最相关的结果(score>0.35)
- 调用memory_get精确读取具体行数
- 将记忆片段注入当前上下文
3.3 会话压缩机制
当上下文长度接近限制时:
- 触发Memory Flush回合:
typescript复制export const DEFAULT_MEMORY_FLUSH_PROMPT = [ "Pre-compaction memory flush.", "Store durable memories now...", `If nothing to store, reply with ${SILENT_REPLY_TOKEN}.` ].join(" "); - Agent判断哪些信息需要持久化
- 系统对剩余上下文进行摘要压缩:
typescript复制const MERGE_SUMMARIES_INSTRUCTIONS = "Merge these partial summaries...Preserve decisions, TODOs..."; - 压缩后的摘要替换原始上下文
4. 性能优化与成本分析
4.1 Token消耗组成
尽管记忆系统优化了上下文长度,但OpenClaw的token消耗仍来自多个方面:
| 消耗项 | 估算tokens | 说明 |
|---|---|---|
| 系统提示词 | 5,000-25,000 | 包含核心指令、工具说明等 |
| 工具定义 | 3,000-5,000 | 所有可用工具的JSON Schema |
| 会话历史 | 可变 | 直到触发压缩前持续增长 |
| 记忆检索结果 | 200-1,000 | 每次搜索返回的内容 |
| 工具调用链 | 每次200-500 | 多步工具调用的请求/响应 |
4.2 成本优化策略
-
精简系统提示词:
- 移除不必要的指令
- 压缩工具描述
- 限制bootstrap文件大小
-
选择性启用工具:
- 只加载当前场景需要的工具
- 禁用不常用的工具定义
-
调整压缩阈值:
json复制// config.json { "compaction": { "threshold": 15000 // 默认20000 } } -
使用低成本模型:
- 对非关键任务使用gpt-3.5-turbo
- 本地模型处理简单查询
5. 实践经验与优化建议
5.1 最佳实践
-
主动管理记忆:
- 定期检查MEMORY.md文件
- 使用/forget命令清理过时信息
- 为重要信息添加明确标签
-
优化搜索查询:
python复制# 不佳查询 "我之前说的那个东西" # 优化查询 "2023年项目计划中的预算数字" -
合理使用会话命令:
- /new - 结束当前会话并保存要点
- /summary - 获取当前会话摘要
- /compress - 手动触发早期压缩
5.2 常见问题排查
-
记忆未被正确保存:
- 检查~/.openclaw/workspace/memory/目录权限
- 验证文件系统监控是否正常工作
- 查看agent日志中的flush记录
-
搜索召回率低:
bash复制# 检查索引状态 sqlite3 ~/.openclaw/data/memory.db "SELECT count(*) FROM chunks" # 重建索引 rm ~/.openclaw/data/memory.db touch ~/.openclaw/workspace/MEMORY.md -
token消耗异常高:
- 使用/debug tokens命令分析消耗组成
- 检查是否有工具在循环调用
- 验证压缩机制是否正常触发
6. 技术演进方向
OpenClaw记忆系统的未来优化可能包括:
-
分层记忆压缩:
- 近期记忆:保留原始对话
- 中期记忆:保存详细摘要
- 长期记忆:只保留关键事实
-
记忆关联网络:
mermaid复制graph LR A[用户偏好] --> B[项目A] A --> C[项目B] D[会议记录] --> B D --> C -
个性化embedding:
- 基于用户反馈调整向量权重
- 领域特定的embedding微调
-
记忆生命周期管理:
- 自动过期临时性记忆
- 基于重要性的记忆衰减算法
在实际使用中,我发现OpenClaw的记忆系统虽然设计精巧,但仍需要用户主动参与管理才能发挥最大价值。建议每周花10分钟审查记忆文件,使用明确的Markdown标题结构,并定期清理测试会话产生的不必要记忆。对于团队使用场景,可以考虑建立记忆命名规范,比如为每个项目添加统一前缀,这样可以大幅提高搜索效率。