🔍 Elasticsearch + Milvus 構建高效知識庫問答系統(RAG 技術實戰)
📌 目錄
- 背景介紹
- Elasticsearch 在知識庫檢索中的作用
- Milvus 在知識庫檢索中的作用
- 混合檢索:Elasticsearch + Milvus
- 完整代碼實現
- 部署建議與優化方向
- 總結
背景介紹
在構建基于大語言模型(LLM)的知識增強型生成系統(RAG)中,知識庫檢索是整個流程的核心環節。它決定了模型是否能從龐大的文檔中快速定位到相關上下文信息。
傳統的 RAG 系統通常采用以下兩階段流程:
[Query] → [Retriever] → [Top-k Docs] → [LLM] → [Answer]
其中 Retriever 可以是稀疏檢索(如 BM25)、稠密檢索(如 Milvus),也可以是兩者的混合。
本文將詳細介紹如何使用 Elasticsearch 和 Milvus 來構建一個高效的多模態檢索系統,并提供可運行的 Python 示例代碼。
Elasticsearch 在知識庫檢索中的作用
功能概述:
- 基于關鍵詞匹配的稀疏檢索
- 支持倒排索引和 TF-IDF/BM25 模型
- 快速召回高相關性文檔
- 支持中文分詞、拼音搜索、近義詞擴展等功能
適用場景:
- 中文醫療問答系統
- 法律條文檢索
- 小規模 FAQ 庫
- 對語義理解要求不高的冷啟動階段
示例代碼(Python)
from elasticsearch import Elasticsearch
from sentence_transformers.util import cos_sim# 初始化 ES 客戶端
es = Elasticsearch(hosts=["http://localhost:9200"])# 插入文檔
doc1 = {"content": "大模型訓練需要大量高質量數據"}
doc2 = {"content": "RAG 系統通過外部知識提升回答能力"}
es.index(index="medical_kb", document=doc1)
es.index(index="medical_kb", document=doc2)# 查詢
query_body = {"match": {"content": "如何提升問答系統的準確性?"}
}
response = es.search(index="medical_kb", body=query_body)# 輸出結果
print("Elasticsearch 回答結果:")
for hit in response['hits']['hits']:print(f" - {hit['_source']['content']}")
Milvus 在知識庫檢索中的作用
功能概述:
- 支持高維向量存儲與相似度檢索(ANN)
- 可與 BERT、Sentence-BERT、BGE 等句向量模型結合
- 實現語義級別的相似度計算
- 支持大規模數據檢索(億級向量)
適用場景:
- 大規模知識庫
- 高精度語義匹配
- 圖像/文本混合檢索
- LLM + 向量數據庫聯合部署
示例代碼(Python + Milvus)
pip install pymilvus sentence-transformers
from sentence_transformers import SentenceTransformer
from pymilvus import connections, Collection# 加載語義編碼器
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')# 連接 Milvus
connections.connect(host='localhost', port='19530')
collection = Collection("faq_collection")# 插入向量(假設你已建立好 collection 并導入了知識庫向量化內容)# 查詢
query_text = "如何提升問答系統的準確性?"
query_vec = model.encode([query_text])collection.load()
results = collection.search(data=query_vec, anns_field="embedding", param={"metric_type": "IP", "offset": 0}, limit=3)# 輸出結果
print("Milvus 語義檢索結果:")
for result in results:for hit in result:print(f" - ID: {hit.id} Distance: {hit.distance}")
混合檢索:Elasticsearch + Milvus
你可以采用如下流程來構建一個高效的 RAG 問答系統:
[用戶問題]↓
Elasticsearch → [Top-50 粗召回文檔] ↓
Milvus → [Top-10 語義相似文檔]↓
Reranker → [Top-3 最佳匹配段落]
? 混合優勢:
優點 | 描述 |
---|---|
冷啟動友好 | 利用 ES 快速上線 |
語義準確 | Milvus 提升召回質量 |
高效排序 | 結合 reranker 進一步優化輸出 |
支持中文 | 可選擇支持中文的 embedding 模型 |
完整代碼實現(Python 示例)
以下是一個完整的混合檢索流程示例:
from elasticsearch import Elasticsearch
from sentence_transformers import SentenceTransformer
from pymilvus import connections, Collection# 初始化組件
es = Elasticsearch(hosts=["http://localhost:9200"])
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
connections.connect(host='localhost', port='19530')
milvus_col = Collection("faq_collection")def hybrid_retrieval(query, k=3):# Step 1: Elasticsearch 粗召回es_result = es.search(index="medical_kb", body={"match": {"content": query}})es_docs = [hit["_source"]["content"] for hit in es_result["hits"]["hits"]]# Step 2: Milvus 語義精排query_vec = model.encode([query])milvus_results = milvus_col.search(data=query_vec, anns_field="embedding", param={"metric_type": "IP"}, limit=k)# Step 3: 返回 top-k 文檔final_docs = []for result in milvus_results:for hit in result:final_docs.append(es_docs[hit.id])return final_docs[:k]
部署建議與優化方向
1. 數據預處理建議:
- 使用
jieba
或HanLP
對中文進行分詞 - 清洗無意義符號、HTML、亂碼
- 構建統一的數據格式(如 JSON)
2. 索引構建建議:
- Elasticsearch:
- 使用
ik-analyzer
中文分詞插件 - 設置字段類型為
text
或keyword
- 使用
- Milvus:
- 使用 HNSW 或 IVF-PQ 索引加速查詢
- 設置合適的維度(如 768 / 1024)
- 開啟 GPU 加速(如支持)
3. 性能調優建議:
組件 | 調優方式 |
---|---|
Elasticsearch | 分片策略、索引合并、關閉不必要的日志 |
Milvus | 使用 ANN 索引、調整 nprobe、批量插入 |
Embedding 模型 | 使用輕量模型(如 bge-small , gte-base ) |
緩存機制 | Redis 緩存高頻問題與答案 |
異步檢索 | 使用 Celery 或 FastAPI 異步接口 |
4. 可選高級功能:
- Reranking:使用
BAAI/bge-reranker-base
等交叉編碼器進一步打分排序 - 向量更新機制:定期更新 Milvus 中的知識庫向量
- 混合評分融合:對 ES 和 Milvus 的結果做加權得分排序
總結
方法 | 是否理解語義 | 是否需訓練 | 是否支持中文 | 是否適合大規模 | 是否適合冷啟動 |
---|---|---|---|---|---|
Elasticsearch | ? 否 | ? 否 | ? 是 | ? 是 | ? 是 |
Milvus | ? 是 | ? 是 | ?(模型決定) | ? 是 | ? 否 |
FAISS | ? 是 | ? 是 | ?(模型決定) | ? 有限 | ? 否 |
混合檢索(ES+Milvus) | ? 是 | ? 是 | ? 是 | ? 是 | ? 是 |
? 推薦組合方案
方案一:純稀疏檢索(僅使用 ES)
適合冷啟動或無語義模型的場景,無需 GPU 資源。
Query → Elasticsearch → Top-k Docs
方案二:純稠密檢索(僅使用 Milvus)
適合有預訓練語義模型(如 BGE、Jina、OpenAI embeddings)的場景。
Query → Dense Encoder → Milvus → Top-k Docs
方案三:混合檢索(ES + Milvus)
適合企業級 RAG 系統,兼顧效率與精度。
Query → Elasticsearch → Top-50 Docs↓Milvus → Top-10 Docs↓Reranker → Top-3 最終輸出
📌 歡迎點贊、收藏,并關注我,我會持續更新更多關于 AI、LLM、視覺-語言模型等內容!