RAG 标准流程:
- 索引:外挂知识库
- 检索
- 生成
Advanced RAG
针对上述 3 个阶段做了优化。例如检索阶段,新增了 检索前处理 以及 检索后处理。
检索前处理:
- 查询转换
- 查询扩充
- …
查询扩充(Query Expansion)
在不改变用户意图的前提下,添加相关词语或同义表达,让检索系统能够匹配到更多语义相关的文档。例如用户输入:
项目合同扩充后的 Query 变成了:
["项目合同", "合作协议", "法律文件", "合同模板"]检索后处理:
常见的处理有:
- 重排序
- 过滤无关内容
- 合并去重
- 精简摘要
- 格式优化
MultiQueryRetriever#
MultiQueryRetriever 是 LangChain 中的一个工具类,作用是 用一个大模型 把用户问题改写成多种表述(多视角查询),对每个改写分别检索,然后合并去重结果,缓解“单一措辞导致召回不足”的问题。
召回率(Recall)
指的是所有相关内容中被成功检索出来的比例。公式为:
召回率 = 检索到的相关内容数量 / 所有实际相关内容的总数例如:实际相关文档有 10 个,系统只检索到其中 6 个,那么召回率 = 6 / 10 = 60%
改写原理
非常简单,就是调用大模型,给予大模型如下的提示词:
You are an AI language model assistant. Your task is to generate {queryCount}different versions of the given user question to retrieve relevant documents from a vector database.By generating multiple perspectives on the user question, your goal is to help the user overcome some ofthe limitations of the distance-based similarity search.Provide these alternative questions separated by newlines.Original question: {question}快速上手
// 创建底层检索器const retriever = vectorstore.asRetriever(2)
const llm = new ChatOllama({ model: 'llama3', temperature: 0.7 })
const mqRetriever = MultiQueryRetriever.fromLLM({ llm, retriever, queryCount: 3, verbose: true,})
const results = await mqRetriever.invoke('茴香豆是做什么用的')
console.log(results, 'results>>>')- llm:用于改写多版本提示词的模型
- retriever:底层的单查询检索器
- queryCount:要生成多少条不同的查询改写。
- verbose:控制台输出调试日志
课堂练习:使用 MultiQueryRetriever 改写用户原始提示词
🤔思考:创建检索器的时候 k 指定的是 2,为什么有 4 条结果?
k 指定的是 2,理论上应该是 2 条结果
理论上是 2 * 3 = 6 条结果,不过经过去重之后,得到了 4 条。
ContextualCompressionRetriever#
该工具类用于在检索出原始相关文档之后,进一步“压缩”内容或 过滤掉不相关部分,返回更简洁、更聚焦于问题的文档片段,属于检索后处理的一种。
基本语法:
new ContextualCompressionRetriever({ baseRetriever: r, // 指定基础的检索器 baseCompressor: LLMChainExtractor.fromLLM(llm), // 配置压缩器})LLMChainExtractor.fromLLM(llm) 相当于配置了一个压缩器,调用 LLM,从候选文档中提取出与问题相关的段落/句子。
课堂演示:使用 LLMChainExtractor 对文档进行压缩
课堂练习:使用 ContextualCompressionRetriever 过滤检索结果
ScoreThresholdRetriever#
一个基于相似度“阈值过滤”的检索器:它在向量库中检索时,只返回 相似度分数不低于 你设定阈值的文档。该类继承自 VectorStoreRetriever,提供 invoke() 等可运行接口方法。
使用示例:
const r = ScoreThresholdRetriever.fromVectorStore(vectorstore, { minSimilarityScore: 0.7,})
const res = await r.invoke('茴香豆是做什么用的?')
console.log(res)- minSimilarityScore:分数阈值,返回的文档的相似度分数不能小于该值。
除了该配置项以外,还支持下面的配置项:
-
kIncrement: number(默认 10):每次追加抓取的候选数量增量,用于在需要时扩大候选集,再按阈值过滤。 -
maxK: number(默认 100):抓取候选的上限,避免无限扩大搜索范围。 -
searchType: "similarity" | "mmr":可选设为"mmr"做多样性与相关性的权衡;默认"similarity"。 -
其余通用项:
filter?、verbose?、callbacks?、tags?、metadata?。