OpenClaw Agent 三层记忆系统实战指南

0 阅读12分钟

让AI学会像人一样记忆、思考和检索 版本:1.0 | 更新日期:2026-02-28


📋 目录

  1. 为什么需要记忆系统
  2. 三层记忆架构
  3. 文件结构设计
  4. 核心代码实现
  5. 使用规范
  6. 工作流程
  7. 实际案例
  8. 常见问题

1. 为什么需要记忆系统

1.1 AI的痛点

痛点表现影响
上下文丢失每次对话都是全新开始重复解释背景
知识遗忘不记得之前的讨论无法连续工作
偏好未知不记得用户习惯每次都从头了解
任务中断无法继续未完成的工作效率低下

1.2 解决方案

三层记忆架构 = 短期记忆 + 中期存储 + 长期沉淀

就像人脑一样:

  • 短期记忆:记住当前正在做的事情
  • 中期记忆:记住今天发生了什么
  • 长期记忆:记住最重要的经验和知识

2. 三层记忆架构

2.1 架构概览

┌─────────────────────────────────────────────────────────┐
│                    用户对话输入                          │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│  第一层:感知层 (SESSION-STATE.md)                        │
│  - 当前任务状态                                          │
│  - 待办事项                                             │
│  - 用户信息                                             │
│  - 会话上下文                                           │
└─────────────────────┬───────────────────────────────────┘
                      │ 每条消息后更新
                      ▼
┌─────────────────────────────────────────────────────────┐
│  第二层:存储层 (memory/YYYY-MM-DD.md)                   │
│  - 每日工作日志                                         │
│  - 完整对话记录                                         │
│  - 任务执行结果                                         │
│  - 学习内容                                             │
└─────────────────────┬───────────────────────────────────┘
                      │ 每天归档
                      ▼
┌─────────────────────────────────────────────────────────┐
│  第三层:认知层 (MEMORY.md)                              │
│  - 提炼的经验和方法论                                   │
│  - 用户画像和偏好                                       │
│  - 重要决策记录                                         │
│  - 技能和知识库                                         │
└─────────────────────────────────────────────────────────┘

2.2 各层职责

层级文件更新频率容量用途
感知层SESSION-STATE.md每条消息最小当前任务
存储层memory/YYYY-MM-DD.md实时中等历史记录
认知层MEMORY.md定期最大知识沉淀

2.3 信息流动

感知 → 存储 → 认知  (信息沉淀方向)
认知 → 存储 → 感知  (检索调用方向)

3. 文件结构设计

3.1 必需文件

workspace/
├── SESSION-STATE.md           # 当前会话状态(必须)
├── MEMORY.md                  # 长期记忆(必须)
├── memory/
   ├── 2026-01-01.md          # 每日日志
   ├── 2026-01-02.md
   └── ...
├── AGENTS.md                  # 运行规则
├── USER.md                   # 用户画像
├── SOUL.md                   # AI人格设定
└── IDENTITY.md               # 身份定义

3.2 SESSION-STATE.md 结构

# 当前会话状态

## 当前任务
- 任务:描述当前正在做的事情
- 进度:X%
- 待办:
  - [ ] 待办事项1
  - [ ] 待办事项2

## 用户信息
- 名字:非空
- 目标:建立高效AI Agent系统
- 偏好:详细、有结构、直接

## 重要上下文
- 项目状态:进行中
- 讨论主题:三层记忆系统

## 刚刚完成
- 1. 回答了关于飞书API的问题

## 刚刚听到
- 用户提到想要建立记忆系统

3.3 memory/YYYY-MM-DD.md 结构

# 2026-02-28 工作记录

## 对话记录

### 上午
- 9:00 与非空讨论飞书文档问题
  - 问题:文档内容为空
  - 解决:分块写入内容
  - 经验:飞书API对表格支持有限

- 10:30 整理三层记忆文档
  - 完成:基础框架
  - 待补充:实际案例

### 下午
- 14:00 修复收集系统bug
  - 问题:历史记录未更新
  - 原因:add_to_history逻辑问题
  - 解决:手动更新history文件

## 任务完成
- ✅ 修复夜间素材收集系统
- ✅ 整理记忆系统文档

## 学习收获
- 了解了飞书文档API的限制
- 学会了分块写入内容

## 待处理
- [ ] 完善记忆系统教学文档
- [ ] 测试新的收集系统

