FastGPT 源码:混合检索调用链路

文章目录

    • [FastGPT 源码:混合检索调用链路](#FastGPT 源码:混合检索调用链路)
      • [1. 入口函数](#1. 入口函数)
      • [2. 核心搜索函数](#2. 核心搜索函数)
      • [3. RRF合并函数](#3. RRF合并函数)
      • [4. Rerank重排序函数](#4. Rerank重排序函数)
      • [5. 完整流程](#5. 完整流程)

FastGPT 源码:混合检索调用链路

主要调用链路如下:

1. 入口函数

dispatchDatasetSearch(packages/service/core/workflow/dispatch/dataset/search.ts):

typescript 复制代码
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):

typescript 复制代码
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):

typescript 复制代码
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):

typescript 复制代码
export function reRankRecall({query, documents}) {
  // 调用重排序模型API
  return 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. 完整流程

  1. dispatchDatasetSearch 作为入口,接收搜索参数
  2. 调用 searchDatasetData 执行核心搜索逻辑
  3. searchDatasetData 中:
    • 先执行向量检索和全文检索
    • 合并这两种检索结果
    • 调用 reRankRecall 进行重排序
    • 最后通过 datasetSearchResultConcat 合并所有结果
  4. 返回最终过滤和处理后的搜索结果

这个调用链路完整实现了:

  • Embedding 和 BM25 检索
  • 结果合并后的 Rerank
  • 最终三路结果的 RRF 合并
相关推荐
成都渲染101云渲染66662 小时前
如何在3ds Max中实现更快、更高质量的渲染
前端·javascript·人工智能
十铭忘4 小时前
MOTIONGPT3:人类运动作为第二模态
人工智能
weigangwin5 小时前
采用 mem0 之前,先决定 Agent 到底允许记住什么
人工智能·opencv·ai·llm·memory·ai agent·mem0
木木学AI5 小时前
AI客服系统技术选型:Agentic架构与传统规则引擎的能力差异评估
人工智能·架构
hhzz5 小时前
Python大数据实战(十六):音乐推荐系统——基于协同过滤算法构建个性化歌单引擎
大数据·人工智能·python·数据挖掘·数据分析
带娃的IT创业者5 小时前
突破算力与安全的边界:深度解析 Mythos AI 的“受信发布”机制与技术影响
人工智能·安全·大语言模型·ai安全·mythos ai·受信发布·ai监管
dreamread5 小时前
2026紫微八字同排工具怎么选:看盘面切换、功能边界和学习路径
人工智能·软件工具·传统文化
耍酷的魔镜5 小时前
核心设计理念:5W2H、JSON-LD 与通用知识图谱
人工智能·json·知识图谱
zlinear数据采集卡6 小时前
从0到1硬核拆解:工业级数据采集卡的隔离设计与Modbus通信实战
arm开发·单片机·嵌入式硬件·fpga开发·开源
星河耀银海6 小时前
大模型安全:对抗攻击与防御方法
人工智能·安全·大模型