/usr/lib/node_modules/openclaw/docs/concepts/memory.md(主要来源,内容完整)/usr/lib/node_modules/openclaw/docs/gateway/configuration-examples.md/usr/lib/node_modules/openclaw/dist/manager-CsIZJ7mU.js(验证 HTTP 格式)agents.defaults.memorySearch 完整 Schemaagents: {
defaults: {
memorySearch: {
// 必填:选择 embedding provider
provider: "openai" | "gemini" | "voyage" | "local" | "auto",
// 指定 embedding 模型名
// openai 默认: "text-embedding-3-small"
// gemini 默认: "gemini-embedding-001"
// voyage 默认: "voyage-4-large"
model: "text-embedding-3-small",
// 远程 provider 配置(openai/gemini/voyage/自定义兼容端点均用此字段)
remote: {
baseUrl: "http://127.0.0.1:8765/v1", // 自定义端点
apiKey: "YOUR_KEY_OR_EMPTY_STRING", // 无认证时传空字符串或省略
headers: { // 可选额外 header
"X-Custom-Header": "value"
},
// Batch 索引配置(大语料库用)
batch: {
enabled: false, // 默认关闭
concurrency: 2, // 并行 batch 数
wait: true, // 等待 batch 完成
pollIntervalMs: 5000,
timeoutMinutes: 60
}
},
// 本地 GGUF 模型配置(provider="local" 时使用)
local: {
modelPath: "/path/to/model.gguf", // 或 "hf:org/repo/file.gguf"
modelCacheDir: "/path/to/cache"
},
// Fallback provider(主 provider 失败时切换)
fallback: "openai" | "gemini" | "local" | "none",
// 额外索引路径(workspace 外的 .md 文件)
extraPaths: ["../team-docs", "/srv/shared-notes/overview.md"],
// 索引存储位置
store: {
path: "~/.openclaw/memory/{agentId}.sqlite",
vector: {
enabled: true,
extensionPath: "/path/to/sqlite-vec" // 可选,覆盖内置路径
}
},
// 混合搜索配置(BM25 + Vector)
query: {
hybrid: {
enabled: true,
vectorWeight: 0.7,
textWeight: 0.3,
candidateMultiplier: 4,
mmr: {
enabled: false, // MMR 去重
lambda: 0.7
},
temporalDecay: {
enabled: false, // 时间衰减
halfLifeDays: 30
}
}
},
// Session transcript 索引(实验性)
experimental: { sessionMemory: true },
sources: ["memory", "sessions"],
// 同步配置
sync: {
watch: true, // 文件变更自动重索引
sessions: {
deltaBytes: 100000,
deltaMessages: 50
}
},
// 嵌入缓存
cache: {
enabled: true,
maxEntries: 50000
}
}
}
}
向量搜索(semantic),不是纯文本搜索。
- 默认使用 Hybrid Search(BM25 + Vector 加权合并),在 FTS5 可用时自动开启
- 纯 BM25 full-text 作为 vector 不可用时的兜底,但不是主模式
MEMORY.md + memory/**/*.md(Markdown only)完全替换内置搜索的 embedding 生成部分(不并存):
- 文件分块 → 调用外部 embedding 服务 → 存入本地 SQLite → BM25+Vector 混合检索
- 外部服务只负责生成向量,检索逻辑仍在 OpenClaw 本地执行
有,通过 memorySearch.fallback 配置:
- 主 provider 失败 → 自动切换到 fallback provider(如 "local" 或 "openai")
- 若 fallback = "none" 则失败后直接禁用向量搜索,降级为 BM25 only
- QMD backend 失败 → 自动回退到内置 SQLite manager
OpenClaw 的 provider: "openai" 使用标准 OpenAI Embeddings API 格式(源码确认):
POST {baseUrl}/embeddings
Content-Type: application/json
Authorization: Bearer {apiKey}
{...custom headers}
{
"model": "your-model-name",
"input": ["text chunk 1", "text chunk 2", ...] // 批量时是数组;单个查询是 ["query text"]
}
关键:input 字段是字符串数组,不是单个字符串。
{
"data": [
{ "embedding": [0.123, -0.456, ...] }, // float 数组,第一个元素对应 input[0]
{ "embedding": [0.789, 0.012, ...] } // 第二个元素对应 input[1]
]
}
源码验证(manager-CsIZJ7mU.js):
return ((await res.json()).data ?? []).map((entry) => entry.embedding ?? []);
URL 构造方式(源码):
const url = `${client.baseUrl.replace(/\/$/, "")}/embeddings`;
即 baseUrl = "http://127.0.0.1:8765/v1" → 请求 http://127.0.0.1:8765/v1/embeddings
OpenClaw 原生支持自定义 OpenAI-compat embedding 端点,无需任何 hack。
配置:
agents: {
defaults: {
memorySearch: {
provider: "openai",
model: "Qwen3-Embedding-0.6B", // 模型名会原样传给你的 server
remote: {
baseUrl: "http://127.0.0.1:8765/v1",
apiKey: "" // 无认证,传空字符串
},
fallback: "none" // 本地服务挂了就禁用,不 fallback 到云端
}
}
}
你的 embed server 需要实现的接口:
POST /v1/embeddings
Content-Type: application/json
{
"model": "Qwen3-Embedding-0.6B",
"input": ["text1", "text2", ...]
}
→ 响应:
{
"data": [
{"embedding": [0.1, 0.2, ...]},
{"embedding": [0.3, 0.4, ...]}
]
}
注意:你草案的 POST /search {text, top_k} 格式不匹配 OpenClaw 期望的格式——需要改为 /v1/embeddings 端点,输出向量而非搜索结果。检索逻辑由 OpenClaw 自己做。
所有 agent(main/coder/reviewer/researcher)的 agents.defaults.memorySearch 配置相同,共用同一个 http://127.0.0.1:8765/v1 服务即可。每个 agent 的向量索引仍然是独立的 SQLite 文件(~/.openclaw/memory/{agentId}.sqlite)。
remote.apiKey = "" 即可,源码中 Authorization: Bearer 会被发送但 FastAPI 端忽略即可。
如果你想要更高级的混合搜索(BM25 + reranking),可以考虑 memory.backend = "qmd":
- 安装独立 QMD CLI
- 但 QMD 不支持接入外部 embedding server,需要本地 GGUF
- 对于你的 usearch + Qwen3 方案,不推荐,直接用 provider: "openai" compat 更简洁
| 问题 | 结论 |
|---|---|
| Q1 schema | 见上文完整字段表;核心:provider/model/remote.baseUrl/remote.apiKey |
| Q2 工作机制 | 向量搜索(hybrid BM25+vector),外部 provider 完全替换 embedding 生成,检索本地执行 |
| Q3 HTTP 格式 | POST {baseUrl}/embeddings,body {model, input: string[]},响应 {data: [{embedding: float[]}]} |
| Q4 替代方案 | 不需要替代——OpenClaw 原生支持 OpenAI-compat endpoint,修改 embed server 接口即可 |
关键改动:embed server 不需要做搜索,只需暴露 /v1/embeddings 端点返回向量,OpenClaw 自己做 usearch。但如果想保留自己的 usearch,则需要另一个路径(见下)。
⚠️ 如果主人希望让 OpenClaw 完全使用外部的 usearch 检索结果(而非只用外部 embedding),目前没有直接支持——OpenClaw 只能外包 embedding 生成,检索逻辑自己做。这种情况需要考虑 MCP tool override 方案,或通过 mcporter 暴露自定义
memory_search工具。