3.4 MEMORY.md 结构

# MEMORY.md - 长期记忆

> 提炼自每日笔记。删除过时信息。

---

## 用户画像

### 基础信息
- 名字:非空
- 角色:内容创作者、技术爱好者
- 目标:建立高效AI Agent系统

### 偏好
- 沟通风格:详细、有结构、直接
- 工作风格:主动、高效、注重质量
- 不喜欢:重复、拖延、缺乏结构

---

## 核心工作流程

### 内容创作流程
1. 选题策划 → ai-interview 梳理目标读者
2. 素材收集 → 夜间自动收集
3. 初稿生成 → 基于分析生成文章
4. 优化润色 → humanizer 去除AI痕迹
5. 排版发布 → weixin-article-style

### 任务管理流程
1. 创建任务 → 看板中添加
2. 设置时间 → 执行时间和截止日期
3. 自动执行 → 到达时间后自动执行
4. 周复盘 → 每周五自动生成

---

## 重要经验

### 技术
- 飞书文档API对表格支持有限,需要分块写入

### 沟通
- 沟通四步法:情感共鸣 → 建立信任 → 陈述事实 → 表达需求
- 70%情绪,30%内容

---

## 技能清单

| 技能 | 用途 | 状态 |
|------|------|------|
| ai-interview | 结构化访谈 | ✅ |
| ai-pattern-learn | 案例学习 | ✅ |
| humanizer | 去除AI痕迹 | ✅ |
| article-workflow | 内容创作自动化 | ✅ |
| study-tracker | 学习进度追踪 | ✅ |

---

*最后更新:2026-02-28*

4. 核心代码实现

4.1 记忆管理器 (Python)

#!/usr/bin/env python3
"""
AI Agent 记忆管理系统
负责三层记忆的读取、更新和检索
"""

import os
import re
import json
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional


