OpenClaw 记忆搜索(Memory Search)完全指南:混合检索、Embedding 供应商与排序调优
2026/9/15 14:03:33 网站建设 项目流程

OpenClaw 记忆搜索(Memory Search)完全指南:混合检索、Embedding 供应商与排序调优

【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw

OpenClaw 的memory_search工具能够在记忆文件中找到与当前问题语义相关的笔记,即使查询措辞与原文完全不同。其核心是"混合检索":向量语义检索负责"意思相近",BM25 关键词检索负责"字面精确",两者并行、合并、再经确定性排序与多样性重排后返回结果。本文以 docs/concepts/memory-search.md 为主体,结合 memory-core 扩展 的源码实现与 Memory 配置参考,完整讲解供应商选择、检索原理、排序机制(recency / importance / MMR)、多模态索引、会话记忆检索与常见故障排查,帮助你在实际部署中把记忆召回质量调到最优。

Quick start:一分钟切换到目标 Embedding 供应商

OpenClaw 默认使用 OpenAI 的 Embedding。若OPENAI_API_KEYmodels.providers.openai.apiKey已配置,向量检索开箱即用。需要切换供应商时,在openclaw.json中显式指定memory.search.provider

{ memory: { search: { provider: "openai", // 或 "gemini"、"voyage"、"mistral"、"bedrock"、"local"、"ollama"、"lmstudio"、"github-copilot"、"openai-compatible" }, }, }

几点关键说明:

  • provider支持自定义 provider id:可以引用models.providers.<id>中的条目(例如ollama-5080),只要该条目的api指向"ollama"或其它带有 memory embedding 适配器的 provider id。这允许在多 GPU / 多主机场景下把记忆向量化固定到某个本地端点,完整示例见 Memory 配置参考 - Custom provider ids。
  • 本地 Embedding(无需 API Key):安装并配置官方 llama.cpp provider 后,设置provider: "local"
openclaw plugins install @openclaw/llama-cpp-provider

在交互式安装中为 llama.cpp 选择一次即可。OpenClaw 会安装经校验的llama-server、自动下载 Embedding GGUF 模型(默认embeddinggemma-300m-qat-Q8_0.gguf,约 0.3 GB),并写入其托管服务配置。默认模型路径见 memory-builtin 文档 中的local.modelPath示例。

  • 非对称 Embedding 端点:部分 OpenAI 兼容端点要求区分input_type标签——查询用"query",索引块用"document"/"passage"。通过queryInputTypedocumentInputType配置,详见 Memory 配置参考 - Provider-specific config。

支持的 Embedding 供应商一览

下表汇总了 memory-search.md 中列出的全部供应商。默认模型列补充自 Memory 配置参考 与 memory-builtin.md:

ProviderID需要 API Key说明
Bedrockbedrock走 AWS 凭证链,无明文密钥
DeepInfradeepinfra默认模型BAAI/bge-m3
Geminigemini支持图片 / 音频索引(多模态)
GitHub Copilotgithub-copilot使用你的 Copilot 订阅
Locallocal托管 llama.cpp GGUF,约 0.3 GB
LM Studiolmstudio本地 / 自托管服务器
Mistralmistral默认模型mistral-embed
Ollamaollama本地 / 自托管服务器
OpenAIopenai默认,模型text-embedding-3-small
OpenAI-compatibleopenai-compatible通常需要通用/v1/embeddings端点
Voyagevoyage默认模型voyage-4-large

各远程供应商的 API Key 解析方式(环境变量 / 配置键)在 Memory 配置参考 - API key resolution 有完整表格;Bedrock 走 AWS SDK 默认凭证链(实例角色、SSO、访问密钥或 Bedrock API key)。注意:Codex OAuth 仅覆盖聊天 / 补全,不满足 Embedding 请求。

检索如何工作:两条检索路径并行 + 确定性排序

OpenClaw 并行运行两条检索路径,再合并结果,流程如下:

  • 向量检索(Vector search):匹配语义相近的内容,例如查询 "gateway host" 能命中 "the machine running OpenClaw"。
  • BM25 关键词检索:匹配精确词条,例如 ID、错误字符串、配置键。
  • 文件名检索:路径与正文分开索引。完整路径、basename、文件名词干排在部分路径匹配之前;而摘要与正文关键词分数仍来自笔记内容本身。

若只有一条路径可用(例如未配置 Embedding 供应商或 FTS 不可用),则另一条单独运行。从 manager-search-orchestration.ts 的源码看,当keywordOnly(无 provider 或显式lexicalOnly)时直接走关键词检索;当hybrid.enabled且 FTS 与 provider 均可用时才进入合并流程。

内置引擎随后应用确定性排序公式:

hybrid relevance × recency decay × importance multiplier

合并与选择:源码视角

真正的合并逻辑在 hybrid.ts 的mergeHybridResults:向量与关键词结果按 chunk id 归并,分别累计vectorScore/textScore,再按vectorWeighttextWeight加权得到contentScore;随后依次执行时间衰减、importance 乘数、项目亲和度排序,再按exactPathSpecificity(0–3,路径精确度分级)分档,对非精确命中应用 MMR。最终由selectHybridSearchResults(hybrid.ts#L319-L359)按minScore阈值筛选并截取maxResults条:

  • 所有得分低于配置阈值的加权结果被过滤,但关键词命中的候选可以回填剩余结果位keyword-only回退);
  • 当全部排名结果都低于最低分时,检索仍会保留关键词匹配;
  • 这些规则同样适用于项目会话(project sessions),纯语义命中仍需达到配置的最低分。

Importance 乘数:写入时的一次性打分

Importance 在记忆条目写入时由"已有模型参与"的记忆工作流打分一次,属于可空字段。缺失的 importance 是中性值(乘数为 1),因此旧索引保持原有的相关性信号。实现位于 importance.ts:bounded = clamp(floor(importance), 1, 10),乘数0.75 + bounded * 0.05,即重要性 1 对应 0.8 倍、重要性 10 对应 1.25 倍。

该"相关性 × 时效性 × 重要性"的设计遵循 Generative Agents 研究(arXiv:2304.03442)的结论,但不引入查询时的模型调用,保持确定性、低延迟。

MMR:只做多样性重排,不改分、不设阈值

MMR(Maximal Marginal Relevance)对混合候选集重排,减少冗余摘要:如果五条笔记都提到同一份路由器配置,MMR 倾向于换入一条相关但内容不同的结果。实现见 mmr.ts,核心公式为:

MMR = λ × relevance − (1 − λ) × max_similarity_to_selected
  • 默认固定 λ =0.7(偏向相关性),Jaccard 相似度基于摘要 token 重叠;
  • 本地计算复杂度为O(k²):默认每条检索腿请求 200 个候选(常量SEARCH_CANDIDATE_UNIVERSE = 200,见 manager-search-orchestration.ts#L36),去重后最多 400 个非精确候选参与重叠计算;更宽的项目与标识符搜索另有独立上限;
  • MMR不改变分数、不改变阈值资格、不发起额外的 provider 调用
  • FTS-only 与 vector-only 回退路径不执行混合 MMR 通道,因此无需任何配置。

确定性触发召回(Deterministic trigger recall)

在符合条件的交互轮次中,内置引擎会把入站消息与已索引条目上存储的短触发短语(triggers)比对。强匹配可在回复前向隐藏上下文注入最多三条紧凑记忆。预过滤复用现有的关键词与向量检索路径,不运行召回模型

自动注入比memory_search刻意更窄:只有被提升(promoted)、可信(trusted)的条目才合格。在索引 provenance(来源溯源)可用之前,这意味着只有根目录MEMORY.mdUSER.md中的条目会参与自动注入。每日笔记、导入的转录与会话转录仍可通过显式记忆工具或 Active Memory 升级访问,但永远不会被自动注入。相关配置见 Memory 配置参考 - Hybrid search config。

FTS-only 模式与显式 provider 不可用时的行为

  • FTS-only 模式:设置provider: "none"可刻意禁用 Embedding,仅用关键词检索。provider未设置或为"auto"(legacy 配置,现在解析为openai)时,若 Embedding 初始化或请求失败,会回退到关键词排序;provider: "local"(GGUF / llama.cpp)同样如此。创建时的回退仍会为关键词检索索引文本——包括首次搜索前的手动与后台索引。memory_search即使无匹配结果,也会在debug.embeddingBootstrap中返回脱敏后的 Embedding 引导原因。
  • 显式 provider 不可用:若你显式命名其它供应商(如openaiollamagemini)且它在请求时不可用(认证失败、网络故障),memory_search会报告"记忆不可用",而不是静默降级为 FTS-only 结果——让坏掉的配置暴露出来。需要刻意 FTS-only 就设provider: "none",否则修复 provider / 认证配置以恢复语义排序。

提升搜索质量:Recency 衰减与 MMR

混合检索默认开启两趟确定性排序。

Recency 衰减(时间衰减)

旧笔记逐渐降低排名权重,让近期信息优先浮现。默认 30 天半衰期:一个月前的笔记得分衰减为原始的 50%。公式与判定逻辑在 temporal-decay.ts:

score × exp(−(ln2 / halfLifeDays) × ageInDays)
  • 常青(evergreen)文件不衰减MEMORY.mdUSER.md,以及memory/下无日期的文件。
  • 带日期的YYYY-MM-DD.mdYYYY-MM-DD-<slug>.md在任何目录深度都衰减,包括会话记忆笔记与嵌套的 dreaming 报告。路径正则DATED_MEMORY_PATH_RE(temporal-decay.ts#L15)支持memory/dreaming/light/2025-01-01.md这类嵌套路径,也兼容 Windows 风格分隔符(见 temporal-decay.test.ts 的测试用例)。
  • 时间戳来源:会话转录命中使用索引时捕获的源活动时间戳;保留的转录档案使用其被索引时的文件修改时间。单条消息时间戳仍是 provenance 元数据,不决定源的 recency 权重。extraPaths下的普通文件则取文件 mtime(测试覆盖见 temporal-decay.test.ts#L206-L222)。

MMR(多样性重排)

如前述,MMR 在混合排序后对候选重排,减少近重复摘要。默认启用、λ=0.7,无需配置;FTS-only 与 vector-only 回退路径不运行混合 MMR。

多模态记忆:用 Gemini 索引图片与音频

使用gemini-embedding-2时,可以在 Markdown 之外一并索引图片与音频。注意以下几点约束:

  • 仅作用于memory.search.extraPaths下的文件;默认记忆根(MEMORY.mdmemory/*.md)保持纯 Markdown;
  • 查询仍为文本,但会与视觉和音频内容匹配;
  • 配置项:multimodal.enabled(默认false)、multimodal.modalities["image"]["audio"]["all"])、multimodal.maxFileBytes(默认 10485760,即 10 MiB),并要求fallback: "none"
  • 支持格式:图片.jpg.jpeg.png;音频.mp3.wav
  • 完整设置见 Memory 配置参考 - Multimodal memory。

会话记忆搜索(Session memory search)

需要从会话转录中做精确全文召回时,优先使用sessions_search定位,再用sessions_history打开结果。memory_search的会话检索是语义化、实验性的补充。

开启会话转录索引

这是 opt-in 功能:设置experimental.sessionMemory: true,并向sources添加"sessions"(默认sources["memory"]):

{ memory: { search: { experimental: { sessionMemory: true }, sources: ["memory", "sessions"], }, }, }
  • 使用corpus: "memory"可只搜记忆笔记;若结果不含会话转录,则不加载会话历史、不做会话可见性查询。
  • 会话命中遵循tools.sessions.visibility(默认"all")。memory_search仍只检索当前所选 agent 的已索引语料;跨 agent 的转录检索请用 Gateway 上的sessions_search
  • 跨 agent 会话访问默认开启,由tools.agentToAgent管理:设enabled: false阻止普通跨 agent 访问(请求方自有的原生子 agent 与 ACP 子会话在treeall下仍可达),或用allow限制 agent 对。
  • 每个对端可设置session.dmScope隔离 DM 上下文,但这不限制通过会话工具读取转录。选择显式"agent"(同 agent 召回)、"tree"(当前 + 衍生范围,main 有 agent 级例外)、或"self"(严格当前会话召回)。沙箱 spawn-only 钳制与 incognito 排除仍然生效。
  • 会话索引是异步且 opt-in 的,结果可能略微滞后;配置细节与排除规则见 Memory 配置参考 - Session memory search。

相关配置项速查

配置键类型默认说明
rememberAcrossConversationsboolean个人安装开启;配置 DM 隔离后关闭允许私密跨会话召回
experimental.sessionMemorybooleanfalse开启会话转录索引
sourcesstring[]["memory"]加入"sessions"以包含转录

注意:内部 dreaming 叙事、cron 与 heartbeat 会话转录不会被索引(包括其保留的压缩叙事归档);被openclaw memory forget清除的会话也会被持久排除,即使源转录仍留在会话存储中。

故障排查(Troubleshooting)

对应 memory-search.md 与 cli/memory.md 中的命令,逐项排查:

症状排查动作
无结果openclaw memory status检查索引;为空则openclaw memory index --force
只有关键词匹配可能未配置 Embedding 供应商;用openclaw memory status --deep探测
本地 Embedding 超时ollamalmstudiolocal使用更长的 provider 自有批量截止时间;先openclaw memory status --deep检查托管服务器端点再重建索引
CJK 文本搜不到openclaw memory index --force重建 FTS 索引

memory status相关参数:--deep探测向量存储、Embedding 供应商与语义搜索就绪状态(会发起额外 provider 调用);--index检查并可重建不兼容索引;--fix修复可自动修复的问题;--json输出结构化结果。更换 Embedding 供应商 / 模型 / 相关设置会改变索引身份(index identity),OpenClaw 会暂停向量搜索并提示,直到你用openclaw memory index --force --agent <id>显式重建。

索引重建注意事项

  • 索引与其它 agent 状态(会话、转录)共享~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite切勿删除该数据库或其-wal-shm-journal边车文件来重置记忆
  • 需要清空派生索引与 Embedding 缓存时,使用openclaw memory reset --agent <id>(加--yes跳过确认),随后openclaw memory index --agent <id>
  • 若要回收磁盘空间,可对 agent 数据库执行openclaw doctor --session-sqlite compact --session-sqlite-agent <id>,详见 memory-builtin.md 的 "Reclaim disk space" 章节。

进一步阅读

  • Memory overview:记忆文件体系(USER.md/MEMORY.md/memory/*.md)与记忆工具
  • Memory architecture:存储、索引与检索层
  • Builtin memory engine:默认 SQLite 后端,chunk 默认 400 token / 80 token 重叠,文件监听 1.5s 防抖重索引
  • Active memory:交互会话的子 agent 记忆
  • Memory configuration reference:全部配置旋钮(查询限额、extraPaths、Embedding 缓存、批量索引、sqlite-vec、FTS tokenizer 等)
  • Memory LanceDB:基于 LanceDB 的记忆插件(若使用替代记忆引擎)
  • CLI: openclaw memory:memory status/index/reset/search命令参考

如需深入源码:混合合并与选择逻辑在 hybrid.ts,时间衰减在 temporal-decay.ts,MMR 在 mmr.ts,importance 乘数在 importance.ts,搜索编排在 manager-search-orchestration.ts,行为均有对应测试(如 temporal-decay.test.ts)可对照验证。

【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询