文章目錄
- 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
存儲數據集基本信息
字段名 | 類型 | 描述 |
---|---|---|
id | BIGINT | 主鍵 |
type | INT | 0:手動數據集 |
name | VARCHAR | 數據集名稱 |
es_index_name | VARCHAR | ES 索引名稱 |
extract_qa_prompt | TEXT | 抽取 QA 問答對 Prompt |
extract_summary_prompt | TEXT | 抽取摘要 Prompt |
extract_param_prompt | TEXT | 抽取參數 Prompt |
is_deleted | TINYINT | 邏輯刪除標志 |
(2) knowledge_base_data
存儲具體知識數據項
字段名 | 類型 | 描述 |
---|---|---|
id | BIGINT | 主鍵 |
dataset_id | BIGINT | 關聯 dataset 表 |
main_content | TEXT | 主要內容 |
auxiliary_data | TEXT | 輔助數據 |
is_deleted | TINYINT | 邏輯刪除標志 |
(3) knowledge_base_index
存儲索引項
字段名 | 類型 | 描述 |
---|---|---|
id | BIGINT | 主鍵 |
data_id | BIGINT | 關聯 data 表主鍵 |
index_type | INT | 0-默認,1-用戶指定,3-提取問題,4-相關摘要 |
index_content | TEXT | 索引內容 |
(4) ai_kb_relation
存儲數據集與應用關聯
字段名 | 類型 | 描述 |
---|---|---|
id | BIGINT | 主鍵 |
module_id | BIGINT | 關聯的模塊 ID |
dataset_id | BIGINT | 知識庫數據集 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_id | long | 關聯 knowledge_base_data 主鍵 ID |
index_id | long | 關聯 knowledge_base_index 主鍵 ID |
dataset_id | long | 關聯 knowledge_base_dataset 主鍵 ID |
vector_index | dense_vector | 1024 維度稠密向量,支持余弦相似度計算 |
text_index | text | 采用 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 算法融合向量和文本搜索結果,提高查詢質量。
此方案支持靈活的知識管理和高效檢索,可擴展至更大規模的知識庫應用。