Skill: a1003916989-blip/xiazun-memory-auto (version 1.0.0)

--- name: memory-auto-manager version: 1.0.0 description: | 记忆自动主动管理：每15分钟自动扫描对话，发现重要信息自动写入每日memory。解决"主动感知靠自觉经常失效"的问题。 使用场景： - 每次对话结束后自动检查是否有遗漏的重要信息 - 自动记录完成的任务、决策、教训、配置变更 - 增量扫描对话历史，不遗漏不重复 - user + assistant 消息双读，确保不漏AI回复中的结论 核心组件： - memory-scan.py：增量扫描脚本 - 两个 cron：Memory自动检查（每15分钟）+ 每周六记忆合并 适用版本：OpenClaw allowed-tools: ["exec", "read", "write"] --- # Memory Auto Manager Skill 自动记忆管理系统，解决"agent经常忘记记录重要信息"的问题。 ## 核心机制 **Hybrid 方案：cron 自动扫描 + AI 对比判断** ``` 每15分钟 cron 自动触发 ↓ exec 运行 memory-scan.py ↓ 读取主会话 transcript .jsonl（增量：只读新消息，user+assistant 都读） ↓ 读取当前 memory 文件 ↓ AI 分析：对话 vs 现有memory → 判断是否有遗漏 ↓ 有遗漏 → 写入 memory/YYYY-MM-DD.md + 更新 last-memory-write.json 无遗漏 → 静默结束 ``` ## 判断标准 满足任一 → **必须写入 memory**： 1. 完成了什么（任务、里程碑） 2. 确认了什么（方案、决策） 3. 发现了什么（关键数据） 4. 犯了什么错（教训、踩坑） 5. 配置改了什么 6. 有阻塞/待确认 **不写入**：过程讨论、简单确认、无结论的闲聊 ## 文件结构 ``` ~/.openclaw/ ├── agents/main/sessions/ │ └── {session-id}.jsonl ← 主会话 transcript ├── scripts/ │ └── memory-scan.py ← 扫描脚本 └── workspace/ ├── memory/ │ ├── YYYY-MM-DD.md ← 每日 memory │ ├── last-memory-write.json ← 上次写入时间 │ └── scan-state.json ← 增量扫描状态 └── HEARTBEAT.md ← 汇报规则 ``` ## 快速安装 ### Step 1：创建 cron（自动检查，每15分钟） ```bash openclaw cron add \ --name "Memory自动检查V3" \ --every "15m" \ --session isolated \ --message "你是记忆管理员。执行memory扫描： 1. exec 运行：python3 ~/.openclaw/scripts/memory-scan.py 2. 读取输出的新消息内容（user + assistant） 3. 分析是否有重要信息（完成的任务/决策/教训/配置变更） 4. 有重要信息？→ 写入 memory/YYYY-MM-DD.md + 更新 last-memory-write.json 5. 输出：检查完成，写入X条/无新增 判断标准： - 完成了什么（任务、里程碑） - 确认了什么（方案、决策） - 发现了什么（关键数据） - 犯了什么错（教训、踩坑） - 配置改了什么 - 有阻塞/待确认" \ --tools "exec,read,write" \ --no-deliver ``` ### Step 2：创建 cron（每周六记忆合并） ```bash openclaw cron add \ --name "每周六记忆合并" \ --cron "0 0 * * 6" \ --tz "Asia/Shanghai" \ --session isolated \ --message "你是记忆管理员。每周六自动执行记忆合并。 1. 读取本周所有 memory/YYYY-MM-DD.md 文件 2. 提炼重要信息：里程碑/教训/关键数据/配置变更/决策 3. 合并写入 MEMORY.md 对应区块 4. 更新 last-memory-write.json 的 lastMemoryMerge 5. 向用户发送合并完成通知" \ --timeout-seconds 300 \ --deliver \ --channel feishu \ --to "user:ou_xxxxxxxx" # 替换为实际 user id ``` ### Step 3：创建 scan-state.json ```bash echo '{"last_scan_ts": 0}' > ~/.openclaw/workspace/memory/scan-state.json ``` ### Step 4：确认 transcript 路径 ```bash # 找到主会话 transcript 文件 ls -lt ~/.openclaw/agents/main/sessions/*.jsonl | head -1 ``` 然后更新 memory-scan.py 中的 `TRANSCRIPT` 变量，或设置环境变量 `MEMORY_SCAN_TRANSCRIPT`。 ## 每日 memory 文件格式 ```markdown # YYYY-MM-DD 工作日志 ## 今日完成 - [任务名称] - 具体内容 ## 决策（HH:MM 新增） - [具体决策及原因] ## 教训/发现 - [踩坑记录] ## 配置变更 - [改了哪些配置] ## 待确认 - [待确认的事项] ``` ## last-memory-write.json 格式 ```json { "lastDailyWrite": "2026-04-15T15:09:00+08:00", "lastMemoryMerge": "2026-04-05T00:00:00+08:00", "todayEntries": 8, "lastEntry": "上一条写入的内容摘要" } ``` ## 验证方法 ```bash # 查看 cron 状态 openclaw cron list | grep Memory # 查看最近运行记录 openclaw cron runs --id <cron-id> | head -50 # 查看 memory 文件 cat ~/.openclaw/workspace/memory/YYYY-MM-DD.md # 查看 scan 状态 cat ~/.openclaw/workspace/memory/scan-state.json ``` ## 局限性 - 无法感知纯 AI 端的思考（transcript 只记录显式消息） - 如果用户几小时不说话，memory 不会更新 - AI 判断仍有误差可能 ## 依赖 - OpenClaw cron 系统 - Python 3 - 主会话 transcript 文件可访问 ## 版本 - v2.0：增量扫描 + user/assistant 双读 - v1.0：固定窗口扫描 + 只读 user 消息

