当前位置: 首页 > article >正文

FastGPT 引申:借鉴 FastGPT 基于MySQL + ES 实现知识库(含表结构以及核心代码)

文章目录

  • FastGPT 引申:借鉴 FastGPT 基于MySQL + ES 实现知识库(含表结构以及核心代码)
    • 一、整体思路
    • 二、存储结构
      • 2.1 MySQL 表结构
        • (1) knowledge_base_dataset
        • (2) knowledge_base_data
        • (3) knowledge_base_index
        • (4) ai_kb_relation
      • 2.2 Elasticsearch Mapping 结构
        • (1) ES索引
        • (2) 字段说明
    • 三、代码实现
      • 3.1 调用 Embedding 服务
      • 3.2 向量检索(ES KNN 查询)
      • 3.3 RRF 排序(融合向量检索和文本检索结果)
    • 四、总结

FastGPT 引申:借鉴 FastGPT 基于MySQL + ES 实现知识库(含表结构以及核心代码)

一、整体思路

  • 知识库查询能力:引入 Elasticsearch (ES) 提供向量存储和检索能力。
  • 三层逻辑结构
    • 数据集:使用模块 ID 关联应用。
    • 数据:存储具体的知识内容。
    • 索引:提供高效的查询能力。

二、存储结构

2.1 MySQL 表结构

(1) knowledge_base_dataset

存储数据集基本信息

字段名类型描述
idBIGINT主键
typeINT0:手动数据集
nameVARCHAR数据集名称
es_index_nameVARCHARES 索引名称
extract_qa_promptTEXT抽取 QA 问答对 Prompt
extract_summary_promptTEXT抽取摘要 Prompt
extract_param_promptTEXT抽取参数 Prompt
is_deletedTINYINT逻辑删除标志
(2) knowledge_base_data

存储具体知识数据项

字段名类型描述
idBIGINT主键
dataset_idBIGINT关联 dataset
main_contentTEXT主要内容
auxiliary_dataTEXT辅助数据
is_deletedTINYINT逻辑删除标志
(3) knowledge_base_index

存储索引项

字段名类型描述
idBIGINT主键
data_idBIGINT关联 data 表主键
index_typeINT0-默认,1-用户指定,3-提取问题,4-相关摘要
index_contentTEXT索引内容
(4) ai_kb_relation

存储数据集与应用关联

字段名类型描述
idBIGINT主键
module_idBIGINT关联的模块 ID
dataset_idBIGINT知识库数据集 ID

2.2 Elasticsearch Mapping 结构

(1) ES索引

存储知识数据的向量索引:ai_knowledge

{
  "mappings": {
    "properties": {
      "data_id": {
        "type": "long",
        "index": true
      },
      "index_id": {
        "type": "long",
        "index": true
      },
      "dataset_id": {
        "type": "long",
        "index": true
      },
      "vector_index": {
        "type": "dense_vector",
        "dims": 1024,
        "index": true,
        "similarity": "cosine"
      },
      "text_index": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}
(2) 字段说明
字段名称类型说明
data_idlong关联 knowledge_base_data 主键 ID
index_idlong关联 knowledge_base_index 主键 ID
dataset_idlong关联 knowledge_base_dataset 主键 ID
vector_indexdense_vector1024 维度稠密向量,支持余弦相似度计算
text_indextext采用 ik_max_word 分词器进行索引

三、代码实现

3.1 调用 Embedding 服务

public List<Float> getVector(String text) {
    ResponseEntity responseEntity = xxxx;
    if (responseEntity != null && responseEntity.getCode() == 0) {
        List<List<Double>> vectorList = (List<List<Double>>) responseEntity.getData();
        if (vectorList != null && !vectorList.isEmpty()) {
            return vectorList.get(0).stream()
                    .map(Double::floatValue)
                    .collect(Collectors.toList());
        }
    }
    return null;
}

3.2 向量检索(ES KNN 查询)

public List<Knowledge> searchByVector(List<Float> vector) throws IOException {
    log.info("Searching knowledge with vector similarity using KNN");
    try {
        return client.search(s -> s
            .index(INDEX_NAME)
            .knn(k -> k
                .field("vector_index")
                .queryVector(vector)
                .k(DEFAULT_SIZE)
                .numCandidates(100)
            ),
            Knowledge.class
        ).hits().hits().stream()
            .map(Hit::source)
            .collect(Collectors.toList());
    } catch (Exception e) {
        log.error("Error searching knowledge by vector: {}", e.getMessage(), e);
        throw e;
    }
}

3.3 RRF 排序(融合向量检索和文本检索结果)

private Map<String, Double> calculateRRFScores(
        List<Hit<KnowledgeCommon>> vectorHits,
        List<Hit<KnowledgeCommon>> textHits) {

    Map<String, Double> rrfScores = new HashMap<>();
    int rank = 1;
    for (Hit<KnowledgeCommon> hit : vectorHits) {
        String id = hit.id();
        double score = VECTOR_WEIGHT * (1.0 / (rank + RRF_CONSTANT));
        rrfScores.put(id, rrfScores.getOrDefault(id, 0.0) + score);
        rank++;
    }

    rank = 1;
    for (Hit<KnowledgeCommon> hit : textHits) {
        String id = hit.id();
        double score = TEXT_WEIGHT * (1.0 / (rank + RRF_CONSTANT));
        rrfScores.put(id, rrfScores.getOrDefault(id, 0.0) + score);
        rank++;
    }

    return rrfScores;
}

四、总结

  • 采用 MySQL 存储基础数据,ES 存储向量及文本索引
  • ES 结合 KNN 和分词搜索进行知识检索
  • 使用 RRF 算法融合向量和文本搜索结果,提高查询质量

此方案支持灵活的知识管理和高效检索,可扩展至更大规模的知识库应用。


http://www.kler.cn/a/573023.html

相关文章:

  • 数据结构与算法:堆排序
  • Android 14 - HDMI_CEC架构分析
  • 本地部署类似 ChatGPT 的大模型:基于 Ollama + Open-WebUI
  • XTDrone+Mavros+Gazebo仿真——配置与控制不同的无人机
  • html中几个符号的转义和还原
  • LeetCode 79: 单词搜索 (Word Search)
  • C++11中atomic
  • 【SpringBoot】一文讲懂什么是scanBasePackages
  • [MySQL初阶]MySQL(3)表的约束
  • 华为最新OD机试真题-计算堆栈中的剩余数字-Python-OD统一考试(E卷)
  • C语言学习笔记-进阶(1)深入理解指针3
  • Ollama+AnythingLLM安装
  • 期权有哪些用处?期权和期货比优势在哪?
  • CentOS 7 安装 Redis6.2.6
  • R语言绘图:韦恩图
  • 06. View工作原理
  • 《HarmonyOS赋能的智能影像诊断系统安全架构与临床实践》
  • 杨辉三角解法
  • kotlin的val声明的变量是常量吗
  • vscode 都有哪些大模型编程插件