TevinClaw
13 hours ago 0f9deaa16bfd125a55283b2750d1586606a01532
新增:memory-md-hot 热记忆管理技能
2 files added
528 ■■■■■ changed files
workspace/skills/memory-md-hot/SKILL.md 191 ●●●●● patch | view | raw | blame | history
workspace/skills/memory-md-hot/scripts/daily_maintenance.py 337 ●●●●● patch | view | raw | blame | history
workspace/skills/memory-md-hot/SKILL.md
New file
@@ -0,0 +1,191 @@
---
name: memory-md-hot
description: 管理 MEMORY.md 热记忆文件,维护事件流水和重要事件记录。当需要更新 memory.md、添加日常事件或重要事件时使用。支持每日自动更新,保留所有历史记录,推荐配合 memory-md-archive 技能进行归档瘦身。
---
# memory-md-hot 技能
管理 `MEMORY.md` 热记忆文件,让 agent 每次启动时被动了解最近发生的事情。
## 文件定位
- **目标文件**: `~/.openclaw/workspace/MEMORY.md`
- **维护脚本**: `scripts/daily_maintenance.py`
## 文件结构
`MEMORY.md` 包含三个部分:
1. **文件说明** - 说明本文件记录已发生的事情,详细信息可通过记忆检索获取
2. **🔔 重要事件** - 全局长期性影响的重要决策和事件(默认空,记录时需告知用户)
3. **📅 事件流水** - 按天分组的每日主要事情概要
## 事件格式
所有事件遵循统一格式:
```
- YYYY-MM-DD HH:MM | 一句话概要 | 关键词1,关键词2
```
示例:
```
- 2026-03-16 10:30 | 创建memory-md-hot技能 | 技能,记忆系统
- 2026-03-16 14:00 | 配置LanceDB嵌入模型 | 配置,向量数据库
```
## 使用场景
### 场景1: 每日维护(自动)
每天执行一次,从记忆检索中获取当日事件,更新流水:
```bash
python3 ~/.openclaw/workspace/skills/memory-md-hot/scripts/daily_maintenance.py update
```
**功能**:
- 扫描当日记忆,提取重要事件
- 添加新的日常事件到对应日期分组
- 保留所有历史记录(不再自动移除旧记录)
- 更新文件统计信息
### 场景2: 添加日常事件
记录一般的日常活动:
```bash
python3 scripts/daily_maintenance.py add-daily 2026-03-16 "10:30" "测试脚本" "开发,测试"
```
或在 agent 会话中:
```python
from skills.memory_md_hot.scripts.daily_maintenance import update_memory_file
# 添加单个日常事件
event = ("2026-03-16", "10:30", "测试脚本", "开发,测试")
result = update_memory_file(new_daily_events=[event])
```
### 场景3: 添加重要事件
记录具有全局长期性影响的事件(**必须告知用户**):
```bash
python3 scripts/daily_maintenance.py add-important 2026-03-16 "14:00" "重构记忆系统" "架构,重要"
```
或在 agent 会话中:
```python
event = ("2026-03-16", "14:00", "重构记忆系统", "架构,重要")
result = update_memory_file(important_event=event)
if result['added_important']:
    print("已记录重要事件,请告知用户")
```
### 场景4: 检查文件统计
```bash
python3 scripts/daily_maintenance.py stats
```
或在 agent 会话中:
```python
from skills.memory_md_hot.scripts.daily_maintenance import get_stats
stats = get_stats()
print(f"当前文件: {stats['size_kb']}KB, {stats['total_events']} 条事件")
if stats['size_kb'] > 50:
    print("建议:文件较大,可考虑使用 memory-md-archive 技能归档")
```
## 重要事件判断标准
什么应该记录为重要事件:
| 类型 | 示例 |
|------|------|
| 架构变更 | 记忆系统重构、技能体系升级 |
| 配置变更 | API Key 更换、模型切换 |
| 重要决策 | 采用新工作流、确立规范 |
| 关键里程碑 | 项目完成、重要功能上线 |
什么只记录为日常事件:
| 类型 | 示例 |
|------|------|
| 常规查询 | 天气查询、网页搜索 |
| 临时任务 | 单次文件处理、数据分析 |
| 日常对话 | 问答、简单讨论 |
## 文件归档管理
本技能**保留所有历史记录**,不再自动移除旧事件。
当文件增长到一定大小时,建议配合 `memory-md-archive` 技能进行归档:
```bash
# 查看文件统计
python3 scripts/daily_maintenance.py stats
# 当文件较大时,使用归档技能
# (需先安装 memory-md-archive 技能)
python3 ~/.openclaw/workspace/skills/memory-md-archive/scripts/archive.py
```
**归档建议**:
- 文件超过 50KB 时建议归档
- 可将较早的重要事件移动到归档文件
- 日常事件可选择性归档或保留
## 与其他组件的关系
```
┌─────────────────────────────────────────────────────────┐
│  LanceDB-Pro 向量记忆                                     │
│  - 存储所有详细记忆                                        │
│  - 支持语义检索                                           │
└────────────────────┬────────────────────────────────────┘
                     │ 检索
                     ▼
┌─────────────────────────────────────────────────────────┐
│  MEMORY.md 热记忆 (本技能管理)                            │
│  - 事件流水(摘要)                                       │
│  - 重要事件(全局影响)                                    │
│  - 所有历史记录(需配合 archive 技能归档)                  │
└────────────────────┬────────────────────────────────────┘
                     │ 启动注入
                     ▼
┌─────────────────────────────────────────────────────────┐
│  Agent 启动上下文                                         │
│  - 快速了解最近发生了什么                                  │
│  - 无需查询即可感知活跃记忆                                │
└─────────────────────────────────────────────────────────┘
```
## 最佳实践
1. **每日更新**: 建议设置定时任务每天执行 `update` 命令
2. **即时记录**: 重要事件发生后立即记录,不要累积
3. **简洁描述**: 一句话概要,关键词用逗号分隔
4. **主动告知**: 添加重要事件时必须告知用户
5. **定期归档**: 文件较大时使用 memory-md-archive 技能归档
## 故障排查
### 文件未更新
- 检查脚本路径是否正确
- 确认 `MEMORY.md` 存在且可写
### 文件过大
- 执行 `stats` 查看当前大小和事件数量
- 安装并使用 `memory-md-archive` 技能进行归档
- 考虑清理不再重要的日常事件
### 日期解析错误
- 确保日期格式为 `YYYY-MM-DD`
- 时间格式建议为 `HH:MM` 或 `--:--`
workspace/skills/memory-md-hot/scripts/daily_maintenance.py
New file
@@ -0,0 +1,337 @@
#!/usr/bin/env python3
"""
memory-md-hot 每日维护脚本
维护 memory.md 文件的事件流水和重要事件
保留所有历史记录,需配合 memory-md-archive 技能归档
"""
import os
import re
import sys
from datetime import datetime
from pathlib import Path
# 配置
MEMORY_FILE = Path.home() / ".openclaw" / "workspace" / "MEMORY.md"
ARCHIVE_THRESHOLD_KB = 50  # 建议归档的阈值(仅提示,不强制)
def read_memory_file():
    """读取 memory.md 文件内容"""
    if not MEMORY_FILE.exists():
        return ""
    return MEMORY_FILE.read_text(encoding='utf-8')
def write_memory_file(content):
    """写入 memory.md 文件"""
    MEMORY_FILE.parent.mkdir(parents=True, exist_ok=True)
    MEMORY_FILE.write_text(content, encoding='utf-8')
def get_file_size():
    """获取文件大小(字节)"""
    if not MEMORY_FILE.exists():
        return 0
    return MEMORY_FILE.stat().st_size
def parse_date_from_line(line):
    """从行中提取日期(YYYY-MM-DD 格式)"""
    match = re.search(r'(\d{4}-\d{2}-\d{2})', line)
    if match:
        try:
            return datetime.strptime(match.group(1), '%Y-%m-%d').date()
        except ValueError:
            return None
    return None
def extract_event_entries(content):
    """
    从内容中提取事件条目
    返回: (important_events, daily_events) 元组
    """
    important_events = []
    daily_events = []
    lines = content.split('\n')
    in_important = False
    in_daily = False
    for line in lines:
        stripped = line.strip()
        # 检测区块
        if '重要事件' in stripped and stripped.startswith('#'):
            in_important = True
            in_daily = False
            continue
        elif ('事件流水' in stripped) and stripped.startswith('#'):
            in_important = False
            in_daily = True
            continue
        elif stripped.startswith('#') and in_important:
            in_important = False
        elif stripped.startswith('#') and in_daily:
            in_daily = False
        # 收集事件
        if in_important and stripped.startswith('-'):
            if len(stripped) > 10:  # 过滤空行和短行
                important_events.append(line)
        elif in_daily and (stripped.startswith('-') or stripped.startswith('*')):
            daily_events.append(line)
    return important_events, daily_events
def generate_default_content():
    """生成默认的 memory.md 内容"""
    today = datetime.now().strftime('%Y-%m-%d')
    return f"""# MEMORY.md - 热记忆 / 活跃记忆
> 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。
---
## 🔔 重要事件
> 记录具有全局长期性影响的重要决策和事件。
> 添加重要事件时会告知用户。
<!-- 重要事件在此添加 -->
---
## 📅 事件流水
> 按天分组,每天主要事情的概要。
> 所有记录永久保留,可使用 memory-md-archive 技能归档瘦身。
### {{today}}
- {today} 10:00 | memory.md 初始化 | 热记忆系统
---
*文件大小: ~0.5KB | 事件数: 1*
*维护脚本: `memory-md-hot/scripts/daily_maintenance.py`*
*归档提示: 文件较大时请使用 memory-md-archive 技能归档*
""".format(today=today)
def update_memory_file(new_daily_events=None, important_event=None):
    """
    更新 memory.md 文件
    Args:
        new_daily_events: 新的每日事件列表 [(date, time, summary, keywords), ...]
        important_event: 重要事件元组 (date, time, summary, keywords) 或 None
    Returns:
        dict: 操作结果
    """
    result = {
        'success': True,
        'added_daily': 0,
        'added_important': False,
        'current_size_kb': 0,
        'total_events': 0,
        'archive_suggested': False,
        'messages': []
    }
    # 读取现有内容
    content = read_memory_file()
    if not content:
        content = generate_default_content()
    # 提取现有事件
    existing_important, existing_daily = extract_event_entries(content)
    # 保留所有现有日常事件(不再移除旧记录)
    all_daily = list(existing_daily)
    # 添加新的日常事件
    if new_daily_events:
        for event in new_daily_events:
            date, time, summary, keywords = event
            entry = f"- {date} {time} | {summary} | {keywords}"
            # 检查是否已存在
            if not any(entry.strip() in existing.strip() for existing in all_daily):
                all_daily.append(entry)
                result['added_daily'] += 1
    # 添加重要事件
    new_important = list(existing_important)
    if important_event:
        date, time, summary, keywords = important_event
        entry = f"- {date} {time} | {summary} | {keywords}"
        new_important.append(entry)
        result['added_important'] = True
        result['messages'].append(f"重要事件已记录: {summary}")
    # 重新构建文件内容
    today = datetime.now().strftime('%Y-%m-%d')
    # 按日期分组日常事件
    daily_by_date = {}
    for line in all_daily:
        date = parse_date_from_line(line)
        if date:
            date_str = date.strftime('%Y-%m-%d')
            if date_str not in daily_by_date:
                daily_by_date[date_str] = []
            daily_by_date[date_str].append(line)
    # 构建日常事件区块
    daily_sections = []
    for date_str in sorted(daily_by_date.keys(), reverse=True):
        daily_sections.append(f"\n### {date_str}\n")
        daily_sections.extend([f"{line}\n" for line in daily_by_date[date_str]])
    daily_content = ''.join(daily_sections) if daily_sections else f"\n### {today}\n\n- {today} --:-- | 暂无记录 | --\n"
    # 构建重要事件区块
    important_content = '\n'.join(new_important) if new_important else "<!-- 重要事件在此添加 -->"
    # 计算统计
    total_events = len(all_daily) + len(new_important)
    result['total_events'] = total_events
    # 组装最终内容
    current_size = get_file_size()
    result['current_size_kb'] = round(current_size / 1024, 2)
    new_content = f"""# MEMORY.md - 热记忆 / 活跃记忆
> 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。
---
## 🔔 重要事件
> 记录具有全局长期性影响的重要决策和事件。
> 添加重要事件时会告知用户。
{important_content}
---
## 📅 事件流水
> 按天分组,每天主要事情的概要。
> 所有记录永久保留,可使用 memory-md-archive 技能归档瘦身。
{daily_content}
---
*文件大小: ~{result['current_size_kb']:.1f}KB | 事件数: {total_events}*
*维护脚本: `memory-md-hot/scripts/daily_maintenance.py`*
*归档提示: 文件较大时请使用 memory-md-archive 技能归档*
"""
    # 写入文件
    write_memory_file(new_content)
    # 检查是否需要建议归档
    new_size = get_file_size()
    result['current_size_kb'] = round(new_size / 1024, 2)
    if result['current_size_kb'] > ARCHIVE_THRESHOLD_KB:
        result['archive_suggested'] = True
        result['messages'].append(f"提示: 文件大小 ({result['current_size_kb']}KB) 超过 {ARCHIVE_THRESHOLD_KB}KB,建议使用 memory-md-archive 技能归档")
    return result
def get_stats():
    """获取文件统计信息"""
    content = read_memory_file()
    if not content:
        return {
            'size_bytes': 0,
            'size_kb': 0,
            'total_events': 0,
            'important_events': 0,
            'daily_events': 0,
            'archive_suggested': False
        }
    important, daily = extract_event_entries(content)
    size = get_file_size()
    size_kb = round(size / 1024, 2)
    return {
        'size_bytes': size,
        'size_kb': size_kb,
        'total_events': len(important) + len(daily),
        'important_events': len(important),
        'daily_events': len(daily),
        'archive_suggested': size_kb > ARCHIVE_THRESHOLD_KB
    }
def main():
    """主函数 - 供命令行调用"""
    if len(sys.argv) < 2:
        print("用法: python daily_maintenance.py <command> [args]")
        print("")
        print("命令:")
        print("  update                     - 执行每日更新")
        print("  stats                      - 查看文件统计")
        print("  add-daily <date> <time> <summary> <keywords>")
        print("                             - 添加日常事件")
        print("  add-important <date> <time> <summary> <keywords>")
        print("                             - 添加重要事件")
        print("")
        print("示例:")
        print('  python daily_maintenance.py add-daily 2026-03-16 "10:30" "测试脚本" "开发,测试"')
        sys.exit(1)
    command = sys.argv[1]
    if command == "update":
        result = update_memory_file()
        print(f"更新完成:")
        print(f"  - 添加日常事件: {result['added_daily']}")
        print(f"  - 添加重要事件: {'是' if result['added_important'] else '否'}")
        print(f"  - 当前大小: {result['current_size_kb']}KB")
        print(f"  - 总事件数: {result['total_events']}")
        for msg in result['messages']:
            print(f"  - {msg}")
    elif command == "stats":
        stats = get_stats()
        print(f"文件统计:")
        print(f"  - 文件大小: {stats['size_kb']}KB ({stats['size_bytes']} 字节)")
        print(f"  - 总事件数: {stats['total_events']}")
        print(f"  - 重要事件: {stats['important_events']}")
        print(f"  - 日常事件: {stats['daily_events']}")
        if stats['archive_suggested']:
            print(f"  - 归档建议: 文件较大,建议使用 memory-md-archive 技能归档")
        else:
            print(f"  - 归档建议: 暂无需要")
    elif command == "add-daily" and len(sys.argv) >= 6:
        event = (sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
        result = update_memory_file(new_daily_events=[event])
        print(f"已添加日常事件: {event}")
        if result['archive_suggested']:
            print(f"提示: 文件大小 {result['current_size_kb']}KB,建议归档")
    elif command == "add-important" and len(sys.argv) >= 6:
        event = (sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
        result = update_memory_file(important_event=event)
        print(f"已添加重要事件: {event}")
        print(f"ℹ️ 请知悉用户: 已记录重要事件 '{sys.argv[4]}'")
        if result['archive_suggested']:
            print(f"提示: 文件大小 {result['current_size_kb']}KB,建议归档")
    else:
        print(f"未知命令或参数不足: {command}")
        sys.exit(1)
if __name__ == "__main__":
    main()