RAG检索方案

6 阅读3分钟

检索步骤

  1. 开启精排(可以做成项目配置,根据配置是否开启)

精排的关键是我们topk的参数得传大点,检索的更多语义相关性chunk 在大模型检索好的结果中的多语义相关性打分,打分最高的优先取出几条来

  1. 密集向量检索

将query进行embedding后通过milvus的查询enbedding后的chunk。进行语义相似度cos比对

  1. 稀疏向量检索
  • 词频(TF):这个词在文档里出现越多,分数越高
  • 逆文档频率(IDF):这个词在整个知识库里越稀有,分数越高("的""是"这种常见词权重很低)
  1. 重排序 RRF(Reciprocal Rank Fusion)
  • RRF得分 = 1/(k + 密集向量排名) + 1/(k + 稀疏向量排名)
  • k=60 是平滑参数(代码指定的参数)
  • 总结:是将密集向量的排名 + 稀疏向量的排名 = RRF的分,两者排名都靠前,得分最高。
  1. 按时间衰减排序(若知识库文档更新频繁,知识内容易过期的场景)
  • 新资料优先的规则,根据chunk的update_at时间排序新的chunk优先
  1. 开启MMR排序(可以做成根据项目配置的功能)
  • 每条都和 query 足够相关(相关性项保证)
  • 彼此之间内容尽量不重复,采用贪心算法,query语义话相关的前提下,越是和当前已采纳的chunk内容不一致,越容易被采纳
  • 功能: MMR 在 RRF 之后再做一轮,补上这个"去冗余"的能力。(先保证每条都相关,再保证整体不重复)

  • 总结: 既要和 query 相关,又要和已选的 chunk 不一样,两个条件同时满足得分才高。

其他的优化项目

  • 提高Chunk 切分质量,比如
    • 语义边界优先切分
      • 第一步:按段落预切分
      1. 先按 \n\n 把文本切成若干段落块,每个段落块保证语义完整。
      • 第二步:合并小段落
      1. 相邻的小段落(< chunkSize)合并,直到接近 chunkSize 再输出为一个 chunk,避免 chunk 太短。
      • 第三步:拆分大段落
      1. 遇到超过 chunkSize 的大段落,在句子边界(。!?)处切,而不是硬截断。
      • 第四步:重叠保留上下文
      1. 重叠部分取上一个 chunk 的最后一句完整句子,而不是固定 150 个字符。
      • 第五步:表格单独处理
      1. PDF 解析出的表格通常有特征(多个 | 或对齐的空格列),可以识别出来,把整张表格作为一个 chunk,不参与滑动窗口切分。
      2. 标题注入,把章节标题前缀到每个 chunk 里。这样每个 chunk 即使脱离上下文,也知道自己在讲的哪个部分,embedding 更准确
  • Embedding 模型质量
  • 知识库本身的质量(文档本身内容混乱、格式不规范,再好的检索也没用)

总结

这只是普通的RAG检索方案和流程,RAG进阶还有很多如

  • Adaptive RAG

  • Self-RAG

  • CRAG

  • Agentic RAG