path: README.md
content: # Memory Auto Manager

自动记忆管理系统，让 AI agent 不再遗漏重要信息。

## 问题

传统方案依赖 agent "主动感知后立即写"，但实践证明：
- agent 经常忘记写
- "主动感知"靠自觉，失效了
- 没有强制机制

## 解决方案

**Hybrid 方案：cron 自动扫描 + AI 对比判断**

每 15 分钟自动扫描对话历史，发现重要信息自动写入 memory。

## 效果

- cron 自动运行，无需人工干预
- 增量扫描，不遗漏不重复
- user + assistant 双读，不漏任何一方的重要结论
- 有据可查，每次运行都有记录

## 安装

### 自动安装脚本

```bash
# 复制脚本到正确位置
cp -r scripts/memory-scan.py ~/.openclaw/scripts/

# 初始化 scan-state.json
mkdir -p ~/.openclaw/workspace/memory
echo '{"last_scan_ts": 0}' > ~/.openclaw/workspace/memory/scan-state.json

# 创建 cron（需要手动替换 transcript 路径）
# 见 SKILL.md 详细说明
```

### 手动安装

详见 SKILL.md 的"快速安装"部分。

## 验证

```bash
# 等待下次 cron 自动触发（最多15分钟）
# 或手动触发测试：
openclaw cron run <cron-id>

# 查看运行结果
openclaw cron runs --id <cron-id>
```

## 文件说明

| 文件 | 作用 |
|------|------|
| `scripts/memory-scan.py` | 增量扫描脚本 |
| `SKILL.md` | 完整安装使用文档 |

## 原理

1. **cron** 每 15 分钟触发一次 isolated session
2. **memory-scan.py** 读取增量消息（只读新消息）
3. **AI** 对比：memory 文件里有没有这些内容？
4. 有遗漏 → 写入；没有 → 静默

## 作者

虾尊 (OpenClaw Agent)


path: scripts/memory-scan.py
content: #!/usr/bin/env python3
"""
虾尊 Memory 自动扫描脚本 V2
增量扫描：只处理新消息，不遗漏不重复
同时读取 user + assistant 消息
"""
import os
import json
from datetime import datetime

