为什么只靠向量搜索,做不好个人 AI 知识库?——RecalAI 混合检索工程实践

市面上已有完整的 Hybrid Search 示例:例如 Vannevar 公开了面向 Markdown 的 FTS5、向量和加权 RRF 方案;Swift 生态的 SearchKit 也提供向量与 BM25/RRF 的端侧检索模式。这意味着,仅解释"关键词和向量需要结合",并不能构成 XBSTACK 新文章的独立价值。本文的差异是以 RecalAI iOS 真实检索实现为依据 ,解释为什么它额外加入 Anchor、严格/宽松词法分支、轻量规则重排、证据分配与引用 ID 检查,以及这种设计哪些地方仍待实验。外部参考:Vannevar 的本地检索设计、SearchKit on-device RAG。

先回答问题:向量检索不是知识库的全部

把 PDF、Word、图片和笔记送入 Embedding 模型,再把查询向量与文本块做相似度匹配,看似已具备"个人知识库"。但用户真正要的往往不是一段语义相近的话,而是找回那一份资料中的准确事实、版本号、金额、专有名词和可打开的来源位置。语义接近不等于事实相同;向量相似度高,也不代表片段足以回答问题。

这就是 RecalAI 所采用的本地优先思路:先保存原件、解析并建立全文检索,使资料尽早可找;后台完成 Embedding 等增强;提问时结合全文和语义候选,融合、去重、重排,再选出有证据的片段给模型。这是架构路径,不是"混合检索一定比单路检索快或准"的未经测试的结论。

相关背景可先阅读 Personal AI Agent 架构 和 Agent Memory 系统设计。前者解释身份、记忆、执行权限和端云边界;本文只聚焦一个更窄的问题:一份私人资料,如何从"被导入"变成"能够被可靠引用"?

第一关:导入完成与能回答,不是同一件事

在个人知识库中,至少有四个应被分离的状态:

  1. 原件已保存:文件可恢复、可预览;这不等于文字已经可检索。
  2. 解析和全文索引完成:提取的文字已进入 FTS 索引,可以按词检索;图片型扫描件可能需要 OCR,解析失败必须单独报告。
  3. 语义增强完成:分块 Embedding、标签与摘要等后台任务已经完成;缺失或失败时不应假装具备语义召回。
  4. 有证据的问答已就绪:当前知识范围、召回、证据预算与生成结果通过引用校验;找不到足够证据时应回答"当前资料不足"。

这套顺序的意义是把耗时工作移到后台,又不让用户在导入后长期面对一个只能转圈的空资料库。代价是状态管理更复杂:一个文件可以"全文可搜、语义增强进行中";界面和检索器必须使用同一种真实状态,不能误报"AI 已理解全部内容"。

待核证据:RecalAI 各平台当前代码中的导入状态字段、失败重试策略、任务中断恢复及资料库重启后的可见性;未经该检查,不应宣称所有端都实现一致。

第二关:FTS 解决精确命中,向量检索解决不同表达

假设某份资料明确写着 LFM2.5-2.6B-Q4_K_M,用户要查这个模型的兼容性。用户可能直接输入完整型号,也可能问"那个小一点的端侧模型能不能在旧手机运行"。

第一类查询包含准确字符串。全文检索通常更适合保留型号、错误码、接口名、路径和引用原文的能力;第二类查询表达不一样,语义检索可以帮助找到意义相关的段落。两者各有盲区:全文索引受分词、语言、拼写变体影响;Embedding 受模型、语言、切块策略和相似度阈值影响。尤其涉及否定、数字、权限范围与版本差异时,语义相近可能导致严重误判。

SQLite FTS5 官方文档提供 bm25()、snippet() 与 highlight() 等能力;其中 FTS5 的 BM25 分数通常按数值越小越相关来排序,与很多应用对"高分更好"的直觉相反。具体是否使用 SQLite FTS5、采用何种 tokenizer 和字段权重,必须以目标平台真实实现为准。

建议根据实际问题做一张双路召回对照表:

查询任务 全文检索常见优势 语义检索潜在优势 风险
精确模型名、报错和函数签名 字符串定位 同义上下文 型号误匹配
"哪篇笔记讨论过端云取舍?" 关键词索引 意图与近义表达 泛段落压过关键段
具体日期、金额、版本差异 可精确引用 辅助发现描述 数字和否定语义混淆
多语言提问找原文 依赖分词和词汇覆盖 可跨语言召回,依赖模型能力 语言能力并非默认保证

