OpenClaw 默认记忆搜索只能关键字匹配,找不到语义相似内容。实测向量检索方案:Ollama 本地 embedding(免费无限制)vs Gemini 云端(每天 1000 次)。混合搜索(BM25+ 向量)+ 自动索引更新,71 个 chunks 查询速度<1 秒。
你好,我是郑工长。
当你装好 OpenClaw 后,真正决定它能不能长期稳定工作的一步,其实是——给 OpenClaw 配置好记忆系统。
我的 OpenClaw 目前创建了3个Agent,以我的本机真实环境为例,这篇文档完整记录了 OpenClaw 向量检索记忆能力的实现全过程:从功能背景、配置步骤、到验证方法,以及我在实测中遇到的关键问题与最终的解决方案。
OpenClaw 默认使用 Markdown 文件来存储记忆:
- memory/YYYY-MM-DD.md - 每日日志(追加模式)
- MEMORY.md - 长期记忆(可选)
这种方案的优点是简单直观,但存在以下问题:
问题 |
描述 |
全文搜索低效 |
只能通过文件名或手动搜索,无法进行语义匹配 |
无法检索相似内容 |
即使文档中表达了相同含义,不同措辞也会导致找不到结果 |
没有相关性排序 |
返回结果按照文件顺序,无法根据相关度排序 |
随着记忆文件增多(当前已有 70+ 个 chunks),手动查找变得困难。我们需要一个能:
- ✅ 理解语义相似性的搜索功能
- ✅ 自动根据相关度排序结果
- ✅ 支持模糊查询(措辞不同但含义相近)
在配置向量检索之前,先确认 OpenClaw 已安装记忆插件:
# 查看已安装的插件列表 openclaw plugins list
或者只查看记忆相关插件
openclaw plugins list | grep -i memory
预期输出:
│ Memory │ memory- │ loaded │ stock:memory-core/index.ts │ 2026.2.26 │ │ (Core) │ core │ │ File-backed memory search tools and CLI │ │
状态说明:
- loaded:✅ 已安装并启用
- disabled:❌ 已安装但未启用
- 无输出:❌ 未安装
如果未安装,执行以下命令安装:
# 安装记忆插件(Core 版本) openclaw plugins install @openclaw/memory
安装后重启 OpenClaw:
openclaw gateway restart
⚠️ 注意:OpenClaw 2026.2.26 版本默认已安装 memory-core 插件,通常无需手动安装。
OpenClaw 提供两种记忆插件,它们有显著区别:
特性 |
memory-core(推荐) |
memory-lancedb |
存储方式 |
Markdown 文件(MEMORY.md + memory/*.md) |
LanceDB 向量数据库 |
数据源 |
✅ 文件是真理源,人类可读 |
❌ 二进制数据库,需通过 API 访问 |
记忆管理 |
手动写入(Agent 主动保存) |
✅ 自动捕获 + 自动回忆 |
检索方式 |
混合搜索(BM25 + 向量) |
向量搜索为主 |
嵌入支持 |
✅ 多 provider(Gemini/Ollama/OpenAI 等) |
历史上绑定 OpenAI |
性能 |
小数据集快 |
大数据集性能更好 |
复杂度 |
✅ 简单,易维护 |
较复杂,需管理数据库 |
版本控制 |
✅ 支持 Git |
❌ 二进制文件 |
- ✅ 简单直观 - 记忆就是 Markdown 文件,可以直接编辑查看
- ✅ 人类可读 - 无需工具就能阅读记忆内容
- ✅ 版本控制友好 - 可以 Git 提交,方便回溯
- ✅ 灵活配置 - 支持多种 embedding provider(我们用的 Ollama)
- ✅ 混合搜索 - BM25 + 向量,兼顾关键字和语义匹配
- ✅ 自动捕获 - 自动保存对话中的重要信息
- ✅ 自动回忆 - 自动注入相关记忆到上下文
- ✅ 向量数据库 - 专业向量存储,大数据集性能更好
- ✅ 生命周期钩子 - 通过 hooks 自动管理记忆
我们选择 memory-core 而非 memory-lancedb,主要基于以下考虑:
- ✅ 记忆文件人类可读 - 方便直接查看和编辑
- ✅ 支持 Git 版本控制 - 便于回溯和审计
- ✅ 对本地 embedding(Ollama)支持更完善 - 无需依赖 OpenAI
- ✅ 配置简单 - 维护成本低
- ✅ 当前记忆规模(~100 chunks)下性能完全够用 - 无需过度设计
- 需要自动记忆捕获功能
- 记忆规模超过 1000+ chunks
- 不介意黑盒存储方式
- 需要自动回忆注入到上下文
建议:对于大多数个人和小团队场景,memory-core 已经足够使用。只有在需要自动记忆捕获或处理大规模记忆数据时,才考虑 memory-lancedb。
OpenClaw 支持多种 Embedding Provider,根据实际场景选择合适的方案:
特性 |
Gemini |
Ollama(本地) |
费用 |
免费 tier 1000 次/天 |
✅ 完全免费 |
网络 |
需要翻墙 |
✅ 本地访问 |
隐私 |
数据发送到 Google |
✅ 数据不出本地 |
速度 |
依赖网络 |
✅ 本地推理 |
配额 |
有限制 |
✅ 无限制 |
配置难度 |
简单 |
中等 |
推荐:
- 优先使用 Ollama(免费、本地、无限制)
- 备选 Gemini(云端、需要 API Key)
# macOS brew install ollama
启动 Ollama 服务
ollama serve
# 推荐模型:nomic-embed-text(性能优秀,8K 上下文) ollama pull nomic-embed-text
验证模型已安装
ollama list
在 ~/.openclaw/openclaw.json 中添加 memorySearch 配置:
{ “agents”: {
"defaults": { "memorySearch": { "provider": "openai", "model": "nomic-embed-text:v1.5", "remote": { "apiKey": "ollama-local", "baseUrl": "http://127.0.0.1:11434/v1" } } }
} }
配置说明:
- provider: 使用 “openai”(OpenClaw 支持的 provider,通过兼容接口调用 Ollama)
- model: 使用 nomic-embed-text:v1.5(需要与本地安装的模型版本一致)
- remote.apiKey: 占位值 “ollama-local”(Ollama 不需要真实 API Key)
- remote.baseUrl: Ollama 的 OpenAI 兼容接口地址
- 无需配置 extraPaths:每个 Agent 默认会自动索引自己工作区的 MEMORY.md 和 memory/*.md 文件
⚠️ 重要:Ollama 的 OpenAI 兼容接口 URL 是 http://127.0.0.1:11434/v1(注意末尾的 /v1)
访问 Google AI Studio:
https://aistudio.google.com/app/apikey
在 ~/.openclaw/.env 文件中配置 Gemini API Key:
# Google Gemini GEMINI_API_KEY=your_gemini_api_key_here
⚠️ 安全提示:不要将真实的 API Key 提交到版本控制系统中。
在 ~/.openclaw/openclaw.json 中添加 memorySearch 配置:
{ “agents”: {
"defaults": { "memorySearch": { "provider": "gemini", "model": "gemini-embedding-001", "remote": { "apiKey": "${GEMINI_API_KEY}" } } }
} }
配置说明:
- provider: 使用 Gemini 作为嵌入服务提供商
- model: 使用 gemini-embedding-001 模型
- remote.apiKey: 从环境变量读取 API Key
配置完成后,重启 Gateway 使配置生效:
openclaw gateway restart
⚠️ 注意:重启操作最好由(你)执行。
重启完成后,执行记忆索引:
openclaw memory index –verbose
索引输出示例(Ollama):
Memory Index (main) Provider: openai (requested: openai) Model: nomic-embed-text:v1.5 Sources: memory Indexed: 17⁄17 files · 46 chunks Memory index updated (main).
Memory Index (zhengxiaobian) Provider: openai (requested: openai) Model: nomic-embed-text:v1.5 Sources: memory Indexed: 7⁄7 files · 19 chunks Memory index updated (zhengxiaobian).
Memory Index (fullstack-dev) Provider: openai (requested: openai) Model: nomic-embed-text:v1.5 Sources: memory Indexed: 4⁄4 files · 7 chunks Memory index updated (fullstack-dev).
索引输出示例(Gemini):
Memory Index (main) Provider: gemini (requested: gemini) Model: gemini-embedding-001 Sources: memory Indexed: 19⁄19 files · 78 chunks Memory index updated (main).
Memory Index (zhengxiaobian) Provider: gemini (requested: gemini) Model: gemini-embedding-001 Sources: memory Indexed: 10⁄10 files · 41 chunks Memory index updated (zhengxiaobian).
Memory Index (fullstack-dev) Provider: gemini (requested: gemini) Model: gemini-embedding-001 Sources: memory Indexed: 3⁄3 files · 7 chunks Memory index updated (fullstack-dev).
说明:
- 每个 Agent 自动索引自己工作区的记忆文件
- 无需配置 extraPaths,默认会索引:MEMORY.md(工作区根目录)memory/*.md(工作区 memory 目录)
使用 memory_search 工具进行测试查询:
openclaw memory search “首次沟通 时间 记录”
预期结果:
- 返回相关记忆片段(按相关度排序)
- 包含文件路径和行号引用
- 显示相似度分数
实际测试结果(Ollama):
{ “results”: [
{ "path": "memory/2026-03-05.md", "startLine": 58, "endLine": 149, "score": 0.7019, "snippet": "...", "citation": "memory/2026-03-05.md#L58-L149" }
], “provider”: “openai”, “model”: “nomic-embed-text:v1.5”, “mode”: “hybrid” }
实际测试结果(Gemini):
{ “results”: [
{ "path": "memory/2026-03-04.md", "startLine": 1, "endLine": 35, "score": 0.4815, "snippet": "...", "citation": "memory/2026-03-04.md#L1-L35" }
], “provider”: “gemini”, “model”: “gemini-embedding-001”, “mode”: “hybrid” }
✅ 功能验证通过!
同时使用向量相似性和 BM25 关键字相关性:
- 向量搜索:理解语义相似性(”首次沟通”能匹配到”首次对话”)
- BM25 关键字:精确匹配高信号 token(ID、错误码、代码符号)
- 自动触发:文件变更后 1.5 秒延迟后自动更新索引
- 按需同步:执行 memory_search 时检查索引状态
- 强制更新:执行 openclaw memory index 时重新索引
每个 Agent 独立的 SQLite 数据库:
- /.openclaw/memory/main.sqlite
- /.openclaw/memory/zhengxiaobian.sqlite
- /.openclaw/memory/fullstack-dev.sqlite
在实施过程中遇到了 Gemini API 配额耗尽(429 错误) 的问题,经过系统排查发现根本原因是环境变量配置不一致。
执行 memory_search 时返回错误:
gemini embeddings failed: 429 RESOURCE_EXHAUSTED You exceeded your current quota, please check your plan and billing details.
发现存在两个不同的 Gemini API Key:
来源 |
值 |
状态 |
终端环境变量 |
AIzaSy…CF-o |
❌ 配额耗尽 |
/.openclaw/.env |
AIzaSy…ZE2o |
✅ 正常 |
发现 memorySearch 配置不完整:
// 错误的配置 “memorySearch”: { “local”: {} },
发现根本原因:OpenClaw Gateway 的 LaunchAgent plist 文件中硬编码了错误的 API Key。
文件位置:
~/Library/LaunchAgents/ai.openclaw.gateway.plist
问题机制:
- 这个文件在 Gateway 首次启动时从环境变量读取并写入 API Key
- 之后不会自动更新,即使修改了 .env 文件
- Gateway 优先使用 plist 中硬编码的值
# 编辑 plist 文件 nano ~/Library/LaunchAgents/ai.openclaw.gateway.plist
或使用 plutil 命令
然后重启 Gateway:
openclaw gateway restart
“memorySearch”: { “remote”: {
"apiKey": "your_correct_api_key" } }
⚠️ 安全警告:硬编码 API Key 会导致密钥泄露风险,仅建议在测试环境使用。
- LaunchAgent plist 不会自动更新:这是最大的坑,需要手动维护
- 环境变量优先级:终端已设置的环境变量~/.openclaw/.env 文件openclaw.json 中的 env 部分Gateway LaunchAgent plist(优先级最高)
- ✅ 统一在 ~/.openclaw/.env 中管理所有 API Key
- ✅ 在 openclaw.json 中使用 ${VAR_NAME} 引用环境变量
- ✅ 定期检查 LaunchAgent plist 中的值是否与 .env 一致
- ✅ 建立操作约定:重启 Gateway 由人工执行,避免自动化操作
项目 |
限制 |
免费 tier |
每天 1000 次请求 |
计费规则 |
每次 embedding 请求计数 |
索引过程 |
每个 chunk = 1 次请求 |
查询过程 |
每次查询 = 1 次请求 |
优化建议:
- ✅ 启用缓存(已配置)
- ✅ 避免频繁手动 reindex
- ✅ 高使用量场景考虑切换到 Ollama(本地免费)
确保配置的模型名称与本地安装的一致:
# 查看本地已安装的模型 ollama list
输出示例:
NAME ID SIZE MODIFIED
nomic-embed-text:v1.5 0a109f422b47 274 MB 9 months ago
qwen2.5:7b 845dbda0ea48 4.7 GB 2 weeks ago
如果安装的是 nomic-embed-text:v1.5,配置中必须使用完整版本名:
“model”: “nomic-embed-text:v1.5”
Ollama 的 OpenAI 兼容接口 URL 是 http://127.0.0.1:11434/v1(注意末尾的 /v1):
“remote”: { “apiKey”: “ollama-local”, “baseUrl”: “http://127.0.0.1:11434/v1” }
# 测试 Ollama 是否正常响应 curl http://127.0.0.1:11434/v1/models
应该返回已安装的模型列表
- ❌ 不要将 API Key 提交到版本控制系统
- ❌ 不要在文档中暴露真实 API Key
- ✅ 使用环境变量或密钥管理服务
- ✅ 定期轮换 API Key
- ✅ Ollama 本地部署无需 API Key,更安全
推荐:每个 Agent 只索引自己的记忆,不配置 extraPaths
{ “agents”: {
"defaults": { "memorySearch": { "provider": "ollama", "model": "nomic-embed-text:v1.5", "remote": { "apiKey": "ollama-local", "baseUrl": "http://127.0.0.1:11434/v1" } } }
} }
优点:
- ✅ 配置简洁,无需维护路径列表
- ✅ 每个 Agent 独立管理自己的记忆
- ✅ 减少不必要的索引重复
- ✅ 降低 API 调用次数(避免重复 embedding)
何时需要配置 extraPaths:
- 需要跨 Agent 共享记忆时
- 需要索引工作区外的 Markdown 文件时
如果需要在 Ollama 和 Gemini 之间切换,只需修改 openclaw.json:
切换到 Ollama:
“memorySearch”: { “provider”: “openai”, “model”: “nomic-embed-text:v1.5”, “remote”: {
"apiKey": "ollama-local", "baseUrl": "http://127.0.0.1:11434/v1"
} }
切换到 Gemini:
“memorySearch”: { “provider”: “gemini”, “model”: “gemini-embedding-001”, “remote”: {
"apiKey": "${GEMINI_API_KEY}"
} }
修改后重启 Gateway 并重新索引:
openclaw gateway restart openclaw memory index –verbose
所有需要重启 OpenClaw 的操作都由用户(郑工)来执行
这是为了避免 Agent 自动执行破坏性操作,确保生产环境的安全性。
- ✅ 向量检索功能正常工作,能理解语义相似性
- ✅ 自动根据相关度排序结果
- ✅ 建立了清晰的操作约定,确保系统安全
- ✅ 发现了 LaunchAgent plist 不会自动更新的坑
- ✅ 已移除不必要的 extraPaths 配置
- ✅ 每个 Agent 独立索引自己的记忆
- ✅ 降低 API 调用次数,避免重复 embedding
- ✅ 已切换到 Ollama 本地 embedding(完全免费)
特性 |
Gemini |
Ollama(本地) |
推荐场景 |
费用 |
免费 1000 次/天 |
✅ 完全免费 |
Ollama |
网络 |
需要翻墙 |
✅ 本地访问 |
Ollama |
隐私 |
数据发送到 Google |
✅ 数据不出本地 |
Ollama |
速度 |
依赖网络 |
✅ 本地推理 |
Ollama |
配额 |
有限制 |
✅ 无限制 |
Ollama |
配置难度 |
✅ 简单 |
中等 |
Gemini |
维护成本 |
需管理 API Key |
✅ 无需维护 |
Ollama |
推荐:
- 日常使用:Ollama(免费、本地、无限制)
- 备用方案:Gemini(云端、应急使用)
- ✅ 已切换到 Ollama,无需监控 API 配额
- 根据需要调整 hybrid search 参数(vectorWeight, textWeight 等)
- 考虑在内存受限场景下优化 embedding 缓存策略
为了解决”手动记忆”需要主动记录的问题,建立了多层保障机制:
memory-core 是”手动记忆”插件,需要 Agent 主动调用工具写入记忆文件。这导致:
- ❌ 容易遗漏重要工作内容
- ❌ 依赖 Agent 自律或用户提醒
- ❌ 记忆更新不及时
┌─────────────────────────────────────┐ │ Cron 定时任务(每天 23:00) │ ← 保底机制 │ 即使忘记记录,也会自动总结 │ ├─────────────────────────────────────┤ │ AGENTS.md 行为规范 │ ← 主要机制 │ 会话结束前必须总结并记录 │ │ 重要阶段完成后立即记录 │ ├─────────────────────────────────────┤ │ HEARTBEAT 检查(每 4 小时) │ ← 补充机制 │ 检查记忆是否及时更新 │ │ 如超过 4 小时未更新,主动询问 │ ├─────────────────────────────────────┤ │ 用户手动触发 │ ← 直接方式 │ 在会话中直接要求 Agent 更新记忆 │ └─────────────────────────────────────┘
使用 openclaw cron add 命令创建定时任务(推荐方式,你可以让你的agent去创建):
# 为 main Agent 创建每日记忆总结任务 openclaw cron add
–name main-daily-memory
–cron “0 23 * * *”
–agent main
–message “请总结今天的工作内容,更新到 memory/YYYY-MM-DD.md 文件中。包括:1.完成的任务 2.解决的问题 3.技术决策 4.配置变更”
–description “Main Agent 每日记忆总结”
为 zhengxiaobian Agent 创建每日记忆总结任务
为 fullstack-dev Agent 创建每日记忆总结任务
命令参数说明:
- –name
: 任务名称(唯一标识) - –cron
: Cron 表达式(5 字段或 6 字段,支持秒) - –agent
: 指定执行记忆的 Agent - –message
: Agent 消息内容 - –description
: 任务描述(可选)
常用 Cron 表达式:
- 0 23 * * * - 每天 23:00 执行
- 0 9 * * 1-5 - 工作日 9:00 执行
- 0 */4 * * * - 每 4 小时执行
- 0 0 * * 0 - 每周日 0:00 执行
管理命令:
# 查看已创建的定时任务 openclaw cron list
查看任务状态
openclaw cron status
手动触发任务(测试用)
openclaw cron run
禁用任务
openclaw cron disable
启用任务
openclaw cron enable
删除任务
openclaw cron rm
优点:
- ✅ 无需编辑配置文件
- ✅ 即时生效,无需重启 Gateway
- ✅ 可以动态管理(启用/禁用/删除)
- ✅ 有完整的任务历史和状态追踪
在每个工作区的 AGENTS.md 中添加记忆更新规范:
记忆更新规范 必须记录的场景
以下情况必须立即更新记忆文件:
- ✅ 完成重要功能开发
- ✅ 解决关键技术问题
- ✅ 做出重要技术决策
- ✅ 配置发生重大变更
- ✅ 会话结束前(总结本次会话)
记录格式
”`markdown
{时间} {工作内容}
背景
{为什么做这件事}
过程
{实施步骤}
结果
{最终结果}
注意事项
{需要注意的点}
- Cron 任务:每天 23:00 自动检查并总结当天工作
- 会话结束:必须总结并记录到 memory/YYYY-MM-DD.md
- HEARTBEAT:每 4 小时检查一次记忆更新状态
- 及时性 - 重要工作完成后立即记录,不要等待
- 准确性 - 记录真实的工作内容和结果
- 完整性 - 包括背景、过程、结果、注意事项
- 可追溯 - 记录关键配置、命令、决策原因
更新的工作区:
~/.openclaw/workspace/AGENTS.md(main Agent)~/.openclaw/workspace-xiaobian/AGENTS.md(zhengxiaobian Agent)~/.openclaw/workspace-fullstack/AGENTS.md(fullstack-dev Agent)
方案 3:HEARTBEAT 定期检查(补充)
在每个工作区的 HEARTBEAT.md 中添加记忆检查清单:
”`markdown
HEARTBEAT.md - 定期检查清单
记忆更新检查
检查今天的记忆文件是否及时更新:
- 读取今天的
memory/YYYY-MM-DD.md文件 - 检查最后更新时间
- 如果超过 4 小时未更新:
- 主动询问用户是否有工作需要记录
- 如果有,总结并写入记忆文件
- 如果无工作,跳过
检查频率
工作时间(09:00-23:00):每 4 小时检查一次 非工作时间:跳过(除非紧急)
更新的工作区:
- /.openclaw/workspace/HEARTBEAT.md
- /.openclaw/workspace-xiaobian/HEARTBEAT.md
- ~/.openclaw/workspace-fullstack/HEARTBEAT.md
用户在会话中直接要求 Agent 更新记忆:
用户:请总结一下今天的工作,更新到记忆文件 Agent:好的,让我总结一下今天的工作… [总结完成的工作] 现在我将更新记忆文件... [调用 edit 工具写入 memory/YYYY-MM-DD.md] ✅ 已记录到记忆文件 优点:
- ✅ 简单直接,无需配置
- ✅ 用户可控,按需触发
- ✅ 可以指定记录内容
缺点:
- ❌ 依赖用户主动提醒
- ❌ 容易忘记执行
适用场景:
- 临时需要更新记忆
- 重要工作完成后立即要求记录
- 会话结束前要求总结
{ “agents”: { "defaults": { "memorySearch": { "provider": "openai", "model": "nomic-embed-text:v1.5", "remote": { "apiKey": "ollama-local", "baseUrl": "http://127.0.0.1:11434/v1" } } } } }
前置条件:
# 安装 Ollama brew install ollama 启动服务
ollama serve
下载模型
ollama pull nomic-embed-text
验证服务
curl http://127.0.0.1:11434/v1/models
{ “agents”: { "defaults": { "memorySearch": { "provider": "gemini", "model": "gemini-embedding-001", "remote": { "apiKey": "${GEMINI_API_KEY}" } } } } }
前置条件:
# 在 ~/.openclaw/.env 中配置 API Key echo “GEMINI_API_KEY=your_api_key_here” >> ~/.openclaw/.env
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/232422.html