“搜不到、搜不准”,提升RAG检索召回率

在AI的世界里,有句老话叫“Garbage In, Garbage Out”。对于RAG系统而言,检索环节就是那个“In”,如果检索不到精准、全面的信息,那么即便是最强的LLM也只能望“材”兴叹,甚至开始一本正经地“胡说八道”,俗称产生幻觉。 本篇将聚焦于检索前和检索中的优化,从数据的源头和查询的入口解决“找不到”和“找不准”的核心痛点。


一:优化数据源:索引构建的最佳实践

核心痛点:粗暴地按固定长度切分文档,就像把一本好书随机撕成碎片,重要的上下文和语义关联都丢失了。

1.1 智能分块

放弃按字符数切分的“一刀切”模式,转向更智能的方法:

  • 语义分块: 利用算法(或LLM)识别文本中语义的自然断点,如段落、标题或一个完整的概念单元,确保每个被索引的文本块都“言之有物”。

  • 句子分块: 以完整的句子为单位进行切分,这是最细粒度的语义单元。

1.2 父文档检索器

这是对“句子窗口检索”更通用、更强大的实现,也是我为您补充的一个关键策略。

  • 原理:

    1. 索引时:我们将一份文档切分成许多小的“子文档”(比如单个句子),并对这些“子文档”进行向量化。同时,我们保留一份完整的、较大的“父文档”(比如整个段落或页面)。

    2. 检索时:我们用用户查询去匹配那些精细的“子文档”。

    3. 返回时:一旦命中某个“子文档”,我们不返回这个小片段,而是返回它所属的那个完整的“父文档”作为上下文。

  • 优点:兼具检索的精准度(匹配小块)和上下文的完整性(返回大块),效果拔群。

1.3 从文档生成QA对:创造更多检索入口

这是另一项极大提升召回率的王牌策略。其核心思想是:用户的提问方式千变万化,直接用问题去匹配一段陈述性的文档,在语义上可能存在鸿沟。但用“问题”去匹配“问题”,则要容易和精准得多。

  • 原理:

    1. 对每一个文档块,我们调用LLM,反向生成几个用户可能会提出的、能够被这个文档块回答的问题。

    2. 在构建索引时,我们只对这些新生成的“代理问题”进行向量化。

    3. 同时,我们将这些“代理问题”全部链接到它们所源自的那个原始文档块的ID。

    4. 当用户提问时,系统会在“代理问题”的向量库中进行搜索。一旦匹配成功,系统不会返回这个代理问题,而是通过ID找到并返回那个包含完整答案的原始文档块。

  • 优点: 为单个知识点创建了多个不同的语义入口,即使用户的提问方式很刁钻,只要能和其中一个代理问题对上,就能找到正确答案,召回率大大提升。

from langchain.storage import InMemoryStore
from langchain_core.documents import Document
from langchain.retrievers.multi_vector import MultiVectorRetriever
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
import uuid
docs
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值