Agent 工程

私有知识库的本地混合检索

不同问题需要不同检索语义:精确数字依赖结构化查询,关键词相关性依赖倒排索引与 BM25,概念近似依赖向量嵌入。混合检索把这些能力放在同一条可审计的数据链路中。

先区分问题的检索语义

“检索”不是单一操作。一个系统可能同时面对精确筛选、关键词匹配、短语定位、概念近似、跨文档聚合和时间序列计算。单一向量接口无法在这些目标上同时保持精确性、可解释性和稳定性。

问题类型主要机制结果含义
某日期范围内的记录字段过滤、SQL满足条件的完整集合
某个名称或术语出现在哪里全文索引、短语查询包含词项的文档排序
与某概念含义接近的段落向量嵌入、相似度语义空间中的近邻
某期间的总额或分类占比结构化数据、确定性聚合可复算的数值
关键词与概念召回并重多路召回、排名融合合并后的候选证据
检索结果通常是候选证据,而不是事实全集。top-k 的含义是“按某种评分排在前 k 位”,不等于“除此之外没有相关内容”。

结构化查询负责精确事实

关系表、CSV 和带类型字段的记录适合等值条件、范围条件、分组、排序与聚合。日期、币种、金额、状态和分类都具有明确的数据类型与运算规则。此类问题的正确性来自 schema、约束和确定性计算,而不是文本相似度。

向量检索会返回“看起来相近”的记录,但不能保证覆盖某个期间的全部行,也不能保持小数精度、会计恒等式或去重规则。因此,数值报表通常由结构化数据生成;文本检索只承担解释材料与上下文的发现。

混合系统不是把所有数据转换成向量。混合系统保留每种数据原本的计算语义,再在查询层组合结果。

倒排索引与全文检索

普通文档可以看作“文档到词项”的映射。倒排索引反转该关系,为每个词项保存出现过的文档或位置列表,列表通常称为 postings。查询一个词时,系统直接读取对应 postings,不需要逐个扫描全部文档。

原始文档保留完整正文与元数据
分词产生规范化词项
倒排表词项指向文档与位置
查询合并多个 postings
排序输出相关候选

位置数据支持短语和邻近查询;字段索引支持标题、正文或标签的不同权重。英文常按单词边界切分。中文没有天然空格边界,常见实现包括词典分词、统计分词和字符 n-gram。字符二元组、三元组会增加索引体积,但能稳定处理新词、简称和混合语言文本。

“全文索引”描述可搜索全文的整体能力;“倒排索引”描述实现该能力的核心数据结构。两者经常同时出现,但概念层级不同。

BM25 如何排序关键词结果

BM25 是基于词项统计的相关性函数。核心因素包括查询词在文档中的频率、词在整个语料中的稀有程度,以及文档长度相对平均长度的偏差。一个常见表达为:

score(D,Q) = Σ IDF(t) × f(t,D)(k₁+1) / [f(t,D) + k₁(1-b+b|D|/avgdl)]

BM25 对专有名词、错误码、产品名和原文措辞具有直接解释性。局限来自词汇不匹配:两个段落表达同一概念但没有共享词项时,BM25 可能无法建立联系。

向量嵌入与语义相似

嵌入模型把文本映射到固定维度的数值向量。训练目标使语义相关文本在向量空间中更接近。检索阶段通常计算余弦相似度、点积或欧氏距离。

cosine(a,b) = (a · b) / (||a|| × ||b||)

精确向量扫描会比较查询向量与全部候选,结果确定但计算量随向量数线性增长。HNSW、IVF 等近似最近邻结构以额外内存、构建成本和召回损失换取更低延迟。数据量较小时,精确扫描的运维复杂度通常更低;规模和延迟要求提高后,近似索引的收益才会显现。

向量相似不代表事实相同。模型可能混淆否定、数字、时间、主体或因果方向;长文本截断和分块边界也会改变向量。因此,向量结果适合扩大召回范围,完整原文仍然承担证据确认。

混合检索与 RRF

关键词评分和向量相似度处在不同量纲,直接相加会引入不稳定的缩放问题。Reciprocal Rank Fusion(RRF)只使用每个通道的名次:

RRF(d) = Σ 1 / (k + rank(d))

每个召回通道分别产生排序列表。某个文档在多个列表中都靠前时,融合得分随之提高。常数 k 降低头部名次差异的敏感度。RRF 不需要把 BM25 分数与余弦分数校准到同一区间,适合组合异构检索器。

