开启左侧

OpenClaw 记忆系统源码深度分析

[复制链接]
米落枫 发表于 前天 18:37 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
作者:CSDN博客
分块策略
  1. // internal.tsexportfunctionchunkMarkdown(params:{
  2.   content:string;
  3.   tokens:number;// 默认 400
  4.   overlap:number;// 默认 80}): MemoryChunk[]{const chunks: MemoryChunk[]=[];const lines = params.content.split('\n');let currentChunk ="";let currentTokens =0;for(const line of lines){const lineTokens =estimateTokens(line);if(currentTokens + lineTokens > params.tokens && currentChunk.length >0){
  5.       chunks.push({ text: currentChunk.trim(),...});const overlapText =extractOverlap(currentChunk, params.overlap);
  6.       currentChunk = overlapText +'\n'+ line;
  7.       currentTokens =estimateTokens(overlapText)+ lineTokens;}else{
  8.       currentChunk += line +'\n';
  9.       currentTokens += lineTokens;}}return chunks;}
复制代码
分块示意
  1. ┌─────────────────────────────────────────┐
  2. │  MEMORY.md 内容                          │
  3. ├─────────────────────────────────────────┤
  4. │  Line 1: # 概述                          │
  5. │  Line 2:                                 │
  6. │  Line 3: 这是内容...                      │
  7. │  ...                                     │
  8. ├─────────────────────────────────────────┤
  9. │  Chunk 1 (Lines 1-10)                    │
  10. │  Chunk 2 (Lines 5-15) ← overlap         │
  11. │  Chunk 3 (Lines 12-22)                  │
  12. └─────────────────────────────────────────┘
复制代码
Embedding 缓存
  1. classMemoryIndexManager{privateasyncgetEmbeddingWithCache(text:string):Promise<number[]>{const hash =hashText(text);// 1. 查找缓存const cached =this.db
  2.       .prepare(`SELECT embedding FROM embedding_cache WHERE hash = ?`).get(hash);if(cached)returnparseEmbedding(cached.embedding);// 2. 调用 LLM 计算const embedding =awaitthis.provider.embed(text);// 3. 存入缓存this.db
  3.       .prepare(`INSERT INTO embedding_cache VALUES (?, ?, ?, ?, ?, ?)`).run(this.provider,this.model,this.providerKey, hash,JSON.stringify(embedding), Date.now());return embedding;}}
复制代码

记忆存储

文件结构
  1. ~/.openclaw/workspace/
  2. ├── AGENTS.md           # Agent 配置 (自动加载)
  3. ├── SOUL.md             # Agent 身份定义
  4. ├── USER.md             # 用户信息
  5. ├── TOOLS.md            # 工具配置
  6. ├── MEMORY.md           # 长期记忆
  7. ├── memory/             # 记忆文件目录
  8. │   ├── daily-notes/    # 每日笔记
  9. │   ├── projects/       # 项目相关
  10. │   └── ...
  11. ├── sessions/           # 会话历史
  12. └── [其他项目文件]
复制代码
配置示例
  1. {"memory":{"sources":["memory","sessions"],"extraPaths":["/path/to/extra"],"provider":"auto","model":"text-embedding-3-small","chunking":{"tokens":400,"overlap":80},"query":{"maxResults":6,"minScore":0.35,"hybrid":{"enabled":true,"vectorWeight":0.7,"textWeight":0.3}}}}
复制代码

配置选项

默认值速查表

配置项默认值说明
provider"auto"自动选择提供商
chunking.tokens400每块最大 token
chunking.overlap80重叠 token 数
query.maxResults6返回结果数
query.minScore0.35最小相似度
query.hybrid.enabledtrue启用混合搜索
query.hybrid.vectorWeight0.7向量权重
query.hybrid.textWeight0.3关键词权重
sync.watchDebounceMs1500防抖时间
cache.enabledtrue启用缓存
Embedding 提供商

提供商模型特点
openaitext-embedding-3-small性价比高
geminigemini-embedding-001Google 生态
voyagevoyage-4-large高质量
local本地模型隐私保护
auto自动选择默认推荐

使用指南

工具调用

memory_search - 语义搜索
  1. exportasyncfunctionmemory_search(
  2.   query:string,
  3.   maxResults?:number,
  4.   minScore?:number):Promise<MemorySearchResult[]>
复制代码
使用示例:
  1. 搜索: "Tom 的项目信息"
  2. 返回:
  3.   [
  4.     {
  5.       "path": "memory/projects/openclaw.md",
  6.       "startLine": 10,
  7.       "endLine": 20,
  8.       "score": 0.85,
  9.       "snippet": "Tom 正在开发 OpenClaw...",
  10.       "source": "memory"
  11.     }
  12.   ]