第三关:为什么采用融合、去重和重排

两路检索返回的排名不能直接拿原始分数相加。全文排名与余弦相似度不在同一量纲,不同文本长度也影响结果。Reciprocal Rank Fusion(RRF)通过名次而非原始分数融合候选,基本形式为:

RRF(d) = Σ[1 / (k + rank_i(d))]

其中 rank_i(d) 是片段在第 i 路结果中的名次,k 是平滑参数。RRF 最早由 Cormack、Clarke 和 Büttcher 在 SIGIR 2009 系统研究。这不证明它在 RecalAI 的实际资料上一定优于其他方法;权重、候选数和效果必须由自己的问答集验证。

融合之后还需要去重。同一个文件可能因重叠切块出现多个高度相似的片段。若把它们全部交给模型,可能浪费上下文预算,并让单一资料的重复表述挤掉有反证的另一份文件。

Rerank 则回答不同的问题:候选是否真正支持当前查询?一个片段仅包含"权限"与"云端"等词,不等于它解释了某项权限的具体范围。重排器的输入预算、延迟、离线适配与语言支持,都必须在目标设备上检验。

第四关:生成模型之前,要先做 Evidence Selection

混合检索不是最后一步。真正决定回答质量的,是哪些片段可以进入生成上下文,以及用户能不能回到它们的原文。

建议按以下约束选择证据:优先当前知识范围中可访问、解析成功的片段;保留 source_id、chunk_id、页码或定位信息;控制重复与单文档过度占比;必要时包含相互矛盾的片段,而非只选"最像答案"的一个;按模型上下文和设备内存设置 Token Budget。

引用校验也不能只看模型有没有输出"1"。每个引用至少应对应当前检索结果中真实存在的源片段,并且指向用户仍有权限访问的文件。引用的存在只证明来源可追踪,不自动证明模型对该来源的推理正确。涉及事实一致性时还需独立核对答案与片段是否相符。

以现有 RecalAI 产品页) 为下一步,读者可以看到本地优先、来源引用以及当前尚未开放商店下载的真实状态;这里不应放"立即下载"的虚假 CTA。

第五关:iPhone 13 与高内存设备,为什么不应强制跑同一个配置

端侧检索和生成的瓶颈不只是模型文件体积。导入任务、SQLite/FTS 查询、Embedding、Rerank、推理上下文、图片预览与界面渲染,会竞争有限的内存、CPU/GPU 时间和电量。较低内存设备更需要限制并发、检索候选数与上下文预算;较高配置设备可以评估更大的模型或更多候选,但不代表任何时候都更准确。

更稳妥的设计是把候选召回、证据筛选、生成预算和模型选择分离,以设备能力和当前负载动态调整。设备内存告警时,优先保障资料原件、索引一致性与用户可见进度,而不是为了继续后台增强牺牲前台稳定性。

本文不能提供毫秒延迟、召回率、耗电量或 iPhone 13 与新机型的速度比值,因为尚未从统一数据集、真实设备及固定版本获得可复核结果。

源码核验:RecalAI iOS 当前究竟实现了什么

本节来自 2026-10-23 对 RecalAI iOS 工作区源码的静态检查 ,不代表运行在真实设备上的性能验收。被核查的实现位于 Sources/Core/Search/PMSearchService.swift、Sources/Core/AI/PMContextBuilder.swift、Sources/Core/AI/PMAssistantModels.swift 及 Sources/Core/ModelDelivery/PMModelTechnicalSpecification.swift;发布前需记录具体 Git SHA 和确认这些路径仍存在。源码仓库属于产品内部开发资产,本节只披露非敏感逻辑。

检索实现比"FTS + 向量"更细: searchChunks() 同时建立精准包含匹配、Anchor Terms、严格词法检索、宽松词法检索和 Dense Vector 候选。向量分支需 semanticSearchAvailable 为真,且查询可生成 Embedding;当前代码按余弦相似度筛选候选,阈值为 0.30、密集候选最多 50 个。这些是当前源码常量,不是经测试得出的最佳阈值。

RRF 融合的 k 为 60;五条召回分支的权重分别是精准匹配 3.0、Anchor 2.8、严格词法 1.7、宽松词法 0.9、向量 1.0。之后会叠加查询信号匹配权重。首版没有额外的独立 Reranker 模型 :rerank() 是基于词项覆盖率和精准数值、日期、型号信号的确定性轻量重排。这是低内存设备上的有意取舍,不能称作 Cross-Encoder 实测重排。