混合检索仍然受各通道候选集限制。若结构化必读材料不进入任一候选集,融合算法不会自动补回。因此,强制证据清单、元数据过滤和多路召回属于不同层次的控制。

SQLite 作为单机检索层

SQLite 是进程内数据库,没有独立服务器进程。FTS5 提供全文索引、短语查询、高亮、snippet 与 bm25()。文档元数据、分块、构建版本和向量 BLOB 可以保存在同一数据库文件中,事务与原子文件替换为索引发布提供清晰边界。

表或索引职责
documents源标识、标题、日期、领域和内容哈希
chunks稳定分块、heading、顺序和原文片段
FTS5词项 postings 与 BM25 排序
embeddings模型标识、维度和 float32 向量
metadataschema 版本、源指纹和构建计数

SQLite 的优势是部署简单、备份直观、SQL 过滤方便和本地事务完整。限制包括单写入者协调、大规模向量扫描成本,以及默认数据库文件不自带加密。文件权限、磁盘加密、备份位置和进程权限仍然属于系统安全设计。

权威数据与隐私边界

派生索引与权威数据分离可以降低损坏面。索引进程只读取源文件;数据库、模型、临时文件、锁和日志位于独立缓存层。索引删除后可由源数据重建,任何检索结果都不反向覆盖原文。

权威源文档与结构化记录
只读提取白名单、解析与哈希
派生索引FTS、向量与元数据
候选召回过滤、排序与通道来源
证据确认重新打开完整权威源

“本地数据库”本身不等于隐私安全。嵌入模型可能在首次使用时联网下载公开权重;完成缓存后,本地推理不需要把文本发送到外部 API。临时文件、崩溃转储、命令历史、云同步目录和备份同样可能扩大数据边界。安全属性来自完整的数据流与运行环境,而不是文件扩展名。

索引构建与更新生命周期

  1. 读取白名单配置,解析并规范化源路径。
  2. 计算源文件集合与内容哈希,形成构建前指纹。
  3. 按标题、段落和长度分块,并保留源路径、日期、heading 与 chunk 哈希。
  4. 在缓存目录的新临时数据库中构建 FTS5 与向量;内容未变的 chunk 可复用旧向量。
  5. 再次计算源指纹。构建期间有变化时,临时结果被放弃。
  6. 执行数据库完整性检查、文件同步与原子替换,上一版数据库直到替换时仍可查询。

稳定 chunk ID 使增量复用成为可能。模型名称、维度、分块配置或 tokenizer 变化会改变索引语义,构建元数据用于识别这种不兼容。单一构建锁避免两个写入者同时发布不同版本。

评测与常见失败模式

检索评测需要带相关性标注的查询集合。Recall@k 衡量相关项是否进入前 k 名;MRR 关注第一个相关项的位置;nDCG 适合存在多级相关性的排序。答案准确性、引用完整性和推理可靠性属于检索之后的独立评测层。

失败模式可观测现象对应控制
中文分词不匹配短词、新词或混合语言漏召回n-gram、领域词典、查询分析
分块过大向量主题混杂,片段难定位按 heading 与段落切分
分块过小上下文断裂,否定与主体丢失重叠窗口、父文档回读
向量误相似措辞接近但事实不同BM25 交叉、元数据过滤、原文确认
索引陈旧源已更新而结果仍指向旧片段源指纹、构建版本、freshness 检查
以 top-k 代表全集聚合遗漏、错误的“没有记录”结论结构化查询、完整枚举、必读清单

其他存储与检索方案

方案主要特征典型适用条件
SQLite + FTS5 + 向量 BLOB单文件、进程内、可精确扫描单机、低运维、数据量与并发有限
sqlite-vecSQLite 向量扩展,SQL 内执行向量查询需要保留单文件形态并增加向量 SQL 能力
PostgreSQL + pgvector事务数据库、丰富过滤、HNSW/IVFFlat已有 PostgreSQL、并发写入与服务化查询
Qdrant专用向量服务、过滤与分布式接口高并发 API、独立服务生命周期
LanceDB面向列式数据与多模态检索的嵌入式方案较大分析数据集、对象存储或多模态工作负载

选择条件包括数据规模、写入并发、延迟目标、过滤复杂度、备份方式、加密要求和运维能力。向量数据库解决的是向量存储与近邻查询,不会替代源数据治理、结构化计算、证据引用或隐私控制。

来源与说明

本文描述通用信息检索架构,不构成针对特定数据集的安全审计、合规意见或容量规划。组件版本、扩展成熟度和性能特征会随实现演进。