Smart Memory
Enhanced memory management for OpenClaw. Zero external dependencies. Inspired by Claude Code's memdir architecture.
Requirements
- - Runtime: Python 3.10+ (standard library only), Bash 4.0+ (health/extract scripts only)
- OS: Linux, macOS
- Environment variables (all optional, with defaults):
-
OPENCLAW_WORKSPACE — Workspace root (default:
~/.openclaw/workspace)
-
OPENCLAW_SESSION_ID — Session identifier for temp cache (default:
default)
Security
Sensitive Data Protection
All write commands (
session_state.py,
session_cache.py) automatically reject inputs matching:
- - API keys/tokens (OpenAI
sk-*, GitHub ghp_*, ClawHub clh_*) - Passwords (
password=, passwd:, etc.) - Private keys (
-----BEGIN PRIVATE KEY-----)
This is a hard block at the script level — the agent cannot bypass it. The regex patterns are conservative (high precision, may miss exotic formats); the agent should additionally avoid extracting any credential-like text even if not matched.
Input Sanitization
- - Control characters stripped from all inputs
- Session ID sanitized to alphanumeric/hyphen/underscore only (prevents path traversal)
- Python-based scripts eliminate shell injection risks
Data Isolation
- - All data stays local — no network calls, no cloud uploads
- Session cache uses
/tmp/ with sanitized session ID filenames - No external dependencies or third-party packages
Memory Layers
| Layer | File | Purpose | Lifetime |
|---|
| HOT RAM | INLINECODE13 | Current task, context, decisions | Session (survives compaction) |
| DAILY |
memory/YYYY-MM-DD.md | Raw daily notes with type tags | 90 days → archive |
|
CURATED |
MEMORY.md | Promoted long-term facts | Permanent |
|
ARCHIVE |
memory/archive/YYYY-MM/ | Stale daily files | Forever (compressed) |
|
CACHE |
/tmp/openclaw-session-*.json | Session temp data | Session end / reboot |
Quick Reference
| Action | Script |
|---|
| WAL shortcut (any command) | INLINECODE18 |
| Set current task |
scripts/wal task "description" |
| Log a decision |
scripts/wal decide "chose X over Y" |
| Add context |
scripts/wal context key value |
| Snapshot & restore |
scripts/wal snapshot /
scripts/wal restore |
| Session cache |
python3 scripts/session_cache.py set/get/list/clear |
| Classify (summary) |
python3 scripts/classify_memory.py --summary |
| Decay (promote only) |
python3 scripts/memory_decay.py --promote-only |
| Health report |
bash scripts/memory_health.sh |
WAL Protocol (Write-Ahead Log)
Critical rule: Write BEFORE responding.
When the user provides information that should be remembered:
- 1. Write to SESSION-STATE.md (via
session_state.py) - Then respond to the user
This prevents context loss if compaction, crash, or restart happens between response and write.
| User Action | WAL Write |
|---|
| States a preference | INLINECODE29 |
| Makes a decision |
session_state.py decide "chose X" |
| Gives a deadline |
session_state.py context "deadline" "date" |
| Corrects agent |
session_state.py decide "correction: X not Y" |
| Assigns task |
session_state.py task "description" |
| Mentions blocker |
session_state.py blocker "description" |
Memory Types
All entries tagged with a type prefix:
- -
[PREF] — User preferences, habits, style - INLINECODE36 — Project context, active work, goals
- INLINECODE37 — Technical details, configs, system knowledge
- INLINECODE38 — Lessons learned, errors, corrections
- INLINECODE39 — People, relationships, social context
- INLINECODE40 — Session-scoped, auto-expires
Core Workflows
Session Start
- 1. Read
SESSION-STATE.md for current task/context - Run
memory_search for relevant prior context - Check
memory/YYYY-MM-DD.md for today's activity
During Conversation (WAL)
- 1. User provides actionable info → write to SESSION-STATE.md FIRST
- Important facts → append to
memory/YYYY-MM-DD.md with type tag - Use
session_cache.py for transient session data
Session End
- 1. Update
SESSION-STATE.md with final state - Promote durable items from daily notes to INLINECODE47
- Run
memory_health.sh periodically to check hygiene
Periodic Maintenance
- - Run
memory_decay.py when MEMORY.md > 200 lines or 50+ daily files - Run
classify_memory.py to tag orphaned entries - Archive daily files older than 90 days
Agent Behavior
Auto-Extract When
- - User shares preference, opinion, or personal fact
- Project decision is made or changed
- Error encountered and resolved (→ LESSON)
- New people, tools, or workflows mentioned
Extraction Modes
- - Keyword mode (default):
extract_memories.sh --auto "text" — zero token cost, pure Python - LLM mode (opt-in): Use
references/extraction_prompt.md template — costs tokens, better quality - Use keyword mode for most conversations; LLM mode only for long/complex sessions (20+ turns)
Do NOT Extract
- - Passwords, tokens, API keys, credentials (scripts hard-block these)
- Private conversations about third parties not relevant to work
- Speculation or uncertain information ("user might prefer X")
- Transient state ("user is currently looking at page X")
- Information the user explicitly said not to remember
Auto-Decay When
- - MEMORY.md exceeds 200 lines
- memory/*.md totals > 50 files
- On heartbeat if configured
File Format
MEMORY.md
CODEBLOCK0
Daily Notes
CODEBLOCK1
SESSION-STATE.md
CODEBLOCK2
Scripts
| Script | Language | Purpose | Security |
|---|
| INLINECODE53 | Python | HOT RAM working memory (WAL protocol) | Sensitive data filter + sanitization |
| INLINECODE54 |
Python | Session-scoped temp key-value cache | Sensitive data filter + path-safe IDs |
|
extract_memories.sh | Bash | Memory extraction guide and daily file init | Read-only output |
|
memory_health.sh | Bash | Health report (stats, orphans, token estimate) | Read-only |
|
memory_decay.py | Python | Temporal decay and archival of stale files | Dry-run mode available |
|
classify_memory.py | Python | Keyword-based type classification | Dry-run mode available |
References
- -
references/extraction_prompt.md — LLM prompt for auto-extraction - INLINECODE60 — Full schema and format spec
- INLINECODE61 — Decay/archival rule set
技能名称: smart-memory
智能内存
为OpenClaw增强的内存管理。零外部依赖。灵感来源于Claude Code的memdir架构。
要求
- - 运行时: Python 3.10+(仅标准库),Bash 4.0+(仅健康/提取脚本)
- 操作系统: Linux, macOS
- 环境变量(均为可选,有默认值):
- OPENCLAW_WORKSPACE — 工作区根目录(默认: ~/.openclaw/workspace)
- OPENCLAW
SESSIONID — 临时缓存的会话标识符(默认: default)
安全性
敏感数据保护
所有写入命令(session
state.py, sessioncache.py)会自动拒绝匹配以下模式的输入:
- - API密钥/令牌(OpenAI sk-, GitHub ghp, ClawHub clh*)
- 密码(password=, passwd: 等)
- 私钥(-----BEGIN PRIVATE KEY-----)
这是脚本级别的硬阻断——代理无法绕过。正则表达式模式较为保守(高精度,可能遗漏特殊格式);即使未匹配,代理也应额外避免提取任何类似凭证的文本。
输入净化
- - 从所有输入中剥离控制字符
- 会话ID仅允许字母数字/连字符/下划线(防止路径遍历)
- 基于Python的脚本消除shell注入风险
数据隔离
- - 所有数据保留在本地——无网络调用,无云上传
- 会话缓存使用带有净化会话ID文件名的 /tmp/
- 无外部依赖或第三方包
内存层级
| 层级 | 文件 | 用途 | 生命周期 |
|---|
| 热内存 | SESSION-STATE.md | 当前任务、上下文、决策 | 会话(在压缩后保留) |
| 每日 |
memory/YYYY-MM-DD.md | 带类型标签的原始每日笔记 | 90天 → 归档 |
|
精选 | MEMORY.md | 提升的长期事实 | 永久 |
|
归档 | memory/archive/YYYY-MM/ | 过期的每日文件 | 永久(压缩) |
|
缓存 | /tmp/openclaw-session-*.json | 会话临时数据 | 会话结束/重启 |
快速参考
| 操作 | 脚本 |
|---|
| WAL快捷方式(任意命令) | scripts/wal task/decide/context/pending/done/blocker/get/snapshot/restore |
| 设置当前任务 |
scripts/wal task 描述 |
| 记录决策 | scripts/wal decide 选择了X而非Y |
| 添加上下文 | scripts/wal context 键 值 |
| 快照与恢复 | scripts/wal snapshot / scripts/wal restore |
| 会话缓存 | python3 scripts/session_cache.py set/get/list/clear |
| 分类(摘要) | python3 scripts/classify_memory.py --summary |
| 衰减(仅提升) | python3 scripts/memory_decay.py --promote-only |
| 健康报告 | bash scripts/memory_health.sh |
WAL协议(预写日志)
关键规则: 在响应前写入。
当用户提供应被记住的信息时:
- 1. 写入 SESSION-STATE.md(通过 session_state.py)
- 然后 回复用户
这可以防止在响应和写入之间发生压缩、崩溃或重启时丢失上下文。
| 用户操作 | WAL写入 |
|---|
| 陈述偏好 | sessionstate.py context pref 值 |
| 做出决策 |
sessionstate.py decide 选择了X |
| 给出截止日期 | session_state.py context deadline 日期 |
| 纠正代理 | session_state.py decide 纠正: X而非Y |
| 分配任务 | session_state.py task 描述 |
| 提到阻塞项 | session_state.py blocker 描述 |
内存类型
所有条目都带有类型前缀标签:
- - [PREF] — 用户偏好、习惯、风格
- [PROJ] — 项目上下文、活跃工作、目标
- [TECH] — 技术细节、配置、系统知识
- [LESSON] — 经验教训、错误、纠正
- [PEOPLE] — 人物、关系、社交上下文
- [TEMP] — 会话范围,自动过期
核心工作流
会话开始
- 1. 读取 SESSION-STATE.md 获取当前任务/上下文
- 运行 memory_search 获取相关先验上下文
- 检查 memory/YYYY-MM-DD.md 获取今日活动
对话期间(WAL)
- 1. 用户提供可操作信息 → 首先写入 SESSION-STATE.md
- 重要事实 → 带类型标签追加到 memory/YYYY-MM-DD.md
- 使用 session_cache.py 处理临时会话数据
会话结束
- 1. 用最终状态更新 SESSION-STATE.md
- 将持久性条目从每日笔记提升到 MEMORY.md
- 定期运行 memory_health.sh 检查卫生状况
定期维护
- - 当 MEMORY.md 超过200行或每日文件超过50个时运行 memorydecay.py
- 运行 classifymemory.py 为孤立条目打标签
- 归档超过90天的每日文件
代理行为
自动提取时机
- - 用户分享偏好、意见或个人事实
- 项目决策被做出或更改
- 遇到并解决错误(→ LESSON)
- 提到新人、工具或工作流
提取模式
- - 关键词模式(默认): extractmemories.sh --auto 文本 — 零令牌成本,纯Python
- LLM模式(可选): 使用 references/extractionprompt.md 模板 — 消耗令牌,质量更好
- 大多数对话使用关键词模式;仅长/复杂会话(20+轮次)使用LLM模式
不要提取
- - 密码、令牌、API密钥、凭证(脚本硬阻断这些)
- 与工作无关的第三方私人对话
- 推测或不确定的信息(用户可能偏好X)
- 临时状态(用户当前正在查看页面X)
- 用户明确表示不要记住的信息
自动衰减时机
- - MEMORY.md 超过200行
- memory/*.md 文件总数超过50个
- 配置了心跳时
文件格式
MEMORY.md
markdown
[PREF] 偏好
[PROJ] 活跃项目
- - 黄金三章: /root/黄金三章/, golden3.killclaw.xyz
[LESSON] 经验教训
每日笔记
markdown
2026-03-31
[PROJ] 黄金三章
SESSION-STATE.md
markdown
当前任务
构建智能内存技能
关键上下文
近期决策
待办事项
脚本
| 脚本 | 语言 | 用途 | 安全性 |
|---|
| sessionstate.py | Python | 热内存工作内存(WAL协议) | 敏感数据过滤 + 净化 |
| sessioncache.py |
Python | 会话范围的临时键值缓存 | 敏感数据过滤 + 路径安全ID |
| extract_memories.sh | Bash | 内存提取指南和每日文件初始化 | 只读输出 |
| memory_health.sh | Bash | 健康报告(统计、孤立项、令牌估算) | 只读 |
| memory_decay.py | Python | 过期文件的时间衰减和归档 | 提供试运行模式 |
| classify_memory.py | Python | 基于关键词的类型分类 | 提供试运行模式 |
参考
- - references/extractionprompt.md — 自动提取的LLM提示
- references/memoryschema.md — 完整模式和格式规范
- references/decay_rules.md — 衰减/归档规则集