给博客加 AI 时,我最先做的是关键词检索。它很朴素,却有一个很难替代的优点:结果为什么出现,一眼就能解释。

后来文章越来越多,“电机故障”和“驱动异常”明明在说相近的事,关键词却把它们当作陌生人。向量检索正好补上这段语义距离。但真正能用的 RAG,不是把文本扔进向量库,再接一个聊天框就结束了。

一条可靠的检索链路

我现在更倾向于把检索拆成五段:

  1. 按标题、段落和代码块切分文档,同时保留文章 URL、章节名和更新时间。
  2. 对切片计算嵌入,并保存可重复生成的文档 ID。
  3. 查询时同时跑关键词与向量召回,不押注单一路径。
  4. 合并候选后重排,限制同一文章占据过多位置。
  5. 让模型只根据选中的证据回答,并把来源返回给前端。

混合检索的意义很实际。错误码、函数名、型号等精确字符串适合 BM25 或词法匹配;“这篇文章主要解决了什么”这类问题更适合语义向量。两者不是竞争关系,而是各自负责自己擅长的部分。

分块不是越小越好

切片太大,召回结果会混入大量无关内容;切片太小,语义和上下文又会被剪碎。我会优先按照 Markdown 标题和自然段切,再设置长度上限,同时让相邻切片保留少量重叠。

代码是例外。一个函数被切成两半,检索出来往往无法解释。因此代码块最好作为完整单元保存,并给它附上文章标题和前一段说明。

先评测,再谈“智能”

RAG 最容易陷入的错觉是:随机问几个问题,回答看起来不错,就认为系统已经完成。更稳妥的办法是准备一组固定问题,记录正确来源、必须出现的事实和不应编造的内容。

至少要观察四件事:召回是否命中、排序是否合理、回答是否忠于证据、没有答案时能否承认不知道。这样每次调整分块、权重或模型后,都能知道系统究竟变好了还是只变得更会说话。

我最后保留的原则

向量数据库不是知识本身,它只是索引。真正的知识仍然来自可追踪、可更新的原文。一个专业的 RAG 系统,最重要的并非回答得像人,而是能把答案带回证据。

参考资料: