文章目录
- FastGPT 源码:混合检索调用链路
- 1. 入口函数
- 2. 核心搜索函数
- 3. RRF合并函数
- 4. Rerank重排序函数
- 5. 完整流程
FastGPT 源码:混合检索调用链路
主要调用链路如下:
1. 入口函数
在 dispatchDatasetSearch
(packages/service/core/workflow/dispatch/dataset/search.ts):
export async function dispatchDatasetSearch(props: DatasetSearchProps) {// 1. 获取参数const {teamId,histories,module,params: {datasets,similarity,limit,usingReRank,searchMode,userChatInput}} = props;// 2. 问题优化/扩展const { concatQueries, rewriteQuery } = await datasetSearchQueryExtension({query: userChatInput,extensionModel,extensionBg,histories});// 3. 调用核心搜索函数const { searchRes } = await searchDatasetData({teamId,reRankQuery: rewriteQuery,queries: concatQueries,model: vectorModel.model,similarity,limit,datasetIds: datasets.map((item) => item.datasetId),searchMode,usingReRank});
}
2. 核心搜索函数
searchDatasetData
(packages/service/core/dataset/search/controller.ts):
export async function searchDatasetData({teamId,reRankQuery,queries,model,similarity,limit,searchMode,usingReRank,datasetIds
}) {// 1. 向量检索和全文检索const { embeddingRecallResults, fullTextRecallResults } = await multiQueryRecall({embeddingLimit,fullTextLimit});// 2. 第一次RRF合并(向量检索和全文检索结果)const concatRecallResults = embeddingRecallResults.concat(fullTextRecallResults.filter((item) => !set.has(item.id)));// 3. Rerank二次排序const reRankResults = await reRankSearchResult({query: reRankQuery,data: concatRecallResults });// 4. 最终RRF合并(三种结果)const rrfConcatResults = datasetSearchResultConcat([{ k: 60, list: embeddingRecallResults },{ k: 60, list: fullTextRecallResults },{ k: 58, list: reRankResults }]);// 5. 结果过滤和处理const scoreFilter = filterResults(rrfConcatResults);return { searchRes: filterResultsByMaxTokens(scoreFilter, maxTokens) };
}
3. RRF合并函数
datasetSearchResultConcat
(packages/global/core/dataset/search/utils.ts):
export const datasetSearchResultConcat = (arr: { k: number; list: SearchDataResponseItemType[] }[]) => {// 1. 计算每个结果的RRF分数arr.forEach((item) => {const k = item.k;item.list.forEach((data, index) => {const rank = index + 1;const score = 1 / (k + rank);// 合并分数...});});// 2. 根据RRF分数排序return results.sort((a, b) => b.rrfScore - a.rrfScore);
}
4. Rerank重排序函数
reRankRecall
(packages/service/core/ai/rerank/index.ts):
export function reRankRecall({query, documents}) {// 调用重排序模型APIreturn POST(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}));});
}
5. 完整流程
dispatchDatasetSearch
作为入口,接收搜索参数- 调用
searchDatasetData
执行核心搜索逻辑 - 在
searchDatasetData
中:- 先执行向量检索和全文检索
- 合并这两种检索结果
- 调用
reRankRecall
进行重排序 - 最后通过
datasetSearchResultConcat
合并所有结果
- 返回最终过滤和处理后的搜索结果
这个调用链路完整实现了:
- Embedding 和 BM25 检索
- 结果合并后的 Rerank
- 最终三路结果的 RRF 合并