Skip to content

OpenClaw 记忆管理完全指南

记忆是 AI 助理保持连续性和个性化的关键。OpenClaw 提供 memory_searchmemory_get 两个工具,支持语义搜索和精确读取记忆文件。本文详细介绍如何高效使用这些工具构建有"记忆"的 AI 助理。

一、工具概述

memory_search - 语义搜索

在记忆文件中搜索相关内容:

  • 支持语义理解(不仅仅是关键词匹配)
  • 搜索范围:MEMORY.md + memory/*.md
  • 返回最相关的片段及位置
  • 可设置最小相关度和最大结果数
javascript
// 基本搜索
memory_search(query="用户偏好")

// 设置参数
memory_search(
  query="项目截止日期",
  minScore=0.7,      // 最小相关度(0-1)
  maxResults=5       // 最多返回结果数
)

memory_get - 精确读取

从指定记忆文件读取特定行:

  • 精确控制读取位置
  • 支持从某行开始读取指定行数
  • 适合读取已知位置的内容
javascript
// 读取整个文件
memory_get(path="MEMORY.md")

// 从第 10 行开始读取 20 行
memory_get(path="memory/2026-03-19.md", from=10, lines=20)

二、记忆文件结构

工作区文件

~/.openclaw/workspace/
├── MEMORY.md          # 长期记忆(主会话专用)
├── SOUL.md            # AI 人格定义
├── USER.md            # 用户信息
├── TOOLS.md           # 工具配置和本地笔记
└── memory/
    ├── 2026-03-17.md  # 每日记忆
    ├── 2026-03-18.md
    └── 2026-03-19.md

MEMORY.md - 长期记忆

用途: 存储需要长期记住的重要信息

特点:

  • 只在主会话(与用户直接对话)加载
  • 群聊、共享会话不加载(安全考虑)
  • 需要人工或 AI 定期整理更新

内容示例:

# 长期记忆

## 用户偏好
- 称呼:老大
- 回复风格:简洁,不啰嗦
- 执行风格:严格命令,不耍滑头

## 重要日期
- 用户生日:1990-05-15
- 项目上线:2026-03-17

## 项目信息
- 网站名称:AiTimes 智能时代
- 域名:www.AiTimes.net
- 技术栈:OpenClaw + VitePress

memory/YYYY-MM-DD.md - 每日记忆

用途: 记录当天的重要事件和对话

特点:

  • 每天一个文件
  • 自动创建(如不存在)
  • 详细记录原始对话和事件

内容示例:

# 2026-03-19

## 重要对话
- 06:05 用户指出文章质量问题
- 06:30 重新发布 7 篇详实文章
- 07:00 总结经验并写入 TOOLS.md

## 完成的任务
- ✅ 发布 7 篇教程文章
- ✅ 建立文章发布流程
- ✅ 配置防重复机制

## 学到的经验
- 质量优先于速度
- 建立标准化流程
- 及时记录经验

三、实战案例 1:个性化对话

场景说明

记住用户的偏好、历史对话,提供个性化的回复和服务。

完整实现

javascript
// 个性化对话管理器
class PersonalizedChat {
  constructor() {
    this.userPrefs = null
    this.loadUserPrefs()
  }
  
  // 加载用户偏好
  async loadUserPrefs() {
    try {
      // 搜索用户偏好相关记忆
      const result = memory_search(
        query="用户偏好 称呼 风格 习惯",
        maxResults=5
      )
      
      // 解析偏好
      this.userPrefs = this.parsePrefs(result)
    } catch (e) {
      console.log("未找到用户偏好,使用默认设置")
      this.userPrefs = {
        address: "用户",
        style: "friendly"
      }
    }
  }
  
  // 解析偏好
  parsePrefs(searchResult) {
    const prefs = {}
    
    // 提取称呼
    const addressMatch = searchResult.match(/称呼 [::]\s*(.+)/)
    prefs.address = addressMatch ? addressMatch[1].trim() : "用户"
    
    // 提取回复风格
    const styleMatch = searchResult.match(/回复风格 [::]\s*(.+)/)
    prefs.style = styleMatch ? styleMatch[1].trim() : "friendly"
    
    // 提取执行风格
    const execMatch = searchResult.match(/执行风格 [::]\s*(.+)/)
    prefs.exec = execMatch ? execMatch[1].trim() : "normal"
    
    return prefs
  }
  
  // 生成个性化回复
  generateResponse(message, context) {
    // 根据偏好调整回复风格
    if (this.userPrefs.style.includes("简洁")) {
      return this.conciseResponse(message, context)
    } else if (this.userPrefs.style.includes("详细")) {
      return this.detailedResponse(message, context)
    } else {
      return this.normalResponse(message, context)
    }
  }
  
  // 记录对话到记忆
  async recordConversation(userMessage, aiResponse) {
    const today = new Date().toISOString().split('T')[0]
    const memoryPath = `memory/${today}.md`
    
    // 读取今日记忆
    let todayMemory = ""
    try {
      todayMemory = memory_get(path=memoryPath)
    } catch (e) {
      // 文件不存在,创建新文件
    }
    
    // 追加对话记录
    const entry = `
## 对话记录 - ${new Date().toLocaleTimeString('zh-CN')}

**用户**: ${userMessage.substring(0, 100)}...
**AI**: ${aiResponse.substring(0, 100)}...

`
    
    write(path=memoryPath, content=todayMemory + entry)
  }
}

// 使用示例
const chat = new PersonalizedChat()

// 生成回复
const response = chat.generateResponse(
  "帮我写个报告",
  { topic: "项目进度", deadline: "明天" }
)

// 记录对话
await chat.recordConversation("帮我写个报告", response)

个性化回复示例

// 用户偏好:简洁
用户:"帮我写个报告"
AI:"好的,报告主题和截止日期是?"

// 用户偏好:详细
用户:"帮我写个报告"
AI:"好的,我很乐意帮您写报告。请告诉我:
1. 报告的主题是什么?
2. 报告的用途(汇报/总结/计划)?
3. 需要包含哪些部分?
4. 截止日期是什么时候?
5. 有没有字数要求?"

四、实战案例 2:项目进度跟踪

场景说明

记住项目的关键节点、待办事项、决策记录,随时回答项目相关问题。

完整实现

javascript
// 项目记忆管理器
class ProjectMemory {
  constructor(projectName) {
    this.projectName = projectName
    this.memoryTag = `项目:${projectName}`
  }
  
  // 记录项目决策
  async recordDecision(decision, rationale, alternatives) {
    const entry = `
## 项目决策 - ${new Date().toISOString()}

**决策**: ${decision}
**理由**: ${rationale}
**备选方案**: ${alternatives}
**标签**: ${this.memoryTag}
`
    
    // 追加到 MEMORY.md
    let memory = ""
    try {
      memory = memory_get(path="MEMORY.md")
    } catch (e) {
      memory = `# ${this.projectName} 项目记忆\n`
    }
    
    write(path="MEMORY.md", content=memory + entry)
  }
  
  // 记录待办事项
  async recordTodo(todo, priority, deadline) {
    const entry = `
## 待办 - ${new Date().toISOString()}

**任务**: ${todo}
**优先级**: ${priority}
**截止**: ${deadline}
**状态**: 待办
**标签**: ${this.memoryTag}
`
    
    let memory = ""
    try {
      memory = memory_get(path="MEMORY.md")
    } catch (e) {
      memory = `# ${this.projectName} 项目记忆\n`
    }
    
    write(path="MEMORY.md", content=memory + entry)
  }
  
  // 更新待办状态
  async updateTodoStatus(todoId, status, notes) {
    // 搜索相关待办
    const result = memory_search(
      query=`${this.memoryTag} 待办 ${todoId}`,
      maxResults=1
    )
    
    // 更新状态(需要手动编辑文件)
    // 这里简化处理,实际应使用 edit 工具
    console.log(`更新待办 ${todoId} 状态为 ${status}`)
  }
  
  // 查询项目信息
  async queryProjectInfo(query) {
    // 搜索项目相关记忆
    const result = memory_search(
      query=`${this.memoryTag} ${query}`,
      maxResults=10
    )
    
    return this.formatQueryResult(result)
  }
  
  // 格式化查询结果
  formatQueryResult(searchResult) {
    // 提取决策、待办、笔记等
    const decisions = searchResult.match(/## 项目决策.*?(?=##|$)/gs) || []
    const todos = searchResult.match(/## 待办.*?(?=##|$)/gs) || []
    
    return {
      decisions: decisions.map(d => this.parseDecision(d)),
      todos: todos.map(t => this.parseTodo(t)),
      total: decisions.length + todos.length
    }
  }
}

// 使用示例
const project = new ProjectMemory("AiTimes 网站")

// 记录技术选型决策
await project.recordDecision(
  "使用 VitePress 作为静态网站生成器",
  "轻量、快速、支持 Markdown,适合文档类网站",
  "备选:VuePress, Docusaurus, GitBook"
)

// 添加待办事项
await project.recordTodo(
  "完成首页设计",
  "高",
  "2026-03-20"
)

// 查询项目信息
const info = await project.queryProjectInfo("技术选型")
console.log(`找到 ${info.total} 条相关信息`)

查询结果示例

查询:"技术选型"

找到 3 条相关信息

## 项目决策 - 2026-03-17
**决策**: 使用 VitePress 作为静态网站生成器
**理由**: 轻量、快速、支持 Markdown,适合文档类网站
**备选方案**: VuePress, Docusaurus, GitBook

## 项目决策 - 2026-03-18
**决策**: 使用 Gitee Pages 部署
**理由**: 国内访问速度快,免费额度够用
**备选方案**: GitHub Pages, Vercel, Netlify

五、实战案例 3:学习笔记管理

场景说明

记录学习过程中的重点、疑问、心得,形成可搜索的知识库。

完整实现

javascript
// 学习笔记管理器
class LearningNotes {
  constructor(subject) {
    this.subject = subject
    this.notesFile = `memory/learning-${subject}.md`
  }
  
  // 添加学习笔记
  async addNote(topic, content, tags) {
    const entry = `
## ${topic} - ${new Date().toISOString()}

${content}

**标签**: ${tags.join(', ')}
**主题**: ${this.subject}

---
`
    
    let notes = ""
    try {
      notes = memory_get(path=this.notesFile)
    } catch (e) {
      notes = `# ${this.subject} 学习笔记\n\n`
    }
    
    write(path=this.notesFile, content=notes + entry)
  }
  
  // 记录疑问
  async recordQuestion(question, context) {
    const entry = `
## ❓ 疑问 - ${new Date().toISOString()}

**问题**: ${question}
**上下文**: ${context}
**状态**: 待解答

---
`
    
    let notes = ""
    try {
      notes = memory_get(path=this.notesFile)
    } catch (e) {
      notes = `# ${this.subject} 学习笔记\n\n`
    }
    
    write(path=this.notesFile, content=notes + entry)
  }
  
  // 解答疑问
  async answerQuestion(questionId, answer) {
    // 搜索疑问
    const result = memory_search(
      query=`${this.subject} 疑问 ${questionId}`,
      maxResults=1
    )
    
    // 更新笔记(简化处理)
    console.log(`解答疑问 ${questionId}: ${answer}`)
  }
  
  // 复习笔记
  async reviewNotes(topics, interval='7d') {
    // 搜索相关笔记
    const results = []
    for (const topic of topics) {
      const result = memory_search(
        query=`${this.subject} ${topic}`,
        maxResults=5
      )
      results.push({ topic, result })
    }
    
    // 生成复习计划
    const reviewPlan = `
# 复习计划 - ${this.subject}

生成时间:${new Date().toLocaleString('zh-CN')}
复习周期:${interval}

## 复习内容

${results.map(r => `
### ${r.topic}
找到 ${r.result.split('##').length - 1} 条相关笔记
`).join('\n')}

## 复习建议

1. 先看概览,再看细节
2. 重点关注标记为"重点"的内容
3. 解答之前的疑问
4. 记录新的理解
`
    
    return reviewPlan
  }
  
  // 导出笔记
  async exportNotes(format='markdown') {
    const notes = memory_get(path=this.notesFile)
    
    if (format === 'markdown') {
      return notes
    } else if (format === 'json') {
      // 解析为 JSON 格式
      const sections = notes.split('## ').slice(1)
      return sections.map(s => {
        const [title, ...content] = s.split('\n')
        return {
          title: title.split(' - ')[0],
          date: title.split(' - ')[1],
          content: content.join('\n')
        }
      })
    }
  }
}

// 使用示例
const learning = new LearningNotes("OpenClaw")

// 添加学习笔记
await learning.addNote(
  "记忆管理工具",
  `
memory_search 用于语义搜索记忆文件。
memory_get 用于精确读取指定位置。

使用场景:
1. 记住用户偏好
2. 跟踪项目进度
3. 管理学习笔记

注意事项:
- MEMORY.md 只在主会话加载
- 定期整理,删除过时信息
  `,
  ["工具", "记忆", "重点"]
)

// 记录疑问
await learning.recordQuestion(
  "如何保证记忆的安全性?",
  "记忆文件包含敏感信息,如何防止泄露?"
)

// 复习笔记
const plan = await learning.reviewNotes(["工具", "安全", "最佳实践"])
console.log(plan)

学习笔记示例

# OpenClaw 学习笔记

## 记忆管理工具 - 2026-03-19T08:00:00.000Z

memory_search 用于语义搜索记忆文件。
memory_get 用于精确读取指定位置。

使用场景:
1. 记住用户偏好
2. 跟踪项目进度
3. 管理学习笔记

注意事项:
- MEMORY.md 只在主会话加载
- 定期整理,删除过时信息

**标签**: 工具,记忆,重点
**主题**: OpenClaw

---

## ❓ 疑问 - 2026-03-19T08:05:00.000Z

**问题**: 如何保证记忆的安全性?
**上下文**: 记忆文件包含敏感信息,如何防止泄露?
**状态**: 待解答

---

六、高级技巧

1. 定期整理记忆

javascript
// 每周整理记忆,删除过时信息
async function weeklyMemoryCleanup() {
  // 读取 MEMORY.md
  let memory = memory_get(path="MEMORY.md")
  
  // 提取所有日期
  const dates = memory.match(/\d{4}-\d{2}-\d{2}/g) || []
  
  // 找出 3 个月前的内容
  const threeMonthsAgo = new Date()
  threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3)
  
  const outdatedDates = dates.filter(d => new Date(d) < threeMonthsAgo)
  
  if (outdatedDates.length > 0) {
    console.log(`发现 ${outdatedDates.length} 条过时内容`)
    // 可以归档或删除
    // 注意:删除前询问用户
  }
}

2. 记忆备份

javascript
// 定期备份记忆文件
async function backupMemories() {
  const timestamp = Date.now()
  const backupDir = `~/.openclaw/backups/memory-${timestamp}`
  
  // 创建备份目录
  exec(command=`mkdir -p ${backupDir}`)
  
  // 备份 MEMORY.md
  try {
    const memory = memory_get(path="MEMORY.md")
    write(path=`${backupDir}/MEMORY.md`, content=memory)
  } catch (e) {
    console.log("MEMORY.md 不存在,跳过")
  }
  
  // 备份每日记忆
  const dailyFiles = exec(
    command="ls ~/.openclaw/workspace/memory/*.md",
    capture_output=True
  ).stdout.trim().split('\n')
  
  for (const file of dailyFiles) {
    if (file) {
      const filename = file.split('/').pop()
      const content = read(path=file)
      write(path=`${backupDir}/${filename}`, content=content)
    }
  }
  
  console.log(`✅ 记忆备份完成:${backupDir}`)
}

3. 记忆导入导出

javascript
// 导出记忆为 JSON
async function exportMemories() {
  const memory = memory_get(path="MEMORY.md")
  
  // 解析为结构化数据
  const sections = memory.split(/^## /m).slice(1)
  const structured = sections.map(section => {
    const [title, ...lines] = section.split('\n')
    return {
      title: title.trim(),
      content: lines.join('\n').trim()
    }
  })
  
  return {
    exportedAt: new Date().toISOString(),
    totalSections: structured.length,
    data: structured
  }
}

// 从 JSON 导入记忆
async function importMemories(jsonData) {
  let memory = "# 长期记忆\n\n"
  
  for (const section of jsonData.data) {
    memory += `## ${section.title}\n\n${section.content}\n\n`
  }
  
  write(path="MEMORY.md", content=memory)
  console.log(`✅ 导入 ${jsonData.data.length} 条记忆`)
}

七、最佳实践

1. 记忆分类

✅ 好的分类:
- 用户偏好
- 项目信息
- 学习笔记
- 重要日期
- 决策记录

❌ 差的分类:
- 把所有内容都堆在一起
- 没有标签和日期
- 不区分长期和短期记忆

2. 定期更新

javascript
// ✅ 好的做法:每天回顾,每周整理
// 每天:记录当天重要事件到 memory/YYYY-MM-DD.md
// 每周:整理 MEMORY.md,删除过时信息
// 每月:导出备份,防止数据丢失

// ❌ 差的做法:
// - 从不整理,记忆文件越来越大
// - 只记录不删除,包含大量过时信息
// - 不备份,数据丢失风险

3. 安全考虑

javascript
// ✅ 好的做法:
// - 敏感信息加密存储
// - MEMORY.md 只在主会话加载
// - 群聊中不读取个人记忆
// - 定期审查记忆内容

// ❌ 差的做法:
// - 在群聊中暴露用户隐私
// - 记忆文件包含明文密码
// - 不审查就记录所有对话

八、常见问题

Q: memory_search 和 web_search 有什么区别?

A:

  • memory_search: 搜索本地记忆文件(语义搜索)
  • web_search: 搜索互联网(基于 Brave API)

Q: 如何确保记忆的准确性?

A:

  1. 记录时注明来源和时间
  2. 定期回顾和验证
  3. 用户确认重要信息
  4. 标记不确定的内容

Q: 记忆文件太大怎么办?

A:

  1. 定期整理,删除过时信息
  2. 归档旧记忆到单独文件
  3. 使用搜索而非全量读取
  4. 分主题存储(如 learning-xxx.md)

Q: 可以在群聊中使用记忆吗?

A:

  • 可以,但要注意安全
  • MEMORY.md 只在主会话自动加载
  • 群聊中手动读取时避免暴露隐私
  • 敏感信息使用加密存储

九、总结

记忆管理让 AI 助理更有"人性":

工具用途特点
memory_search语义搜索理解意图,返回相关片段
memory_get精确读取控制位置,适合已知内容

掌握记忆管理,你可以:

  • 记住用户偏好,提供个性化服务
  • 跟踪项目进度,随时回答疑问
  • 管理学习笔记,形成知识库
  • 保持对话连续性,提升体验

记住:好的记忆 = 准确记录 + 定期整理 + 安全存储


相关资源:

Released under the MIT License.