复制代码
memory_get - 读取记忆
  1. // 读取文件awaitmemory_get({ path:"memory/daily-notes/2024-01-15.md"});// 读取行范围awaitmemory_get({ path:"memory/projects.md", from:10, lines:20});
复制代码
最佳实践

1. 记忆文件组织
  1. memory/
  2. ├── AGENTS.md           # Agent 核心配置
  3. ├── SOUL.md             # Agent 身份定义
  4. ├── USER.md             # 用户偏好
  5. ├── MEMORY.md           # 长期重要记忆
  6. ├── daily-notes/        # 每日笔记
  7. │   ├── 2024-01-15.md
  8. │   └── 2024-01-16.md
  9. ├── projects/           # 项目相关
  10. │   ├── openclaw.md
  11. │   └── website.md
  12. └── preferences/        # 偏好设置
复制代码
2. 内容格式
  1. # SSH 配置
  2. ## 概述
  3. 记录 Tom 的 SSH 配置信息。
  4. ## 主机信息
  5. - 服务器: 192.168.1.100
  6. - 用户: admin
  7. - 端口: 22
  8. ## 密钥位置
  9. ~/.ssh/id_rsa_openclaw
复制代码
3. 性能优化
  1. // 减少返回结果awaitmemory_search("查询", maxResults=3);// 提高分数阈值awaitmemory_search("查询", minScore=0.5);// 禁用混合搜索{"memory":{"query":{"hybrid":{"enabled":false}}}}
复制代码

源码关键代码解读

1. 混合搜索入口
  1. // manager.tsasyncsearch(query:string, opts?:{...}):Promise<MemorySearchResult[]>{const queryVec =awaitthis.provider.embed(query);returnawaitthis.hybridSearch(queryVec, opts);}privateasynchybridSearch(queryVec:number[], opts?:{...}){const{ hybrid }=this.settings.query;if(hybrid.enabled && queryVec.length >0){const[vectorResults, keywordResults]=awaitPromise.all([this.searchVector(queryVec, opts),this.searchKeyword(query, opts),]);returnmergeHybridResults({
  2.       vector: vectorResults,
  3.       keyword: keywordResults,
  4.       vectorWeight: hybrid.vectorWeight,
  5.       textWeight: hybrid.textWeight,});}return queryVec.length >0?this.searchVector(queryVec, opts):this.searchKeyword(query, opts);}
复制代码
2. 评分计算
  1. // 综合评分公式
  2. score = vectorWeight × vectorScore + textWeight × textScore
  3. // 示例// 向量 0.9 + 关键词 0.6// 综合 = 0.7 × 0.9 + 0.3 × 0.6 = 0.81
复制代码
3. 增量同步
  1. // manager.tsprivateasyncsyncFiles():Promise<void>{const files =awaitlistMemoryFiles(this.memoryDir);for(const file of files){const currentHash =awaithashFile(file.path);const dbHash =this.getFileHash(file.path);if(currentHash !== dbHash){awaitthis.reindexFile(file);}}this.cleanupDeletedFiles();}
复制代码

常见问题

Q1: 搜索不到内容?

    检查 memory/ 目录下是否有文件确认 memory_search 的 minScore 不要太高运行 memory_sync 手动触发同步
Q2: 性能差?

    启用 Embedding 缓存 (cache.enabled: true)使用 sqlite-vec 扩展加速向量搜索减少 chunking.tokens 增加并行度
Q3: FTS 不可用?

SQLite 编译时缺少 FTS5 模块,降级到关键词匹配。
Q4: 如何清除索引?

删除 SQLite 数据库文件:
  1. rm ~/.openclaw/workspace/.memory/index.sqlite
复制代码
Q5: 支持哪些 Embedding 模型?

提供商模型
OpenAItext-embedding-3-small, text-embedding-3-large
Geminigemini-embedding-001
Voyagevoyage-2, voyage-4-large
本地支持 Ollama 等兼容 OpenAI API 的服务

总结

OpenClaw 记忆系统核心要点:
    混合搜索: 向量 (70%) + 关键词 (30%) 融合SQLite 存储: 轻量级本地数据库自动同步: 文件变化监听 + 防抖增量更新: 只处理变更文件嵌入缓存: 避免重复计算分块策略: 400 tokens + 80 overlap故障转移: QMD → 内置索引回退
掌握这些,就能高效使用 OpenClaw 的记忆系统!

原文地址:https://blog.csdn.net/caicongyang/article/details/158073798
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题
阅读排行更多+

Powered by Discuz! X3.4© 2001-2013 Discuz Team.( 京ICP备17022993号-3 )