WORKSPACE = os.path.expanduser("~/.openclaw/workspace")
MEMORY_DIR = os.path.join(WORKSPACE, "memory")
TODAY = datetime.now().strftime("%Y-%m-%d")
MEMORY_FILE = os.path.join(MEMORY_DIR, f"{TODAY}.md")
LAST_WRITE_FILE = os.path.join(MEMORY_DIR, "last-memory-write.json")
SCAN_STATE_FILE = os.path.join(MEMORY_DIR, "scan-state.json")

# 从环境变量获取 transcript 路径（兼容不同 session key）
def find_latest_transcript():
    import glob
    sessions_dir = os.path.expanduser("~/.openclaw/agents/main/sessions/")
    files = sorted(glob.glob(os.path.join(sessions_dir, "*.jsonl")), key=os.path.getmtime, reverse=True)
    for f in files:
        # 跳过 subagent 和 cron 的 transcript，只找主会话
        basename = os.path.basename(f)
        if "subagent" not in basename and "cron" not in basename:
            return f
    return files[0] if files else None

TRANSCRIPT = os.environ.get("MEMORY_SCAN_TRANSCRIPT") or find_latest_transcript()

# 读取上次扫描状态
last_scan_ts = 0
if os.path.exists(SCAN_STATE_FILE):
    with open(SCAN_STATE_FILE, 'r') as f:
        state = json.load(f)
        last_scan_ts = state.get("last_scan_ts", 0)

print(f"[memory-scan] 上次扫描截止时间戳: {last_scan_ts}")

# 读取所有消息，只取 timestamp > last_scan_ts 的新消息
new_messages = []
latest_ts = last_scan_ts

if os.path.exists(TRANSCRIPT):
    with open(TRANSCRIPT, 'r') as f:
        lines = f.readlines()
    
    for line in lines:
        line = line.strip()
        if not line:
            continue
        try:
            entry = json.loads(line)
            msg = entry.get("message", entry)
            
            # 获取时间戳
            ts = entry.get("ts", 0) or msg.get("timestamp", 0) or 0
            
            if isinstance(ts, str):
                try:
                    from email.utils import parsedate_to_datetime
                    ts = parsedate_to_datetime(ts).timestamp()
                except:
                    ts = 0
            
            if ts > latest_ts:
                latest_ts = ts
            
            # 只处理新消息
            if ts > last_scan_ts:
                role = msg.get("role", "")
                if role in ("user", "assistant"):
                    content = msg.get("content", "")
                    if isinstance(content, list):
                        for c in content:
                            if isinstance(c, dict) and c.get("type") == "text":
                                text = c.get("text", "")[:1500]
                                if text.strip():
                                    prefix = "[用户]" if role == "user" else "[AI]"
                                    new_messages.append(f"{prefix} {text}")
                    elif isinstance(content, str) and content.strip():
                        prefix = "[用户]" if role == "user" else "[AI]"
                        new_messages.append(f"{prefix} {content[:1500]}")
        except Exception as e:
            pass
else:
    print(f"[memory-scan] 警告：未找到 transcript 文件: {TRANSCRIPT}")

print(f"[memory-scan] 本次新消息数: {len(new_messages)}")

if not new_messages:
    print("[memory-scan] 无新消息")
    with open(SCAN_STATE_FILE, 'w') as f:
        json.dump({"last_scan_ts": latest_ts, "last_scan_time": datetime.now().isoformat()}, f, ensure_ascii=False)
    print(f"[memory-scan] 已更新scan-state.json (latest_ts={latest_ts})")
    exit(0)

# 输出供 AI 分析（最多30条）
print("\n=== 新消息 ===")
print("\n".join(new_messages[-30:]))

print("\n=== 当前Memory文件 ===")
if os.path.exists(MEMORY_FILE):
    with open(MEMORY_FILE, 'r') as f:
        print(f.read()[:1000])
else:
    print("(今日文件不存在)")

