Memory 是什么
在大语言模型(LLM)中,我们知道Agent中,一般有二类的记忆:
- 瞬时记忆:会话中的临时数据(对话上下文、工具执行缓存),会话结束自动清空。 无需索引,直接通过 RAM 读写,完全离线可用。
- 长期记忆:关键规则沉淀至
memory/MEMORY.md,以及在这个文件中引用的文件,比如:项目约束、设计规范等等。手动编辑即可生效,完全离线可用。
OpenClaw 中的记忆
分为二个层级,是基础的记忆关键字搜索(md文件存储,也会在SQLite里存储FTS索引)与可选且推荐的向量语义检索(SQLite数据库存储VS索引)。注意:md是源内容,而SQLite是对md文件构建的索引库。
- 基础的md记忆存储与上面类似,但做了扩充,比如:
| 层级 | 存储载体 | 核心作用 | 加载/读写方式 |
|---|---|---|---|
| 长期记忆 | MEMORY.md | 存放持久化事实、个人偏好、长期设定、精简摘要信息 | 会话启动时自动注入上下文;仅允许 Dreaming 深度处理阶段写入更新 |
| 工作层 / 每日笔记 | memory/YYYY-MM-DD.md | 记录详细当日笔记、观测内容、会话摘要、原始对话上下文 | 自动加载今日+昨日文件;内容建立索引用于memory_search检索,不会每轮对话注入上下文 |
| 梦境日记(可选) | DREAMS.md | 存储 Dreaming 模块产出:扫描摘要、日记条目、经过事实校验的回填数据 | 仅用于人工复核查看 |
| 短期跟进记忆 | Follow-up、Commitments | 临时时效性信息(例:明日有面试),非永久记忆 | 后台静默根据Agent+通信渠道做轮次推断;依靠Heartbeat机制触发到期提醒 |
| 短期Dreaming存储 | memory/.dreams/ | 提供机器可读、结构化排序数据 | 深度处理阶段依据该目录内容筛选可晋升至MEMORY.md的数据 |
| 导入记忆 | memory/imports/ | 存放从 Codex / Claude Code 导入的Markdown文档 | 文件建立检索索引,仅用于查询,不会合并写入MEMORY.md |
- (向量)记忆索引存储在每个 Agent 独立的 SQLite 数据库中(OpenClaw 内置记忆引擎是默认的记忆后端,无需额外依赖即可使用;可改为其他存储方式),是基于上述 Markdown 文件自动构建的检索加速索引库,它并不存储原始记忆的完整内容,只存储用于快速匹配的分词片段、向量嵌入、文件位置等元数据。但在这一步是需要嵌入向量模型支持,才能完成语义检索(vector search)。
- 完整数据流向:智能体写入 / 更新 Markdown 记忆文件 → 内置
memory-core引擎自动同步构建 / 更新 SQLite 索引 →memory_search工具查询 SQLite 索引定位相关片段 →memory_get工具读取原始 Markdown 文件的对应行内容。 - 在没有完成嵌入向量模型的配置+索引前,只能通过 FTS5 全文索引(BM25 评分)进行关键词搜索(也就是精确术语匹配)支持。
- 通过 FTS5 全文索引(BM25 评分)进行关键词搜索(精确术语匹配)
- 在完成后,就会将纯关键词检索升级为混合检索模式,支持语义召回,即使查询语句与原文表述不一致也能匹配相关记忆。比如:
- 向量搜索/语义检索(vector search)/语义召回(Semantic Recall):语义相似度的匹配,简单来说查询语句和原文表述不一致,依旧可以匹配到相关记忆。
- 混合搜索:关键词+语义召回两路并行加权合并,以获得最佳结果。
- CJK 支持:通过三元组分词支持中文、日文和韩文
- 使用 sqlite-vec 加速数据库内的向量查询(可选)。
- 完整数据流向:智能体写入 / 更新 Markdown 记忆文件 → 内置
最直观的表现就是:字面文字不一样、措辞不同、句式不同、同义改写、概括转述,依然能命中语义相近的记忆片段,这也是它和关键词精准匹配最大的区别。
- Query:上周部门周会定下的上线排期
- 原文记忆:本周一团队例会确定版本于本月 15 号灰度发布
字面词汇重合度很低,但语义一致,语义召回可以命中,纯关键词搜索很难匹配。
嵌入向量模型与对话模型的区别
- 嵌入向量模型在baseUrl后面接的 embeddings(/v1/embeddings)
- 有向量维度概念,比如:512、768、1024
- 注意:OpenClaw 只需要使用文本类型,嵌入向量模型也能支持文本与图片等。
- 对话模型/大语言模型(LLM)在baseUrl后面接 /v1/chat/completions 和 /v1/responses 是不一样的
- 有最大上下文(MAX_CONTEXT_TOKENS)概念,比如:Deepseep支持1M的上下文。
架构:存储层 / 读侧 / 写侧
┌─ 存储层(持久化)─────────────────────────────┐
│ MEMORY.md 长期(仅 Deep 写入) │
│ memory/YYYY-MM-DD.md 每日笔记(工作层) │
│ memory/imports/ 导入记忆 │
│ memory/.dreams/ 机器状态/短期证据 │
│ DREAMS.md 人类可读日记(审核用) │
│ Follow-up Commitments 短期跟进(非持久) │
└─────────────────────────────────────────────┘
▲ 写入 ▲ 读取
│ │
┌─ 写侧(整合)───────────┐ ┌─ 读侧(召回)──────────────────┐
│ Dreaming │ │ memory_search / memory_get │
│ Light→REM→Deep │ │ (依赖 embedding + FTS 索引)│
│ 提升→MEMORY.md │ │ ▲ │
│ fact-grounded backfill│ │ active-memory 插件 │
└────────────────────────┘ │ (主回复前阻塞式召回注入) │
└──────────────────────────────┘
关键关系:active-memory(读侧)和 Dreaming(写侧)都依赖底层的 memory_search 检索能力。而 memory_search 的语义部分靠 embedding(嵌入向量模型)。
而安装后,默认是没有开启(或者没有配置) embedding,见后面的 $ openclaw memory status 输出:
- Vector search 是停止,memory_search 只剩 FTS(关键词)。
- active-memory 受影响:即使你启用它,子智能体调 memory_search 也只能关键词召回,语义相关的记忆召不回来–注入质量打折。
- Dreaming 受影响:Deep 阶段的”相关性信号(0.30)”= 平均检索质量,”查询多样性(0.15)”= 不同查询触发召回–这两个信号都依赖检索系统,embedding 没配好,评分会失准。
有与没有 embedding 的区别
在配好 embedding + 重建索引(openclaw memory index –force)是让读侧(active-memory)和写侧(Dreaming)都能正常工作的前提。
- 启用向量路径 -> 混合搜索:语义+关键词加权合并,用词不同也能命中。这是 FTS 永远做不到的。
- 召回质量增强:MMR 去重 + temporalDecay 时间衰减,靠前的结果更相关更多样。
- active-memory(读侧)的前提:active-memory 子智能体调 memory_search 注入上下文,没向量路径召回质量打折。
- Dreaming(写侧)评分的基础:Deep 阶段相关性信号(0.30)=平均检索质量、查询多样性(0.15),都依赖检索系统。
- 多模态:配 gemini 可索引图像/音频。
- 嵌入缓存减少重复计算。
而不配,代价是只有 FTS5 的 BM25 关键词,语义召回全丢,active-memory/Dreaming 质量打折。
注意:基础记忆功能本身不依赖任何 API,是独立于 embedding 的。比如:
# 全局禁用向量检索(所有 Agent 生效):关闭语义搜索功能,保留所有基础记忆能力
openclaw config set memorySearch.enabled false
openclaw gateway restart
再直接编辑 ~/.openclaw/workspace/MEMORY.md,添加:
## 用户偏好
- **编程语言**:**TypeScript 优先**,拒绝 CoffeeScript。
- **会议习惯**:**周一 10:00 团队周会**,需提前 5 分钟准备议程。
保存后,Agent 在下次会话中会自动加载此规则。无需重建索引,直接提问:
> “我周一的会议需要做什么准备?”
> Agent 将基于 `MEMORY.md` 返回:**“需提前 5 分钟准备议程”**。
或强制读取记忆文件,在聊天中输入以下内容,将直接输出文件内容
/memory get MEMORY.md
以上,都证明基础记忆功能是独立于向量索引;所以,OpenClaw 的记忆功能 ≠ 仅向量检索。
启用记忆搜索
安装后默认只有FTS
$ openclaw memory status # 检查(记忆)索引状态和提供商
Memory Search (main)
Provider: openai (requested: openai) # 默认是 openai公司的
Model: openai
Sources: memory
Indexed: 0/6 files · 0 chunks # 记忆文件存在但未索引,导致无法实际调用历史记忆
Dirty: yes
Store: ~/.openclaw/agents/main/agent/openclaw-agent.sqlite
Workspace: ~/.openclaw/workspace
Dreaming: off # Dreaming(主动记忆)明确关闭
Index identity: index metadata is missing
Vector search: paused until memory is rebuilt # 记忆检索功能因索引缺失而失效,下一行是Fix办法。
Fix: Run: openclaw memory status --index --agent main
By source:
memory · 0/6 files · 0 chunks
Vector store: unknown
FTS: ready
Embedding cache: enabled (0 entries)
Batch: disabled (failures 0/2)
Recall store: 0 entries · 0 promoted · 0 concept-tagged · 0 spaced
Recall path: plugin-state:memory-core/short-term-recall/62f101f94bc509c715646d26c64be8e50bf7b79c039cb840bb687a1743fc18bf
Dreaming artifacts: diary absent · 0 corpus files · ingestion state absent
Dream corpus: ~/.openclaw/workspace/memory/.dreams/session-corpus
Dream ingestion: ~/.openclaw/workspace/memory/.dreams/session-ingestion.json
$ openclaw memory status --index --agent main
[openclaw] Reason: No API key found for provider "openai". Auth store: /home/claw/.openclaw/agents/main/agent/openclaw-agent.sqlite (agentDir: /home/claw/.openclaw/agents/main/agent). Configure auth for this agent (openclaw agents add <id>) or copy only portable static auth profiles from the main agentDir. | missing-provider-auth
先使用嵌入模型开启向量检索
- 无论使用API,还是本地,都需要开启
memorySearch总开关。 - 官方文档的配置是错误的,
openclaw config set memory.search.provider "openai-compatible"报错无search。可参考:https://openclaw.club/archives/OuFvbN01 memorySearch废弃节点,已被agents.defaults.memorySearch取代,网上还有很多文档使用这个节点。
openclaw config set agents.defaults.memorySearch.enabled true
CLI
openclaw memory status [--deep] # 检查索引状态和提供商
openclaw memory status --index --agent main # 在配置后,初始索引
openclaw memory search "query" # 从命令行搜索
openclaw memory index --force # 重建索引
最简单方法,用免费的向量模型:阿里云百炼(100W+90天)、火山(50W)
openclaw config set agents.defaults.memorySearch.provider "openai-compatible"
openclaw config set agents.defaults.memorySearch.model "qwen3.7-text-embedding"
openclaw config set agents.defaults.memorySearch.remote.baseUrl "https://ws-xxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
openclaw config set agents.defaults.memorySearch.remote.apiKey "sk-ws-xxx"
不需要重启,可直接启动索引了。
$ openclaw memory status --index --agent main
OpenClaw 2026.7.1-2 (0790d9f) — Hot reload for config, cold sweat for deploys.
Memory index complete.
Memory Search (main)
Provider: openai-compatible (requested: openai-compatible) # 已有变化了
Model: qwen3.7-text-embedding # 已有变化了
Sources: memory
Indexed: 5/5 files · 14 chunks # 向量索引完成的数量
Dirty: no
Store: ~/.openclaw/agents/main/agent/openclaw-agent.sqlite # 数据库包含 向量表(chunks_vec)和全文索引表(chunks_fts),实现混合检索
Workspace: ~/.openclaw/workspace/main
Dreaming: off # Dreaming(主动记忆)还是为关闭状态
Embeddings: ready # **向量生成服务已就绪**
By source:
memory · 5/5 files · 14 chunks
# 下面的 unknown 表示 没有外部向量数据库(如 Chroma、Qdrant 等),而是直接通过 SQLite 的本地扩展 sqlite-vec 实现向量存储。
Vector store: unknown
Vector dims: 1024 # 向量维度为 1024
#SQLite 向量扩展库 `sqlite-vec` 的本地路径。该库提供 **向量相似度搜索能力**(如余弦相似度),是混合检索的技术基础。
Vector path: /usr/local/nodejs/lib/node_modules/openclaw/node_modules/sqlite-vec-linux-x64/vec0.so
FTS: ready
Embedding cache: enabled (12 entries) # 嵌入缓存开启状态,且有索引数据
Batch: disabled (failures 0/2) # 批量嵌入处理未启用(当前配置为单次请求),后面5行全是 Dreaming(主动记忆)
Recall store: 0 entries · 0 promoted · 0 concept-tagged · 0 spaced
Recall path: plugin-state:memory-core/short-term-recall/dcd62ab12ac732d083824caf84315ee87402bd3e63851aa780b7199d61bba404
Dreaming artifacts: diary absent · 0 corpus files · ingestion state absent
Dream corpus: ~/.openclaw/workspace/main/memory/.dreams/session-corpus
Dream ingestion: ~/.openclaw/workspace/main/memory/.dreams/session-ingestion.json
再开启 MMR + 时间衰减,验证混合搜索
- https://docs.openclaw.ai/zh-CN/concepts/memory-search
- https://openclaw.club/archives/OuFvbN01
- 时间衰减:旧笔记的排名权重会逐渐降低,使近期信息优先显示。采用默认的 30 天半衰期时,上个月的笔记得分为其原始权重的 50%。
- MEMORY.md 和 memory/ 下其他未注明日期的文件属于长期有效内容,永不衰减;
- 只有带日期的 memory/YYYY-MM-DD.md 文件会衰减。
- MMR(多样性):减少重复结果。如果五条笔记都提到相同的路由器配置,MMR 会确保排名靠前的结果涵盖不同主题,而不是重复相同内容。
# 这二个需要主动配置,才生效。
openclaw config set agents.defaults.memorySearch.query.hybrid.temporalDecay.enabled true
openclaw config set agents.defaults.memorySearch.query.hybrid.mmr.enabled true
- 混合搜索:只要向量检索功能就绪(
Vector: ready),混合搜索即自动生效,无需额外显式启用hybrid.enabled。- 系统 默认采用
70% 向量 + 30% 关键词的加权融合策略 - 向量检索可用(
Vector: ready),系统会自动执行混合搜索;若向量检索失败,则优雅降级为纯关键词检索(仍保留“混合”逻辑,但权重调整为0% 向量 + 100% 关键词) - 验证方法:
openclaw memory search "查询词" --json,返回结果中是否同时包含vectorScore(非零)和textScore(非零)字段——两者均存在即证明混合搜索生效。
- 系统 默认采用
$ openclaw memory search "OK" --json
{
"results": [
{
"path": "memory/2026-07-20-1636.md",
"startLine": 1,
"endLine": 13,
"score": 0.5087063045057383,
"vectorScore": 0.4867861866950989,
"textScore": 0.5598532460638971,
"snippet": "xxxx",
"source": "memory"
}
]
}
后开启梦境系统(Dreaming)
- Dreaming 是 memory-core 中的后台记忆整合系统。它将强烈的短期信号转化为持久记忆,同时确保整个过程可解释、可审查。
- Dreaming 配置在 plugins.entries.memory-core.config.dreaming 下,默认是关闭。
- Dreaming 作为定时扫描运行,会自动摄取并整理会话中的内容,在内部经过 Light -> REM -> Deep 三个阶段
- 个人和敏感内容会在摄取前进行脱敏处理。
memory/*.md每日笔记从一开始就在 memory_search 索引范围内,Dreaming 只是对其做整理、打分和晋升筛选,并不会改变它们本身的可检索性。同时形成反馈闭环:每次 memory_search 命中每日笔记中的内容,都会生成召回信号,写入短期召回记录,作为 Dreaming 后续评分晋升(写入到 MEMORY.md)的依据之一- Dreaming 的核心价值是筛选高价值内容沉淀到长期记忆层,让
memory_search的召回结果更精炼、信噪比更高,而非扩展检索范围。 - Dreaming 自动生成的反思、日记类内容本身,不会被当作记忆晋升,也不纳入记忆检索范围。
- 会形成以下产物:
| 产物类型 | 是否参与 memory_search | 说明 |
|---|---|---|
| 晋升至 MEMORY.md 的会话片段 | 是 | 正式长期记忆,支持关键词 + 语义混合检索。前提:使用加权评分和阈值门控对候选项进行排序(minScore、minRecallCount、minUniqueQueries 必须全部通过) |
| memory/.dreams/ 下的中间状态 | 否 | 机器用的排序信号、暂存候选,仅内部使用 |
| DREAMS.md 梦境日记 | 否 | 叙事性报告,供人工审阅,不作为正式记忆 |
| memory/dreaming/ 阶段报告 | 否 | 审计日志,用于回溯整理过程 |
开启配置
openclaw config set plugins.entries.memory-core.config.dreaming.enabled true
# 每6小时扫描运行一次
openclaw config set plugins.entries.memory-core.config.dreaming.frequency "0 */6 * * *"
# 指定使用Model,在不可用时,Dream Diary 会使用会话默认LLM模型重试一次。
#openclaw config set plugins.entries.memory-core.subagent.allowModelOverride true
#openclaw config set plugins.entries.memory-core.subagent.allowedModels '["provider/model",""]'
#openclaw config set plugins.entries.memory-core.config.dreaming.model "provider/model"
重启后生效,openclaw config get plugins.entries.memory-core 示例
{
subagent: {
allowModelOverride: true,
allowedModels: ["anthropic/claude-sonnet-4-6"],
},
config: {
dreaming: {
enabled: true,
frequency: "0 3 * * *",
model: "anthropic/claude-sonnet-4-6",
},
},
}
会话中命令
/dreaming status
/dreaming on
/dreaming off
/dreaming help
CLI
# 提升预览/应用:除非通过 CLI 标志覆盖,否则手动 memory promote 默认使用 Deep 阶段阈值。
openclaw memory promote
openclaw memory promote --apply
openclaw memory promote --limit 5
openclaw memory status --deep
# 解释特定候选项为何会或不会被提升:
openclaw memory promote-explain "router vlan"
openclaw memory promote-explain "router vlan" --json
# REM harness 预览:在不写入任何内容的情况下预览 REM 反思、候选事实和深度提升输出
openclaw memory rem-harness
openclaw memory rem-harness --json
其他
本地 GGUF 嵌入
等我的免费额度使用完了,再来折腾吧。
| 提供商 ID | 底层依赖 | 模型格式 | 核心特点 |
|---|---|---|---|
| local | @openclaw/llama-cpp-provider 插件 | GGUF | 进程内运行,无需额外启动服务,纯本地无网络依赖 |
| ollama | 本地 Ollama 服务 | Ollama 模型格式 | 部署简单,模型生态丰富,通过 HTTP API 调用 |
| lmstudio | 本地 LM Studio 服务 | GGUF 等通用格式 | 偏向桌面端可视化管理,服务器场景使用较少 |
记忆搜索的参数:其他配置示例
一般使用默认就好,如有更高要求可参考:
agents.defaults."memorySearch": {
// 使用 API 做批量索引(Batch Indexing):默认是单次请求
"remote": {
"batch": {
"enabled": true,
"concurrency": 2, // 并发批量任务数
"wait": true, // 等待批量完成
"pollIntervalMs": 1000, // 轮询间隔
"timeoutMinutes": 30 // 超时时间
}
},
// 混合搜索 + MMR + 时间衰减
"query": {
"hybrid": {
"enabled": true, // 启用混合搜索,不需要主动开启
"vectorWeight": 0.7, // 可选参数(默认 0.7)向量权重(0-1)
"textWeight": 0.3, // 可选参数(默认 0.3)文本权重(0-1)
"candidateMultiplier": 4 // 候选池倍数
,"mmr": {
"enabled": true, // 启用 MMR
"lambda": 0.7 // 可选参数(默认 0.7)0=最大多样性,1=最大相关性
},
"temporalDecay": {
"enabled": true, // 启用 时间衰减
"halfLifeDays": 30 // 可选参数(默认 30)30 天后分数减半
}
}
},
// 嵌入缓存:默认开启
"cache": {
"enabled": true,
"maxEntries": 50000 // 最多缓存 5 万个嵌入
},
// 索引会话记录,让 memory_search 可以检索之前的对话
"experimental": {
"sessionMemory": true
},
"sources": ["memory", "sessions"], // 在源中加入会话,默认只有memory
"sync": {
"sessions": {
"deltaBytes": 100000, // 100KB 触发重新索引
"deltaMessages": 50 // 50 条消息触发重新索引
}
},
// 索引工作区外的文档
"extraPaths": [
"../team-docs", // 相对路径
"/srv/shared-notes" // 绝对路径
]
}
}
主动记忆(Active Memory):一把双刃剑
- plugins.entries.active-memory.config.queryMode 不一定能解决问题,除非配置为full;但配置 full 无意义/燥声高,且 token 消耗大。
- 主动注入上下文是优点,也是缺点,Dreaming 不能主动注入。
- 跨会话保持对话连贯性是优点,也是缺点。
- 梦境系统(Dreaming),虽然会整理会话内容,但要求高(只有晋升到 MEMORY.md,再才会参与 memory_search)
- Dreaming 的前提有向量模型,而active-memory不需要使用向量模型
主动记忆(Active Memory)的核心作用是让AI智能体从“被动响应”升级为“主动预判”——它无需用户显式指令,即可在每次对话前自动检索并注入最相关的背景信息,使AI表现得像真正理解上下文的人类助手。与<u>传统记忆系统依赖用户主动触发检索</u>不同,主动记忆通过前置式上下文注入机制,彻底解决了AI“健忘”和“上下文漂移”问题,实现跨会话的连续性协作。
主动记忆是一项对话增强功能,而不是平台级 推理功能,只能在以下两个途径运行:
- Control UI / Web 聊天持久会话
- 同一持久聊天路径上的其他交互式渠道会话
适合会话是持久且面向用户的(跨会话保持对话连贯性),它不适合自动化、内部工作进程、单次 API 任务,或任何隐藏式 个性化会令人意外的场景。
每次主 Agent 回复前额外运行一次子 Agent,每次对话都会多消耗 token。
openclaw plugins info active-memory # 默认是关闭
openclaw plugins enable|disable active-memory # 只是把插件启用了,要重启生效
openclaw config get plugins.entries.active-memory # 查看配置
开启的配置:只要运行二命令可以了
- 更多参数:主动记忆
# 限定Agent为 main,支持多个。
openclaw config set plugins.entries.active-memory.config.agents '["main"]'
# 限定为私信会话(默认值),有效值:direct、group、channel,进一步控制范围添加 config.allowedChatIds 和 config.deniedChatIds 指定。
#openclaw config set plugins.entries.active-memory.config.allowedChatTypes: '["direct"]'
# 限定对话内容范围,有效值:(内容越多token消耗越多,config.timeoutMs值要越大)
# message 仅发送最新的用户消息。config.timeoutMs,可从 3000-5000 ms 左右开始。
# recent 最新的用户消息加上一小段近期对话尾部。可从 15000 ms 左右开始。
# full 完整对话会发送给阻塞式子智能体。从约 15000 ms 或更高值开始。
openclaw config set plugins.entries.active-memory.config.queryMode "recent"
# 在返回记忆时的积极程度或严格程度,有效值参考 https://docs.openclaw.ai/zh-CN/concepts/active-memory#%E6%8F%90%E7%A4%BA%E8%AF%8D%E9%A3%8E%E6%A0%BC
#openclaw config set plugins.entries.active-memory.config.promptStyle "balanced"
# 超时范围 250-120000 ms;默认 15000
#openclaw config set plugins.entries.active-memory.config.timeoutMs 15000
# 主动记忆摘要的最大字符数(范围 40-1000;默认 220)
#openclaw config set plugins.entries.active-memory.config.maxSummaryChars 220
# 调优时输出主动记忆日志
#openclaw config set plugins.entries.active-memory.config.logging true
会话开关
–global代表所有会话(全局形式会写入 plugins.entries.active-memory.config.enabled,注意不是plugins.entries.active-memory.enabled)
/active-memory status [--global]
/active-memory off [--global]
/active-memory on [--global]
#openclaw config set plugins.entries.active-memory.config.enabled false # 全局会话关闭主动记
验证
/verbose on
/trace on
发表回复
要发表评论,您必须先登录。