关键词:混合检索|向量数据库|SQLite FTS5|ONNX 嵌入|相似度归一化|候选重排序
在上一篇中,我们了解了 OpenClaw 记忆系统的配置体系。但配置只是“蓝图”,真正的挑战在于如何高效、准确、低延迟地执行检索。尤其当系统需同时处理:
单一检索策略往往力不从心。为此,OpenClaw 构建了一套轻量但强大的混合检索引擎(Hybrid Search Engine),巧妙结合向量语义搜索与全文关键词匹配,在资源受限的边缘设备(如个人服务器)上也能提供接近商业 RAG 系统的体验。
本文将从数据管道、索引构建、查询执行到结果融合,完整拆解这一引擎的实现细节。

OpenClaw 默认采用 70% 向量 + 30% 全文 的加权融合,经大量测试验证为最佳平衡点。
OpenClaw 不依赖外部向量数据库(如 Pinecone、Weaviate),而是基于 SQLite 构建一体化存储:

vector 扩展支持浮点数组这使得 OpenClaw 可在树莓派、NAS 或个人 Mac 上运行完整 RAG。
支持格式:.txt, .md, .pdf, .docx, .html
使用工具链:
pdf-parse:提取 PDF 文本mammoth:解析 Word分块策略:
source: "hr-policies.md", chunk_index: 3OpenClaw 支持三种嵌入后端:

默认优先使用本地 ONNX 模型,保障隐私与离线可用性。
每块文本生成 384 维向量(bge-small),存入 SQLite 表:
CREATE TABLE memory_chunks (
id TEXT PRIMARY KEY,
agent_id TEXT,
session_key TEXT,
source TEXT,
content TEXT,
embedding BLOB, -- FLOAT32 数组序列化
created_at INTEGER
);
-- 创建向量索引(使用 sqlite-vector 扩展)
CREATE INDEX idx_embedding ON memory_chunks(embedding)
USING vector(dim=384, metric='cosine');同时,为 content 字段创建 FTS5 虚拟表:
CREATE VIRTUAL TABLE memory_fts USING fts5(
content,
chunk_id UNINDEXED,
tokenize = "porter unicode61"
);同一份数据,双索引并存。
当用户提问 “上次提到的 API 密钥怎么重置?”,系统执行:
q_vecSELECT id, content, distance
FROM memory_chunks
WHERE agent_id = 'dev-assistant'
ORDER BY vector_distance(embedding, ?) ASC
LIMIT 15; -- 候选数 = maxResults × candidateMultiplierSELECT chunk_id, content, rank
FROM memory_fts
WHERE content MATCH 'API 密钥 重置'
ORDER BY rank
LIMIT 15;rank 值越小越相关⚡ 两路查询并发执行,总耗时 ≈ max(向量耗时, 全文耗时)
这是混合检索的核心——如何公平比较两个不同尺度的分数?
[0, 2] → 转为相似度 sim = 1 - distance/2 → 归一化到 [0,1]rank 是负对数概率 → 通过 sigmoid 映射到 [0,1]function normalizeVectorScore(distance: number): number {
return Math.max(0, 1 - distance / 2);
}
function normalizeTextScore(rank: number): number {
// rank 越小越好,典型值 -10 ~ -1000
return 1 / (1 + Math.exp(rank / 100)); // sigmoid 缩放
}const finalScore =
normalizedVectorScore * config.vectorWeight +
normalizedTextScore * config.textWeight;chunk_id 去重finalScore 降序排序融合不是简单相加,而是语义与关键词的协同投票。
sqlite-vector 的 HNSW 近似索引(非暴力扫描)// 不阻塞主推理流程
if (!indexExists(agentId)) {
spawnBackgroundIndexer(agentId);
return []; // 首次查询无记忆
}实测:在 M1 MacBook 上,1000 个 chunk 的混合检索 < 300ms。

可通过智能体配置动态调整:
# agents/legal-assistant/config.yaml
memory:
vectorWeight: 0.35
textWeight: 0.65
minSimilarity: 0.4 # 提高阈值,过滤模糊匹配当前 OpenClaw 的混合检索聚焦文本,但架构已预留扩展点:
记忆系统正从“静态知识库”走向“动态感知中枢”。
OpenClaw 的混合检索引擎,没有追求最前沿的 ANN 算法或最大规模的向量库,而是在实用性、性能与准确性之间找到最优解。它证明了:即使在资源有限的环境中,通过精心设计的数据流与融合策略,依然能构建出可靠、高效、可解释的 RAG 系统。
这正是工业级 AI 工程的核心精神——不炫技,只解决问题。
在下一篇中,我们将探讨长期记忆的持久化机制:如何让 AI “记住”跨天、跨设备的对话。
下一篇预告: 第 9 篇:长期记忆与会话同步 —— 如何让 AI “记住”跨天对话