class MemoryManager:
    """记忆管理器"""
    
    def __init__(self, workspace: str = None):
        """初始化记忆管理器"""
        if workspace is None:
            workspace = os.environ.get('OPENCLAW_WORKSPACE', '/home/pi/.openclaw/workspace')
        
        self.workspace = Path(workspace)
        self.session_state = self.workspace / 'SESSION-STATE.md'
        self.memory = self.workspace / 'MEMORY.md'
        self.memory_dir = self.workspace / 'memory'
        
        # 确保目录存在
        self.memory_dir.mkdir(exist_ok=True)
        
        # 初始化文件
        self._init_files()
    
    def _init_files(self):
        """初始化必要的文件"""
        # SESSION-STATE.md
        if not self.session_state.exists():
            self.session_state.write_text("""# 当前会话状态

## 当前任务
- 任务:等待用户输入
- 进度:0%
- 待办:[]

## 用户信息
- 名字:
- 目标:
- 偏好:

## 重要上下文
-

## 刚刚完成
- (无)

## 刚刚听到
- (无)
""", encoding='utf-8')
        
        # MEMORY.md
        if not self.memory.exists():
            self.memory.write_text("""# MEMORY.md - 长期记忆

> 提炼自每日笔记。删除过时信息。

---

## 用户画像

### 基础信息
- 名字:
- 角色:
- 目标:

### 偏好
- 沟通风格:
- 工作风格:
- 不喜欢:

---

## 核心工作流程

[待补充]

---

## 重要经验

[待补充]

---

*最后更新:{date}*
""".format(date=datetime.now().strftime('%Y-%m-%d')), encoding='utf-8')
    
    # ===== 感知层操作 =====
    
    def update_task(self, task: str, progress: str = "0%", todos: List[str] = None):
        """更新当前任务"""
        content = self.session_state.read_text(encoding='utf-8')
        
        # 更新任务
        pattern = r'(- 任务:).*'
        content = re.sub(pattern, f'- 任务:{task}', content)
        
        # 更新进度
        pattern = r'(- 进度:).*'
        content = re.sub(pattern, f'- 进度:{progress}', content)
        
        # 更新待办
        if todos:
            todo_text = '\n'.join([f'  - [ ] {t}' for t in todos])
            pattern = r'(- 待办:\[).*?(\])'
            content = re.sub(pattern, f'- 待办:[\n{todo_text}\n  ]', content, flags=re.DOTALL)
        
        self.session_state.write_text(content, encoding='utf-8')
    
    def add_done(self, item: str):
        """添加已完成事项"""
        content = self.session_state.read_text(encoding='utf-8')
        
        # 移动"刚刚完成"到历史,新事项放到顶部
        lines = content.split('\n')
        done_section = []
        in_done = False
        new_lines = []
        
        for line in lines:
            if '## 刚刚完成' in line:
                in_done = True
                new_lines.append(line)
                continue
            if in_done:
                if line.startswith('## '):
                    in_done = False
                    # 添加新事项
                    new_lines.append(f'- {item}')
                    new_lines.append('')
                elif line.strip():
                    done_section.append(line)
                else:
                    done_section.append(line)
            else:
                new_lines.append(line)
        
        self.session_state.write_text('\n'.join(new_lines), encoding='utf-8')
    
    def add_heard(self, item: str):
        """添加刚听到的信息"""
        content = self.session_state.read_text(encoding='utf-8')
        lines = content.split('\n')
        
        in_heard = False
        new_lines = []
        
        for line in lines:
            if '## 刚刚听到' in line:
                in_heard = True
                new_lines.append(line)
                continue
            if in_heard:
                if line.startswith('## '):
                    in_heard = False
                    new_lines.append(f'- {item}')
                    new_lines.append('')
            new_lines.append(line)
        
        self.session_state.write_text('\n'.join(new_lines), encoding='utf-8')
    
    def get_context(self) -> Dict:
        """获取当前上下文"""
        content = self.session_state.read_text(encoding='utf-8')
        
        context = {
            'task': '',
            'progress': '',
            'todos': [],
            'user_name': '',
            'user_goal': '',
            'recent_done': [],
            'recent_heard': []
        }
        
        # 简单解析
        for line in content.split('\n'):
            if '- 任务:' in line:
                context['task'] = line.split(':', 1)[1].strip()
            elif '- 进度:' in line:
                context['progress'] = line.split(':', 1)[1].strip()
            elif '- 名字:' in line:
                context['user_name'] = line.split(':', 1)[1].strip()
            elif '- 目标:' in line:
                context['user_goal'] = line.split(':', 1)[1].strip()
            elif '- ' in line and '[ ]' in line:
                context['todos'].append(line.split('[ ]', 1)[1].strip())
        
        return context
    
    # ===== 存储层操作 =====
    
    def add_daily_log(self, log: str):
        """添加每日日志"""
        today = datetime.now().strftime('%Y-%m-%d')
        log_file = self.memory_dir / f'{today}.md'
        
        if log_file.exists():
            existing = log_file.read_text(encoding='utf-8')
            log_file.write_text(existing + '\n\n' + log, encoding='utf-8')
        else:
            log_file.write_text(f"""# {today} 工作记录

## 对话记录

{log}

---

*记录时间:{datetime.now().strftime('%H:%M')}*
""", encoding='utf-8')
    
    def get_today_logs(self) -> str:
        """获取今日日志"""
        today = datetime.now().strftime('%Y-%m-%d')
        log_file = self.memory_dir / f'{today}.md'
        
        if log_file.exists():
            return log_file.read_text(encoding='utf-8')
        return ""
    
    def search_logs(self, keyword: str, days: int = 7) -> List[Dict]:
        """搜索历史日志"""
        results = []
        cutoff = datetime.now().timestamp() - (days * 86400)
        
        for log_file in self.memory_dir.glob('*.md'):
            if log_file.stat().st_mtime < cutoff:
                continue
            
            content = log_file.read_text(encoding='utf-8')
            if keyword.lower() in content.lower():
                results.append({
                    'date': log_file.stem,
                    'content': content[:500]  # 截取前500字符
                })
        
        return results
    
    # ===== 认知层操作 =====
    
    def update_memory(self, key: str, value: str):
        """更新长期记忆"""
        content = self.memory.read_text(encoding='utf-8')
        
        # 简单替换
        pattern = f'({key}:).*'
        if re.search(pattern, content):
            content = re.sub(pattern, f'\\1{value}', content)
        else:
            # 添加新项
            content = content.replace('[待补充]', f'{key}{value}\n[待补充]')
        
        # 更新日期
        content = content.replace(
            '*最后更新:*',
            f'*最后更新:{datetime.now().strftime("%Y-%m-%d")}*'
        )
        
        self.memory.write_text(content, encoding='utf-8')
    
    def get_user_info(self) -> Dict:
        """获取用户信息"""
        content = self.memory.read_text(encoding='utf-8')
        
        info = {}
        for line in content.split('\n'):
            if '名字:' in line:
                info['name'] = line.split(':', 1)[1].strip()
            elif '角色:' in line:
                info['role'] = line.split(':', 1)[1].strip()
            elif '目标:' in line:
                info['goal'] = line.split(':', 1)[1].strip()
            elif '沟通风格:' in line:
                info['communication'] = line.split(':', 1)[1].strip()
        
        return info
    
    def search_memory(self, keyword: str) -> str:
        """搜索长期记忆"""
        content = self.memory.read_text(encoding='utf-8')
        
        if keyword.lower() in content.lower():
            # 找到相关内容,返回附近段落
            lines = content.split('\n')
            for i, line in enumerate(lines):
                if keyword.lower() in line.lower():
                    start = max(0, i - 3)
                    end = min(len(lines), i + 10)
                    return '\n'.join(lines[start:end])
        
        return "未找到相关内容"


