Skip to content

OpenClaw Memory

OpenClaw 的记忆就是 workspace(默认 ~/.openclaw/workspace)里的一堆纯 Markdown 文件,没有隐藏状态:模型记住的东西 = 磁盘上写下来的东西。可以(也建议)把整个 workspace 做成一个私有 git 仓库来备份。

两层记忆

文件何时进入上下文定位
长期(精炼)MEMORY.md每次会话启动时整份注入 prompt(超限会截断)持久事实、偏好、长期决策;紧凑、可维护
短期(工作)memory/YYYY-MM-DD.md/new/reset 时自动带上今天 + 昨天;其余靠 memory_search 检索每日流水、观察、会话小结、暂时还有用的原始上下文

补充:DREAMS.md(可选)是 dreaming 扫描的人类可读产出,memory/.dreams/ 是它的机器状态。

两层的流向是短期 → 长期:日志先落在 memory/,随后由 agent(或 dreaming)蒸馏出耐用的结论追加进 MEMORY.md,同时删掉 MEMORY.md 里过期的条目。

判断放哪一层的一句话标准:下次开新会话,不看它就会答错的,放 MEMORY.md;只是"以后可能查得到就行"的,放 memory/

MEMORY.md vs memory/*.md vs memory/YYYY-MM-DD.md

  • MEMORY.md(根目录,大写)— 唯一的长期记忆文件,只有它会被完整注入 bootstrap 上下文。小写 memory.md 是历史遗留,只作为 openclaw doctor --fix 的迁移输入,不要故意同时保留两个根文件。
  • memory/YYYY-MM-DD.md带日期的每日笔记,是"短期层"的正规形态。memory/YYYY-MM-DD-<slug>.md 是同一天的分片(如 bundled session-memory hook 写的),会和纯日期文件一起被加载。带日期的文件会受 temporal decay(若开启)影响,越旧排序权重越低。
  • memory/不带日期的文件(如 memory/entehub-profile.md)— 属于 evergreen 常青档案:同样被索引、可被 memory_search 检索,但永不衰减,也不会自动进入 bootstrap。适合放"篇幅太大不配进 MEMORY.md、但需要长期准确"的资料(项目档案、客户画像、规范细节)。

一个实用组合:MEMORY.md 里给每个项目写 3~5 行摘要,然后 - **Details**: 详见 [memory/xxx-profile.md](memory/xxx-profile.md) 指向常青档案 —— bootstrap 只花几百 token,需要细节时 agent 自己去 memory_get

索引范围:MEMORY.md + memory/**/*.md 默认全部索引(includeDefaultMemory: true,递归子目录),存进 per-agent SQLite(~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite),文件变更会触发 1.5s debounce 的增量重建。

memory/ 子目录组织最佳实践

  • 日期文件保持平铺在 memory/ 根下,别按 2026/07/ 分目录 —— "今天 + 昨天"自动加载和 backfill 都按扁平日期文件名来找。
  • 常青档案按主题一个文件、用稳定的 kebab-case 命名(entehub-profile.mdamazon-ads-account.md),文件名本身就是检索关键词。
  • 数量多了再按域分子目录(memory/clients/memory/projects/memory/reference/),子目录一样会被递归索引;不要为了三五个文件提前分层。
  • 保留给系统的路径别占用:memory/.dreams/(dreaming 机器状态)、memory/dreaming/<phase>/YYYY-MM-DD.md(阶段报告)。
  • 单个档案别无限膨胀 —— chunk 默认 400 token / 80 token overlap,过长的大杂烩文件会让检索命中变模糊,按主题拆开更好。
  • 写之前先读:只写具体更新,不要留空占位;密钥类内容除非明确要求,不要写进记忆文件。

配置激活

短期/长期两层文件本身开箱即用,不需要配置;需要配置的是三件事:检索、注入预算、自动蒸馏。

不配 embedding provider 时只有关键词检索(FTS5,含 CJK trigram)。配上任一 provider 即启用向量 + 混合检索:

json
{
  "agents": {
    "defaults": {
      "memorySearch": {
        "enabled": true,
        "provider": "openai"
      }
    }
  }
}

provider 可选 openai(默认,text-embedding-3-small)、geminivoyagemistraldeepinfrabedrockollamalmstudiolocal(GGUF)、openai-compatible。显式指定的远程 provider 不可用时不会静默降级为关键词检索,会直接返回 unavailable;想要故意只用关键词就设 provider: "none"

改动 provider / model / chunking / 索引范围后向量索引会失效,需要重建:

shell
openclaw memory status          # 查看 provider 与索引状态
openclaw memory status --deep   # 分别报告 embeddings 与本地向量库
openclaw memory search "查询词"
openclaw memory index --force   # 重建索引

2. 注入预算

MEMORY.md 涨过预算时磁盘文件不动,但注入 prompt 的副本会被截断 —— 这是"该把细节挪去 memory/"的信号。

  • agents.defaults.bootstrapMaxChars 单文件上限,默认 20000
  • agents.defaults.bootstrapTotalMaxChars 全部 bootstrap 文件合计上限,默认 60000

/context list/context detailopenclaw doctor 看 raw vs injected 大小和是否被截断。

3. 自动蒸馏

compaction memory flush(默认开启):压缩会话前先跑一轮静默 turn,提醒 agent 把重要上下文落盘,避免压缩丢信息。关掉:agents.defaults.compaction.memoryFlush.enabled: false。也可以给这一轮单独指定便宜模型:

json
{
  "agents": {
    "defaults": {
      "compaction": { "memoryFlush": { "model": "ollama/qwen3:8b" } }
    }
  }
}

dreaming(默认关闭,opt-in):后台按 light → REM → deep 三阶段跑,只有 deep 阶段在通过 minScore / minRecallCount / minUniqueQueries 三重门槛后才会把内容追加进 MEMORY.md,过程写入 DREAMS.md 供人工复核。开启后 memory-core 会自动维护一条 cron(默认 0 3 * * *):

json
{
  "plugins": {
    "entries": {
      "memory-core": {
        "config": {
          "dreaming": {
            "enabled": true,
            "timezone": "Asia/Hong_Kong",
            "frequency": "0 3 * * *"
          }
        }
      }
    }
  }
}

聊天里也可以 /dreaming status/dreaming on/dreaming off

把历史日记重放一遍看看系统认为哪些"够持久"(只写 DREAMS.md,不直接改 MEMORY.md):

shell
openclaw memory rem-backfill --path ./memory --stage-short-term
openclaw memory rem-backfill --rollback

4. 别忘了 agent 侧的约定

AGENTS.md 里的 session-start 仪式才是让 agent 真正去读记忆的那一半:开场读 SOUL.mdUSER.mdmemory/ 今天+昨天、MEMORY.md;捕捉决策、偏好、约束、未闭环事项。默认模板已包含,自定义 AGENTS.md 时别把这段删了。

Released under the CC-BY-NC-4.0