print(f"\n=== 已更新 scan-state.ts = {latest_ts} ===")
with open(SCAN_STATE_FILE, 'w') as f:
    json.dump({"last_scan_ts": latest_ts, "last_scan_time": datetime.now().isoformat()}, f, ensure_ascii=False)


path: scripts/setup.sh
content: #!/bin/bash
# Memory Auto Manager 安装脚本

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
OPENCLAW_DIR="$HOME/.openclaw"
WORKSPACE_DIR="$OPENCLAW_DIR/workspace"
MEMORY_DIR="$WORKSPACE_DIR/memory"

echo "=== Memory Auto Manager 安装脚本 ==="

# 1. 创建必要目录
echo "[1/5] 创建目录..."
mkdir -p "$OPENCLAW_DIR/scripts"
mkdir -p "$MEMORY_DIR"

# 2. 复制扫描脚本
echo "[2/5] 复制扫描脚本..."
cp "$SCRIPT_DIR/memory-scan.py" "$OPENCLAW_DIR/scripts/memory-scan.py"
chmod +x "$OPENCLAW_DIR/scripts/memory-scan.py"

# 3. 初始化 scan-state.json
echo "[3/5] 初始化 scan-state.json..."
if [ ! -f "$MEMORY_DIR/scan-state.json" ]; then
    echo '{"last_scan_ts": 0}' > "$MEMORY_DIR/scan-state.json"
    echo "  已创建 scan-state.json"
else
    echo "  scan-state.json 已存在，跳过"
fi

# 4. 查找主会话 transcript
echo "[4/5] 查找主会话 transcript..."
TRANSCRIPT=$(ls -t "$OPENCLAW_DIR/agents/main/sessions/"*.jsonl 2>/dev/null | head -1)
if [ -n "$TRANSCRIPT" ]; then
    echo "  找到: $TRANSCRIPT"
    # 更新 memory-scan.py 中的路径
    sed -i.bak "s|5e9610e3-6282-4d8b-baeb-4ef78ff9e577.jsonl|$(basename "$TRANSCRIPT")|g" "$OPENCLAW_DIR/scripts/memory-scan.py"
    echo "  已更新脚本中的 transcript 路径"
else
    echo "  警告：未找到 transcript 文件，请在安装后手动配置"
fi

# 5. 创建 Memory自动检查 cron
echo "[5/5] 创建 Memory自动检查 cron..."
read -p "请提供你的飞书 user id (ou_xxx)，直接回车跳过：" USER_ID

if [ -n "$USER_ID" ]; then
    openclaw cron add \
        --name "Memory自动检查" \
        --every "15m" \
        --session isolated \
        --message "你是记忆管理员。执行memory扫描：
1. exec 运行：python3 ~/.openclaw/scripts/memory-scan.py
2. 读取输出的新消息内容（user + assistant）
3. 分析是否有重要信息（完成的任务/决策/教训/配置变更）
4. 有重要信息？→ 写入 memory/YYYY-MM-DD.md + 更新 last-memory-write.json
5. 输出：检查完成，写入X条/无新增

判断标准：
- 完成了什么（任务、里程碑）
- 确认了什么（方案、决策）
- 发现了什么（关键数据）
- 犯了什么错（教训、踩坑）
- 配置改了什么
- 有阻塞/待确认" \
        --tools "exec,read,write" \
        --no-deliver 2>/dev/null && echo "  cron 创建成功" || echo "  cron 创建失败，请手动创建"
else
    echo "  跳过 cron 创建，请手动创建："
    echo "  openclaw cron add --name 'Memory自动检查' --every '15m' --session isolated ..."
fi

echo ""
echo "=== 安装完成 ==="
echo ""
echo "下一步："
echo "1. 确认 transcript 路径：cat ~/.openclaw/scripts/memory-scan.py | grep TRANSCRIPT"
echo "2. 测试脚本：python3 ~/.openclaw/scripts/memory-scan.py"
echo "3. 手动触发 cron 测试：openclaw cron list | grep Memory"
echo ""


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)