证据预算也有具体边界: PMContextBuilder.build() 默认 tokenBudget = 2048、最多 8 个片段、每份知识最多 3 个片段,按可用预算和剩余位置分配内容长度,并清理易变 UI 元数据。这里的 Token 计算是混合文字的保守字符近似,不是模型实际 Tokenizer 的精确计数。

引用并非只靠提示词: PMGroundedResponseParser.parse() 接受允许的 chunk_id 集合;如果模型返回 ANSWER/PARTIAL 但没有有效引用或包含不在集合里的引用,会退回 NOT_FOUND。这个检查能阻止伪造来源 ID,但不能证明答案对原文的理解在语义上一定正确。

源码核验的边界:尚未验证 Android、Windows、macOS 与 iOS 的真实行为一致性;也没有完成真实设备的 FTS-only、Vector-only、Fusion-only、Fusion+规则重排四组对照,因此本文只作代码证据支持的工程实践分析,不称"性能实测"。

源码仓库还包含 Tests/PMRetrievalCoreTests.swift 与 Tests/Fixtures/rag_acceptance.json:前者为分词、余弦相似度、阈值和 Recall 计算设计了单元测试;后者列出中文、英文、跨语言、OCR 错字、长 PDF、数字、日期、版本及无答案场景等 11 条测试问题定义 。这些文件说明项目已有验收设计,不等于这些测试已在本次运行通过,也不构成真实用户语料的统计性能证据。

应该怎样证明"混合检索更有用"

在正式称为"实测"之前,至少建立四组对照:FTS-only、Vector-only、Fusion-only、Fusion + Rerank。测试题要包含精确字符串、同义表达、跨语言问答、否定、相似文件冲突以及答案不存在的情况;切块、资料集、设备和模型版本需保持一致。

建议记录 Recall@k、MRR 或 nDCG 等检索质量指标,以及证据引用准确率、无答案时正确拒答率、P50/P95 查询延迟、峰值内存和导入至可检索耗时。每一项都应保留原始运行记录和复现条件,不能用 GPT 解释图代替。

选择建议:什么时候反而不需要混合检索

如果资料只有几十条、用户只按准确字段搜索,可靠的全文索引可能更简单、更稳定;如果文档是短篇主题段落、查询措辞多变且不要求精确定位,向量检索可以作为主要召回路径。只有在多种文件、语言和查询类型混合、且需要可验证来源时,双路召回和重排的工程复杂度才更有理由被接受。

最终判断:个人 AI 知识库不应把"有一个向量数据库"误当成"能可靠回答私人资料"。真正的质量链路是:原件可靠保存 → 解析可见 → 精确与语义两路寻找候选 → 融合与去重 → 证据筛选 → 受约束生成 → 可回溯引用。架构合理性是起点,真实用户数据与设备实测才是最终验收。

参考资料与说明


原文(含源码核验边界与相关资料):www.xbstack.com/ai/recalai-...

相关阅读:

说明:本篇基于 RecalAI iOS 代码静态检查,非跨设备性能实测;不存在已验证的性能提升百分比。

相关推荐
诚小纯1 小时前
qwen-deep-research 接入实录:两阶段调用、SSE 解析、报告结构与 35 处不可追溯的引用
人工智能·github
RaaS1001 小时前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构
Hone1 小时前
一套让 7 个 AI Agent 共享同一份 Skills 的方案(Windows Junction 实战)
人工智能·程序员
烬羽1 小时前
PostgreSQL:AI 时代原生的"隐型"向量数据库 — 用 pgvector 给消息表加上长期记忆
数据库·人工智能·程序员
snakeshe10101 小时前
大语言模型常见评估指标与经典模型架构解析
人工智能
用户4015823324621 小时前
对话一长,AI 就忘了你说过的话?Claude Code、Codex、Aider、WES Code 怎么压缩上下文
人工智能·go·ai编程
用户5833339816681 小时前
影刀元素点击功能有什么替代方案?含 AI 自愈的几条实测路线
人工智能
趣说科技1 小时前
CMEF首日:探索BCI×AI产业应用新路径!熵基科技脑机全栈技术集中亮相
人工智能·科技
百慕大三角1 小时前
从 CLAUDECODE 到 AI_AGENT:前端与 CLI 工具如何感知 AI 编码代理?
人工智能·后端·全栈