文章目录
- FastGPT 源码:RRF、Rerank 相关代码
- 1. RRF (Reciprocal Rank Fusion) 合并实现
- 2. Rerank 二次排序实现
- 3. 重排序的主要特点
- 4. 整个搜索流程
- 5. 这种方式的优势
FastGPT 源码:RRF、Rerank 相关代码
下边介绍 RRF 合并和 Rerank 二次排序的相关实现:
1. RRF (Reciprocal Rank Fusion) 合并实现
主要在 datasetSearchResultConcat
函数中实现(packages/global/core/dataset/search/utils.ts
):
// RRF公式实现
const score = 1 / (k + rank); // k是一个常数(60),rank是搜索结果的排名
// 合并多个渠道的搜索结果
arr.forEach((item) => {
const k = item.k;
item.list.forEach((data, index) => {
const rank = index + 1;
const score = 1 / (k + rank);
// 如果已存在相同ID的结果,合并score
if (record) {
map.set(data.id, {
...record,
score: concatScore,
rrfScore: record.rrfScore + score
});
} else {
map.set(data.id, {
...data,
rrfScore: score
});
}
});
});
RRF 合并主要用在以下场景:
- 合并向量检索和全文检索的结果
- 合并多个查询的搜索结果
- 合并重排序后的结果
2. Rerank 二次排序实现
重排序功能在 reRankRecall
函数中实现(packages/service/core/ai/rerank/index.ts
):
export function reRankRecall({
query,
documents
}: {
query: string;
documents: { id: string; text: string }[];
}) {
// 调用重排序模型API
return POST<PostReRankResponse>(
model.requestUrl,
{
model: model.model,
query,
documents: documents.map((doc) => doc.text)
}
).then((data) => {
// 返回重排序后的结果和相关性分数
return data?.results?.map((item) => ({
id: documents[item.index].id,
score: item.relevance_score // 0-1之间的相关性分数
}));
});
}
3. 重排序的主要特点
- 使用专门的重排序模型对搜索结果进行二次评分
- 得到 0-1 之间的相关性分数,比向量相似度更精确
- 可以根据重排分数进行过滤,提高精度
- 重排结果会与其他搜索结果一起通过 RRF 合并
4. 整个搜索流程
- 同时进行向量检索和全文检索
- 对检索结果进行重排序评分
- 使用 RRF 合并三种结果(向量检索、全文检索、重排序)
- 根据相关度分数进行过滤
- 返回最终结果
5. 这种方式的优势
- 综合多种检索方式的优势
- 通过重排序提高精度
- 使用 RRF 合理合并多个渠道的结果