# ===== 便捷函数 =====

def get_memory() -> MemoryManager:
    """获取记忆管理器实例"""
    return MemoryManager()

4.2 使用示例

from memory_manager import MemoryManager, get_memory

# 初始化
mm = get_memory()

# ===== 感知层:当前任务 =====

# 更新任务状态
mm.update_task(
    task="帮用户整理三层记忆文档",
    progress="70%",
    todos=["补充案例", "完善公众号版本"]
)

# 添加完成事项
mm.add_done("回答了关于飞书API的问题")

# 添加听到的信息
mm.add_heard("用户想建立AI记忆系统")

# 获取当前上下文
context = mm.get_context()
print(f"当前任务: {context['task']}")
print(f"用户: {context['user_name']}")

# ===== 存储层:每日日志 =====

# 添加日志
mm.add_daily_log("""### 上午
- 9:00 与用户讨论记忆系统设计
  - 确定三层架构
  - 分配具体任务""")

# 搜索历史
results = mm.search_logs("飞书", days=30)
for r in results:
    print(f"{r['date']}: {r['content'][:100]}")

# ===== 认知层:长期记忆 =====

# 更新用户信息
mm.update_memory('名字', '非空')
mm.update_memory('目标', '建立高效AI Agent系统')

# 获取用户信息
user = mm.get_user_info()
print(f"用户目标: {user.get('goal')}")

# 搜索记忆
result = mm.search_memory("沟通风格")
print(result)

5. 使用规范

5.1 会话开始

必须做的事情

  1. 读取当前上下文

    mm = get_memory()
    context = mm.get_context()
    
  2. 检查用户信息

    user = mm.get_user_info()
    if user.get('name'):
        print(f"你好,{user['name']}!")
    

5.2 会话进行中

每条消息后

  1. 更新SESSION-STATE.md

    • 如果任务有进展 → 更新进度
    • 如果听到重要信息 → 添加到"刚刚听到"
    • 如果完成工作 → 添加到"刚刚完成"
  2. 记录重要内容到每日日志

    • 重要决策
    • 任务完成情况
    • 学习到的知识

示例

# 用户提到一个重要概念
mm.add_heard("用户提到想要学习Python")

# 完成一个任务
mm.add_done("整理了三层记忆文档")
mm.update_task(progress="50%")

5.3 会话结束

可选做的事情

  1. 总结当日工作

    mm.add_daily_log("""### 总结
    - 完成了记忆系统设计
    - 整理了技术文档""")
    
  2. 更新长期记忆

    # 学到新经验
    mm.update_memory('飞书API限制', '表格需要分块写入')
    

5.4 定期维护

每周或重要里程碑

  1. 回顾MEMORY.md

    • 检查是否有过时信息
    • 添加新的经验总结
  2. 清理旧日志

    • 30天前的日志可以归档

6. 工作流程

6.1 完整工作流程图

用户发送消息
    │
    ▼
┌─────────────────┐
│  读取感知层     │  ← SESSION-STATE.md
│  获取上下文     │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  处理用户请求   │
│  完成任务      │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  更新感知层    │  → SESSION-STATE.md
│  - 任务进度    │
│  - 完成事项    │
└────────┬────────┘
         │
         ▼
         (会话结束或重要节点)
         │
         ▼
┌─────────────────┐
│  更新存储层     │  → memory/YYYY-MM-DD.md
│  - 记录日志    │
└────────┬────────┘
         │
         ▼
         (定期)
         │
         ▼
┌─────────────────┐
│  更新认知层     │  → MEMORY.md
│  - 提炼经验    │
│  - 更新用户    │
└─────────────────┘

6.2 代码集成

class AIAgent:
    def __init__(self):
        self.mm = get_memory()
    
    def on_message(self, user_message: str) -> str:
        # 1. 获取上下文
        context = self.mm.get_context()
        user_info = self.mm.get_user_info()
        
        # 2. 处理消息
        response = self.think(user_message, context, user_info)
        
        # 3. 更新感知层(如果有必要)
        if self.current_task:
            self.mm.update_task(
                task=self.current_task,
                progress=self.progress
            )
        
        # 4. 如果有重要更新,记录到日志
        if self.important_update:
            self.mm.add_daily_log(self.important_update)
        
        return response
    
    def on_session_end(self):
        """会话结束时的清理工作"""
        # 更新长期记忆
        if self.learned_something:
            self.mm.update_memory('新经验', self.learned_something)

7. 实际案例

案例一:连续任务

场景:用户让AI帮忙写文章,分多次对话完成

第一次对话

用户:帮我写一篇关于AI记忆系统的文章
AI:好的,我来帮你规划...

AI的操作

mm.update_task(
    task="撰写AI记忆系统公众号文章",
    progress="10%",
    todos=["收集素材", "整理框架", "撰写初稿", "优化发布"]
)
mm.add_heard("用户想要一篇关于AI记忆系统的公众号文章")

第二次对话

用户:我再给你补充一些素材...

AI的操作

context = mm.get_context()
# 自动知道当前任务是什么
print(f"好的,我会把这些素材加入到《{context['task']}》中")

mm.add_daily_log("用户补充了关于三层架构的素材")

结果

  • 不需要用户重复解释任务背景
  • AI记得任务进度和待办
  • 可以连续工作

案例二:用户偏好学习

场景:用户第一次使用,需要记住偏好

对话

用户:我喜欢简洁的风格,不要太多废话
AI:明白了,你偏好简洁风格...

AI的操作

# 记住用户偏好
mm.update_memory('沟通风格', '简洁,直接,不说废话')
mm.add_daily_log("用户偏好:简洁风格")

后续

# 下次对话时
user_info = mm.get_user_info()
# 自动使用用户偏好的风格回复

案例三:问题追溯

场景:用户问"之前那个脚本报错的问题解决了吗"

AI的操作

# 搜索历史日志
results = mm.search_logs("脚本报错", days=30)

if results:
    # 找到之前的记录
    old_issue = results[0]['content']
    print(f"找到了之前的记录:{old_issue}")
    # 结合解决方案给出回答
else:
    print("我没有找到相关记录")

8. 常见问题

Q1: SESSION-STATE.md 会不会越来越大?

:会,但这是正常的。

  • "刚刚完成"和"刚刚听到"只保留最近3-5条
  • 旧内容会自动移到每日日志
  • 定期清理即可

Q2: 多个会话同时运行怎么办?

:每个会话独立维护 SESSION-STATE.md

  • 可以用会话ID区分
  • 或者每个会话使用独立的workspace

Q3: 如何避免记忆冲突?

  • 感知层:每次写入前先读取
  • 存储层:使用日期作为文件名,不会冲突
  • 认知层:定期手动合并

Q4: 记忆系统需要多大存储空间?

:很小

  • 文本文件,压缩率很高
  • 每天几KB到几十KB
  • 一年大约几十MB

Q5: 可以用数据库代替文件吗?

:可以,但没必要

  • 文件系统足够简单可靠
  • 便于调试和查看
  • 不需要额外依赖

📎 附录

快速开始 Checklist

  • 创建 SESSION-STATE.md
  • 创建 MEMORY.md
  • 创建 memory/ 目录
  • 部署 MemoryManager 代码
  • 在Agent启动时加载记忆
  • 在每条消息后更新状态
  • 定期更新MEMORY.md

相关文件

文件路径用途
记忆管理器scripts/memory_manager.py核心代码
示例配置scripts/memory_example.py使用示例
测试脚本scripts/memory_test.py单元测试