如果你曾经使用过 AI 助手,可能会遇到这样的困扰:聊了半天,换个话题回来,它就"失忆"了。OpenClaw 用一种简单但聪明的方式解决了这个问题——把记忆写到文件里。
什么是 OpenClaw 记忆?
OpenClaw 的记忆系统其实很直白:就是 Markdown 文件。没有复杂的数据库,没有神秘的存储机制,就是你能直接打开、编辑的普通文本文件。
这种设计有个好处:模型只"记住"真正写到磁盘上的内容。你可以随时查看、修改这些记忆文件,完全透明可控。
记忆功能由 memory-core 插件提供。如果不需要记忆功能,可以通过配置禁用。
两层记忆结构
OpenClaw 默认使用两种记忆文件:
每日日志:memory/YYYY-MM-DD.md
这就像你的工作日记。每天的对话、想法、临时笔记都记在这里。这个文件采用仅追加模式,系统会自动读取今天和昨天的日志,让 AI 能记住最近的上下文。
适合记录:
- 今天讨论的技术问题
- 临时的想法和灵感
- 正在进行的任务进度
长期记忆:MEMORY.md
这是精心整理的"知识库"。你的重要决策、个人偏好、持久性的事实都应该放在这里。
适合记录:
- 你的编程习惯和偏好
- 项目的重要决策
- 需要长期记住的信息
注意:MEMORY.md 只在私人会话中加载,不会在群组对话中暴露,保护你的隐私。
什么时候该写记忆?
OpenClaw 的设计哲学很简单:想让 AI 记住,就明确告诉它写下来。
- 重要决策和偏好 → 写入
MEMORY.md - 日常笔记和临时信息 → 写入
memory/YYYY-MM-DD.md - 有人说"记住这个" → 立即写入文件
别指望 AI 自己判断什么该记。直接说"把这个写到记忆里",它就知道该怎么做。
自动记忆刷新:不让重要信息丢失
这是个很贴心的功能。当对话快要超出上下文窗口时,OpenClaw 会自动触发一个"静默回合",提醒 AI 把重要信息写入记忆,然后再压缩对话历史。
整个过程是静默的,你不会感觉到任何打扰。AI 会自动判断是否需要保存信息,如果没什么要记的,就回复 NO_REPLY,继续正常对话。
配置要点
{
agents: {
defaults: {
compaction: {
reserveTokensFloor: 20000,
memoryFlush: {
enabled: true,
softThresholdTokens: 4000,
systemPrompt: "Session nearing compaction. Store durable memories now.",
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store.",
},
},
},
},
}
关键参数:
enabled: true- 启用自动刷新softThresholdTokens: 4000- 提前 4000 个 token 触发刷新- 工作空间必须可写(只读模式下会跳过)
向量搜索:让记忆真正可用
有了记忆文件是第一步,但如果记忆太多,怎么快速找到相关信息?OpenClaw 用向量搜索解决这个问题。
它是如何工作的?
系统会自动为你的记忆文件建立向量索引。当 AI 需要查找信息时,即使你换了种说法,它也能找到相关内容。
搜索机制:
- 将 Markdown 文件分成约 400 个 token 的块
- 块之间有 80 个 token 的重叠(避免信息被截断)
- 返回的片段文本上限约 700 个字符
- 包含文件路径、行范围、相似度分数等元数据
可用工具:
memory_search- 语义搜索记忆片段memory_get- 按路径读取完整记忆文件
比如:
- 你之前记录了"Mac Studio gateway host"
- 现在问"运行 gateway 的那台机器"
- 向量搜索能理解这是同一件事
三种嵌入模式
1. 远程嵌入(默认)
使用 OpenAI 或 Gemini 的 API。如果未手动设置提供商,OpenClaw 会按以下优先级自动选择:
- 如果配置了本地模型路径且文件存在 → 使用
local - 如果可以解析 OpenAI 密钥 → 使用
openai - 如果可以解析 Gemini 密钥 → 使用
gemini - 都没有 → 禁用搜索
API 密钥来源:
- 身份验证配置文件
models.providers.*.apiKey配置- 环境变量(如
GEMINI_API_KEY)
注意:Codex OAuth 只涵盖聊天/补全功能,不能用于记忆搜索的嵌入需求。
配置示例(OpenAI):
agents: {
defaults: {
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
apiKey: "YOUR_API_KEY"
}
}
}
}
配置示例(Gemini):
agents: {
defaults: {
memorySearch: {
provider: "gemini",
model: "gemini-embedding-001",
remote: {
apiKey: "YOUR_GEMINI_API_KEY"
}
}
}
}
2. 本地嵌入
不想依赖外部 API?可以用本地模型。默认会自动下载约 0.6 GB 的模型。
agents: {
defaults: {
memorySearch: {
provider: "local",
local: {
modelPath: "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf"
},
fallback: "none"
}
}
}
注意:本地模式需要运行 pnpm approve-builds 并重新编译 node-llama-cpp。
3. 自定义端点
如果你用的是 OpenRouter、vLLM 或其他兼容 OpenAI 的服务:
agents: {
defaults: {
memorySearch: {
provider: "openai",
model: "text-embedding-3-small",
remote: {
baseUrl: "https://api.example.com/v1/",
apiKey: "YOUR_API_KEY",
headers: { "X-Custom-Header": "value" }
}
}
}
}
混合搜索:语义 + 关键词
向量搜索很强大,但有时你需要精确匹配,比如查找特定的 ID、环境变量名或错误信息。OpenClaw 的混合搜索结合了两种方式:
- 向量搜索:理解语义,找到"意思相近"的内容
- BM25 关键词搜索:精确匹配特定词汇
算法原理
混合搜索的工作流程:
-
检索候选池:
- 向量搜索:按余弦相似度取前 N 个结果
- BM25 搜索:按关键词相关性取前 N 个结果
- N =
maxResults × candidateMultiplier(默认 4 倍)
-
分数归一化:
- 向量分数:0-1 范围的余弦相似度
- BM25 分数:
textScore = 1 / (1 + max(0, bm25Rank))
-
加权合并:
finalScore = vectorWeight × vectorScore + textWeight × textScore- 权重自动归一化为 1.0
容错机制:
- 如果嵌入不可用 → 仅使用 BM25
- 如果全文搜索不可用 → 仅使用向量搜索
配置混合搜索
agents: {
defaults: {
memorySearch: {
query: {
hybrid: {
enabled: true,
vectorWeight: 0.7, // 语义搜索权重 70%
textWeight: 0.3, // 关键词搜索权重 30%
candidateMultiplier: 4
}
}
}
}
}
你可以根据需求调整权重:
- 更注重语义理解 → 提高
vectorWeight - 更需要精确匹配 → 提高
textWeight
索引额外的文档
除了默认的记忆文件,你还可以索引其他 Markdown 文档:
agents: {
defaults: {
memorySearch: {
extraPaths: [
"../team-docs", // 团队文档目录
"/srv/shared-notes/overview.md" // 共享笔记
]
}
}
}
说明:
- 支持绝对路径和相对路径
- 目录会递归扫描所有
.md文件 - 符号链接会被忽略
性能优化配置
嵌入缓存
避免重复计算相同内容的嵌入:
agents: {
defaults: {
memorySearch: {
cache: {
enabled: true,
maxEntries: 50000
}
}
}
}
SQLite 向量加速
使用 sqlite-vec 扩展加速向量搜索:
agents: {
defaults: {
memorySearch: {
store: {
vector: {
enabled: true,
extensionPath: "/path/to/sqlite-vec" // 可选
}
}
}
}
}
如果扩展不可用,系统会自动回退到 JavaScript 实现,不会影响功能。
批量索引(OpenAI/Gemini)
处理大量文档时,批量索引更快更便宜:
agents: {
defaults: {
memorySearch: {
provider: "openai",
remote: {
batch: {
enabled: true,
concurrency: 2, // 并行批处理数
pollIntervalMs: 5000, // 轮询间隔
timeoutMinutes: 30 // 超时时间
}
}
}
}
}
为什么用批量索引?
- OpenAI Batch API 有折扣定价
- 异步处理,不阻塞主流程
- 适合大规模文档索引
实验性功能:会话记忆搜索
想让 AI 搜索历史对话?可以启用会话记忆索引:
agents: {
defaults: {
memorySearch: {
experimental: { sessionMemory: true },
sources: ["memory", "sessions"],
sync: {
sessions: {
deltaBytes: 100000, // 累积 100KB 后触发索引
deltaMessages: 50 // 或累积 50 条消息
}
}
}
}
}
注意事项:
- 这是实验性功能,默认关闭
- 会话日志存储在本地磁盘,注意隐私
- 索引是异步的,可能有轻微延迟
实用技巧
1. 记忆文件位置
默认在 ~/.openclaw/workspace 下:
MEMORY.md- 长期记忆memory/2026-03-11.md- 今天的日志memory/2026-03-10.md- 昨天的日志
2. 禁用记忆功能
如果不需要记忆功能:
{
plugins: {
slots: {
memory: "none"
}
}
}
3. 回退策略
设置主提供商失败时的备选方案:
agents: {
defaults: {
memorySearch: {
provider: "local",
fallback: "openai" // 本地失败时用 OpenAI
}
}
}
4. 监控索引状态
系统会自动监控文件变化并更新索引(去抖动 1.5 秒)。索引存储在:
~/.openclaw/memory/<agentId>.sqlite
索引触发时机:
- 会话开始时
- 执行搜索时
- 按配置的时间间隔
- 会话记录超过增量阈值时(后台异步)
索引新鲜度:
- 文件监视器实时监控
MEMORY.md、memory/和extraPaths - 检测到变化后标记索引为"脏"(去抖动 1.5 秒)
- 下次触发时自动同步更新
5. 触发重新索引
当以下配置变化时,系统会自动重建索引:
- 嵌入提供商或模型
- API 端点
- 分块参数
总结
OpenClaw 的记忆系统设计得很务实:
- 简单透明:就是 Markdown 文件,你能直接查看和编辑
- 分层管理:日志记临时信息,MEMORY.md 记长期知识
- 智能搜索:向量 + 关键词混合搜索,既理解语义又支持精确匹配
- 灵活配置:支持远程/本地/自定义端点,适应不同需求
- 自动维护:压缩前自动刷新,文件变化自动索引
最重要的是:想让 AI 记住什么,就明确告诉它写下来。这比依赖 AI 自己判断要可靠得多。