【原創】使用ElasticSearch存儲向量實現大模型RAG

一、概述

檢索增強生成(Retrieval-Augmented Generation,RAG)已成為大型語言模型(LLM)應用的重要架構,通過結合外部知識庫來增強模型的回答能力,特別是在處理專業領域知識、最新信息或企業私有數據時。本報告將系統梳理使用 Elasticsearch(ES)作為向量數據庫實現 RAG 系統的優缺點,與傳統向量數據庫及其他存儲解決方案的對比,以及基于 Deepseek V3 和 Qwen2.5 大模型的實現方案。

二、Elasticsearch 作為 RAG 向量數據庫的優缺點分析

1. 優點

低門檻的獨立技術棧
  • 一站式解決方案:ES 能夠一站式完成向量生成、存儲、索引和檢索,通過配置即可實現大部分功能
  • 成熟的生態系統:作為成熟的搜索引擎,擁有豐富的文檔、社區支持和工具集
  • 簡化的部署和維護:相比需要部署多個組件的解決方案,ES 可以作為單一系統處理所有 RAG 相關任務
高性能和擴展性
  • 分布式架構:支持百萬級 QPS 和千億級數據量
  • 靈活的擴展能力:可以通過添加節點水平擴展,滿足不斷增長的數據需求
  • 高可用性:內置的分片和復制機制確保系統的可靠性
混合檢索能力
  • 文本與向量的結合:同時支持傳統的全文檢索和向量相似性搜索
  • 提高檢索精度:混合檢索策略能夠顯著提升搜索結果的準確性和多樣性
  • 處理短查詢優勢:對于短查詢,傳統關鍵詞搜索可以彌補純向量搜索的不足
豐富的數據處理能力
  • 強大的文本分析:內置多種語言分析器,支持分詞、同義詞、停用詞等處理
  • 結構化和非結構化數據支持:可以同時處理結構化字段和非結構化文本
  • 聚合和分析功能:提供豐富的聚合功能,可用于數據分析和可視化
多種相似度計算算法支持
  • 余弦相似度(Cosine Similarity):適用于文本語義搜索,不受向量長度影響
  • 點積(Dot Product):適用于推薦系統,考慮向量長度和方向
  • 歐幾里得距離(L2 Norm):適用于圖像特征、地理位置等場景
  • 腳本評分(Script Score):支持自定義腳本實現更復雜的相似度計算
  • 函數評分(Function Score):允許結合衰減函數、字段值等因素調整相似度分數
與大模型的無縫集成
  • 簡化的集成流程:提供 API 和工具,便于與各種大模型集成
  • 靈活的檢索配置:可以根據不同大模型的特點調整檢索策略

2. 不足

向量搜索性能限制
  • 非專用架構:ES 的架構不是專為向量搜索設計的,在大規模向量搜索時性能可能不如專用向量數據庫
  • 延遲問題:在大規模向量集上,搜索延遲通常為毫秒級,而專用向量數據庫可達微秒級
  • 資源消耗較高:向量操作可能需要更多的內存和計算資源
向量功能相對有限
  • 算法支持有限:支持的向量索引和搜索算法相對較少,主要是 HNSW
  • 缺乏專業優化:缺少針對向量操作的專門優化,如 GPU 加速
  • 向量維度限制:在處理超高維向量時可能存在效率問題
學習和配置復雜性
  • 配置復雜:需要正確配置索引映射、分片策略等
  • 調優難度:優化 ES 性能需要專業知識和經驗
  • 維護成本:需要定期維護和監控集群狀態
存儲效率問題
  • 存儲開銷:存儲向量數據可能需要更多空間
  • 索引大小:包含向量的索引通常比純文本索引大得多

三、Elasticsearch 向量存儲與檢索原理

1. 向量數據存儲原理

Elasticsearch 使用?dense_vector?字段類型來存儲向量數據,其工作原理如下:

基本存儲結構
  • 文檔結構:向量被存儲為文檔的一個字段,與其他字段(如文本、數字等)一起構成完整的文檔。
  • 向量表示:向量以浮點數數組的形式存儲,每個數組元素對應向量的一個維度。
  • 索引映射:通過索引映射定義向量字段的屬性,包括維度大小、索引方式和相似度計算方法。

存儲過程簡述
  1. 1.?向量生成:通過嵌入模型將文本、圖像等內容轉換為固定維度的向量。

  2. 2.?文檔創建:創建包含向量字段的文檔,將向量數據與其他元數據一起存儲。

  3. 3.?分片分配:ES 將文檔分配到不同的分片中,每個分片可以位于不同的節點上。

  4. 4.?磁盤存儲:向量數據最終以 Lucene 索引格式存儲在磁盤上,同時部分熱數據會緩存在內存中。

2. 向量檢索原理

Elasticsearch 主要使用 HNSW(Hierarchical Navigable Small World)算法進行向量檢索,這是一種近似最近鄰(ANN)搜索算法:

HNSW 算法簡介
  • 多層圖結構:HNSW 構建一個多層的圖結構,頂層包含少量節點,底層包含所有節點。
  • 導航原理:搜索從頂層開始,通過"貪心"策略快速找到大致方向,然后在下層進行更精細的搜索。
  • 近似搜索:通過犧牲一定的精確度來換取顯著的性能提升。

檢索過程
  1. 1.?查詢向量生成:將用戶查詢轉換為向量表示。

  2. 2.?分片搜索:在每個相關分片上執行向量搜索。

  3. 3.?相似度計算:根據配置的相似度方法(余弦、點積或 L2 范數)計算查詢向量與索引向量的相似度。

  4. 4.?結果合并:將各分片的搜索結果合并,并按相似度排序。

  5. 5.?返回結果:返回最相似的文檔作為搜索結果。

性能優化參數
  • ef_construction:構建索引時的精度參數,值越大索引質量越高但構建越慢。
  • ef_search:搜索時的精度參數,值越大搜索結果越精確但速度越慢。
  • m:每個節點的最大連接數,影響圖的連通性和搜索效率。

3. 多模態向量存儲支持

Elasticsearch 不僅可以存儲文本向量,還可以存儲來自圖片、音頻和視頻等多模態數據的向量表示:

圖像向量存儲
  • 實現原理:使用圖像嵌入模型(如 ResNet、ViT 等)將圖像轉換為向量表示。
  • 存儲方式:與文本向量相同,使用?dense_vector?字段存儲圖像向量。
  • 應用場景:圖像相似度搜索、以圖搜圖、視覺內容檢索。

音頻向量存儲
  • 實現原理:使用音頻嵌入模型(如 Wav2Vec、CLAP 等)將音頻轉換為向量表示。
  • 存儲方式:同樣使用?dense_vector?字段,維度根據音頻嵌入模型而定。
  • 應用場景:音樂推薦、語音搜索、音頻內容分類。

視頻向量存儲
  • 實現原理:可以通過兩種方式處理:
    1. 將視頻分解為關鍵幀,然后使用圖像嵌入模型處理每個關鍵幀。
    2. 使用專門的視頻嵌入模型(如 Video Transformers)直接生成視頻向量。
  • 存儲方式:可以存儲單個視頻的整體向量,或者存儲多個關鍵幀的向量序列。
  • 應用場景:視頻內容搜索、相似視頻推薦、視頻分類。

多模態向量存儲的簡單示例
# 圖像向量存儲示例
from?PIL?import?Image
from?transformers?import?AutoFeatureExtractor, AutoModel
import?torch# 加載圖像嵌入模型
image_model = AutoModel.from_pretrained("openai/clip-vit-base-patch32")
feature_extractor = AutoFeatureExtractor.from_pretrained("openai/clip-vit-base-patch32")# 處理圖像
image = Image.open("example.jpg")
inputs = feature_extractor(images=image, return_tensors="pt")
with?torch.no_grad():image_features = image_model.get_image_features(**inputs)
image_vector = image_features[0].tolist()# 存儲到Elasticsearch
doc = {"title":?"示例圖片","description":?"這是一張示例圖片","image_path":?"example.jpg","image_vector": image_vector ?# 使用dense_vector字段存儲
}es.index(index="image-vectors", document=doc)

四、Elasticsearch 與其他向量存儲解決方案的對比

1. 各向量存儲解決方案綜合對比

特性ElasticsearchPGVector (PostgreSQL)Redis VectorMongoDB AtlasFAISSMilvusPineconeQdrantChroma
架構類型分布式搜索引擎關系型數據庫擴展內存數據庫擴展文檔數據庫擴展庫/嵌入式分布式向量數據庫托管向量數據庫向量數據庫嵌入式向量數據庫
部署模式自托管/云服務自托管/云服務自托管/云服務自托管/云服務嵌入式自托管/云服務僅云服務自托管/云服務嵌入式/自托管
向量索引算法HNSWHNSW, IVFHNSWHNSWHNSW, IVF, PQ 等多種HNSW, IVF, FLAT 等多種HNSW 變體HNSWHNSW
查詢性能毫秒級毫秒級亞毫秒級毫秒級微秒-毫秒級微秒-毫秒級毫秒級毫秒級毫秒級
擴展性優秀有限有限優秀有限優秀優秀良好有限
混合查詢原生支持支持 SQL+向量有限支持支持文檔+向量不支持支持有限支持支持支持
元數據過濾強大強大(SQL)有限強大(文檔查詢)有限支持支持支持支持
GPU 加速不支持不支持不支持不支持支持支持內部支持不支持不支持
存儲容量TB-PB 級TB 級GB-TB 級TB-PB 級受內存限制TB 級TB 級TB 級GB-TB 級
全文搜索優秀基礎良好基礎不支持有限不支持有限有限
相似度算法余弦、點積、L2 范數余弦、L2 范數余弦、L2 范數余弦、點積、歐幾里得多種(余弦、內積、L2 等)多種(余弦、內積、L2 等)余弦、點積余弦、點積、歐幾里得余弦
事務支持有限完整 ACID有限文檔級事務不支持有限不支持不支持不支持
易用性中等高(SQL 熟悉度)高(MongoDB 用戶)復雜中等簡單簡單簡單
維護成本中等中等低(嵌入式)低(托管)
社區支持強大強大強大強大活躍活躍有限活躍活躍
成本開源,自托管開源,自托管開源+商業版開源+商業版開源,免費開源+商業版商業版,按量付費開源+商業版開源,免費
適用場景混合搜索結構化數據+向量高性能、低延遲半結構化數據+向量高性能向量搜索大規模向量管理簡單部署、高可用中小規模應用快速原型開發

2. 不同相似度計算方法對比

相似度方法數學表達式值域適用場景特點支持的存儲系統
余弦相似度cos(θ) = A·B / (‖A‖·‖B‖)[-1, 1]文本語義搜索不受向量長度影響,只考慮方向全部
點積A·B = ∑(A_i × B_i)無限制推薦系統考慮向量長度和方向,通常需要歸一化ES, MongoDB, FAISS, Milvus, Pinecone, Qdrant
歐幾里得距離‖A-B‖ = √(∑(A_i - B_i)2)[0, ∞)圖像特征、地理位置值越小表示越相似,需要轉換為相似度ES, PGVector, Redis, MongoDB, FAISS, Milvus, Qdrant
曼哈頓距離∑|A_i - B_i|[0, ∞)網格空間、特征差異計算簡單,對異常值不敏感FAISS, Milvus
杰卡德相似度J(A,B) = |A∩B| / |A∪B|[0, 1]集合比較、文檔相似度適用于二進制特征或集合ES(腳本), PGVector(SQL)
漢明距離H(A,B) = ∑(A_i ⊕ B_i)[0, dim]二進制特征、錯誤檢測計算二進制向量中不同位的數量FAISS

3. 適用場景對比總結

解決方案最適合場景不適合場景
Elasticsearch需要混合搜索(文本+向量)、已有 ES 基礎設施、需要復雜文本處理超大規模純向量搜索、極低延遲要求、GPU 加速需求
PGVector已有 PostgreSQL 基礎設施、需要事務支持、結構化數據+向量超大規模向量集、分布式部署需求
Redis Vector超低延遲需求、緩存層向量搜索、臨時數據持久化要求高、復雜查詢、大規模數據
MongoDB Atlas半結構化數據、文檔+向量混合、MongoDB 用戶復雜文本分析、極高性能要求
FAISS純向量搜索、算法研究、GPU 加速、嵌入式應用需要持久化、分布式部署、元數據過濾
Milvus大規模向量管理、需要豐富索引算法、混合查詢簡單應用、資源受限環境
Pinecone快速部署、無運維需求、按需擴展自托管需求、成本敏感、復雜查詢
Qdrant中小規模應用、需要良好元數據過濾、開源需求超大規模、GPU 加速需求
Chroma快速原型開發、簡單應用、本地部署企業級應用、大規模數據、高并發

五、基于 Elasticsearch 的 RAG 實現方案

1. 系統架構設計

基于 Elasticsearch 實現 RAG 系統的整體架構如下:

  1. 1.?數據處理層:負責文檔的收集、清洗、分塊和向量化

  2. 2.?存儲層:使用 Elasticsearch 存儲文本內容和向量表示

  3. 3.?檢索層:實現混合檢索策略,結合文本和向量搜索

  4. 4.?生成層:集成 Deepseek V3 或 Qwen2.5 大模型,基于檢索結果生成回答

  5. 5.?應用層:提供用戶界面和 API 接口

2. 實現步驟詳解

2.1 環境準備

首先,我們需要安裝必要的依賴:

# 安裝必要的庫
pip install elasticsearch langchain langchain-elasticsearch langchain-community langchain-openai
pip install deepseek-ai qwen-api
2.2 Elasticsearch 配置

設置 Elasticsearch 集群并創建適合 RAG 的索引,展示不同相似度計算方法:

from?elasticsearch?import?Elasticsearch# 連接到Elasticsearch
es = Elasticsearch(hosts=["http://localhost:9200"],basic_auth=("user",?"password"), ?# 如果有認證request_timeout=60
)# 創建索引映射,使用cosine相似度
cosine_index_mapping = {"mappings": {"properties": {"title": {"type":?"text",?"analyzer":?"standard"},"content": {"type":?"text",?"analyzer":?"standard"},"source": {"type":?"keyword"},"content_vector": {"type":?"dense_vector","dims":?1536, ?# 根據嵌入模型調整維度"index":?True,"similarity":?"cosine"??# 余弦相似度}}},"settings": {"number_of_shards":?2,"number_of_replicas":?1}
}# 創建使用余弦相似度的索引
es.indices.create(index="rag-knowledge-cosine", body=cosine_index_mapping)# 創建索引映射,使用dot_product相似度
dot_product_index_mapping = {"mappings": {"properties": {"title": {"type":?"text",?"analyzer":?"standard"},"content": {"type":?"text",?"analyzer":?"standard"},"source": {"type":?"keyword"},"content_vector": {"type":?"dense_vector","dims":?1536,"index":?True,"similarity":?"dot_product"??# 點積相似度}}},"settings": {"number_of_shards":?2,"number_of_replicas":?1}
}# 創建使用點積相似度的索引
es.indices.create(index="rag-knowledge-dot-product", body=dot_product_index_mapping)# 創建索引映射,使用l2_norm相似度
l2_norm_index_mapping = {"mappings": {"properties": {"title": {"type":?"text",?"analyzer":?"standard"},"content": {"type":?"text",?"analyzer":?"standard"},"source": {"type":?"keyword"},"content_vector": {"type":?"dense_vector","dims":?1536,"index":?True,"similarity":?"l2_norm"??# 歐幾里得距離(L2范數)}}},"settings": {"number_of_shards":?2,"number_of_replicas":?1}
}# 創建使用L2范數相似度的索引
es.indices.create(index="rag-knowledge-l2-norm", body=l2_norm_index_mapping)

2.3 文檔處理與索引

實現文檔的處理、分塊和向量化,并分別存儲到不同相似度計算方法的索引中:

import?os
from?langchain_community.document_loaders?import?DirectoryLoader, TextLoader
from?langchain.text_splitter?import?RecursiveCharacterTextSplitter
from?langchain_openai?import?OpenAIEmbeddings ?# 也可以使用其他嵌入模型# 加載文檔
loader = DirectoryLoader("./documents", glob="**/*.txt", loader_cls=TextLoader)
documents = loader.load()# 文檔分塊
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200,length_function=len,
)
chunks = text_splitter.split_documents(documents)# 初始化嵌入模型
embeddings = OpenAIEmbeddings() ?# 可替換為其他嵌入模型# 處理文檔并索引到不同的Elasticsearch索引
for?i, chunk?in?enumerate(chunks):# 生成向量嵌入vector = embeddings.embed_query(chunk.page_content)# 準備索引文檔doc = {"title":?f"Chunk?{i}?from?{chunk.metadata.get('source',?'unknown')}","content": chunk.page_content,"source": chunk.metadata.get("source",?"unknown"),"content_vector": vector}# 索引文檔到不同相似度計算方法的索引es.index(index="rag-knowledge-cosine", document=doc)# 對于dot_product,通常需要歸一化向量es.index(index="rag-knowledge-dot-product", document=doc)# 對于l2_norm,直接使用原始向量es.index(index="rag-knowledge-l2-norm", document=doc)# 刷新索引
es.indices.refresh(index="rag-knowledge-cosine")
es.indices.refresh(index="rag-knowledge-dot-product")
es.indices.refresh(index="rag-knowledge-l2-norm")

2.4 使用 LangChain 與 Elasticsearch 實現 RAG

下面是使用 LangChain 與 Elasticsearch 結合實現 RAG 的代碼,支持不同相似度計算方法:

from?langchain_elasticsearch?import?ElasticsearchStore
from?langchain.chains?import?RetrievalQA
from?langchain.prompts?import?PromptTemplate
from?langchain_core.runnables?import?RunnablePassthrough
from?langchain_core.output_parsers?import?StrOutputParser
from?langchain.schema?import?Document# 初始化不同相似度計算方法的Elasticsearch向量存儲
es_store_cosine = ElasticsearchStore(es_url="http://localhost:9200",index_name="rag-knowledge-cosine",embedding=embeddings,es_user="user", ?# 如果有認證es_password="password"??# 如果有認證
)es_store_dot_product = ElasticsearchStore(es_url="http://localhost:9200",index_name="rag-knowledge-dot-product",embedding=embeddings,es_user="user",es_password="password"
)es_store_l2_norm = ElasticsearchStore(es_url="http://localhost:9200",index_name="rag-knowledge-l2-norm",embedding=embeddings,es_user="user",es_password="password"
)# 創建不同相似度計算方法的檢索器
retriever_cosine = es_store_cosine.as_retriever(search_type="similarity",search_kwargs={"k":?5}
)retriever_dot_product = es_store_dot_product.as_retriever(search_type="similarity",search_kwargs={"k":?5}
)retriever_l2_norm = es_store_l2_norm.as_retriever(search_type="similarity",search_kwargs={"k":?5}
)# 創建多相似度混合檢索器
def?multi_similarity_retriever(query, top_k=5):# 從三種不同相似度方法獲取結果cosine_docs = retriever_cosine.get_relevant_documents(query)dot_product_docs = retriever_dot_product.get_relevant_documents(query)l2_norm_docs = retriever_l2_norm.get_relevant_documents(query)# 合并結果all_docs = cosine_docs + dot_product_docs + l2_norm_docs# 去重unique_docs =?list({doc.page_content: doc?for?doc?in?all_docs}.values())# 限制返回數量return?unique_docs[:top_k]# 定義提示模板
template =?"""
你是一個專業的AI助手。請基于以下提供的上下文信息,回答用戶的問題。
如果你無法從上下文中找到答案,請直接說"我無法從提供的信息中找到答案",不要編造信息。上下文信息:
{context}用戶問題: {question}回答:
"""prompt = PromptTemplate(template=template,input_variables=["context",?"question"]
)# 格式化文檔函數
def?format_docs(docs):return?"\n\n".join([doc.page_content?for?doc?in?docs])

2.5 集成 Deepseek V3 模型

from?langchain_deepseek?import?DeepseekChat# 初始化Deepseek模型
deepseek_llm = DeepseekChat(model_name="deepseek-ai/deepseek-v3",api_key="your_api_key",temperature=0.1
)# 構建RAG鏈(使用余弦相似度)
deepseek_rag_chain_cosine = ({"context": retriever_cosine | format_docs,?"question": RunnablePassthrough()}| prompt| deepseek_llm| StrOutputParser()
)# 構建RAG鏈(使用點積相似度)
deepseek_rag_chain_dot_product = ({"context": retriever_dot_product | format_docs,?"question": RunnablePassthrough()}| prompt| deepseek_llm| StrOutputParser()
)# 構建RAG鏈(使用L2范數相似度)
deepseek_rag_chain_l2_norm = ({"context": retriever_l2_norm | format_docs,?"question": RunnablePassthrough()}| prompt| deepseek_llm| StrOutputParser()
)# 構建RAG鏈(使用多相似度混合檢索)
def?answer_with_deepseek_multi_similarity(question):# 獲取多相似度混合檢索結果docs = multi_similarity_retriever(question)context = format_docs(docs)# 構建RAG鏈chain = ({"context": RunnablePassthrough(),?"question": RunnablePassthrough()}| prompt| deepseek_llm| StrOutputParser())# 生成回答return?chain.invoke({"context": context,?"question": question})# 示例
response = answer_with_deepseek_multi_similarity("什么是向量數據庫?")
print(response)

2.6 集成 Qwen2.5 模型

from?langchain_community.llms?import?QianfanLLMEndpoint# 初始化Qwen模型
qwen_llm = QianfanLLMEndpoint(model_name="qwen-2.5",api_key="your_api_key",secret_key="your_secret_key",temperature=0.1
)# 構建RAG鏈(使用余弦相似度)
qwen_rag_chain_cosine = ({"context": retriever_cosine | format_docs,?"question": RunnablePassthrough()}| prompt| qwen_llm| StrOutputParser()
)# 構建RAG鏈(使用點積相似度)
qwen_rag_chain_dot_product = ({"context": retriever_dot_product | format_docs,?"question": RunnablePassthrough()}| prompt| qwen_llm| StrOutputParser()
)# 構建RAG鏈(使用L2范數相似度)
qwen_rag_chain_l2_norm = ({"context": retriever_l2_norm | format_docs,?"question": RunnablePassthrough()}| prompt| qwen_llm| StrOutputParser()
)# 構建RAG鏈(使用多相似度混合檢索)
def?answer_with_qwen_multi_similarity(question):# 獲取多相似度混合檢索結果docs = multi_similarity_retriever(question)context = format_docs(docs)# 構建RAG鏈chain = ({"context": RunnablePassthrough(),?"question": RunnablePassthrough()}| prompt| qwen_llm| StrOutputParser())# 生成回答return?chain.invoke({"context": context,?"question": question})# 示例
response = answer_with_qwen_multi_similarity("Elasticsearch的主要優勢是什么?")
print(response)

3. 高級功能實現

3.1 實現混合搜索策略
def?enhanced_hybrid_search(query, es_client, index_name, embedding_model, similarity_type="cosine"):# 生成查詢向量query_vector = embedding_model.embed_query(query)# 根據不同相似度類型構建腳本if?similarity_type ==?"cosine":similarity_script =?"cosineSimilarity(params.query_vector, 'content_vector') + 1.0"elif?similarity_type ==?"dot_product":similarity_script =?"dotProduct(params.query_vector, 'content_vector')"elif?similarity_type ==?"l2_norm":# 對于L2范數,較小的值表示更相似,所以我們使用負值或倒數similarity_script =?"1 / (1 + l2Norm(params.query_vector, 'content_vector'))"else:raise?ValueError(f"不支持的相似度類型:?{similarity_type}")# 構建混合查詢hybrid_query = {"query": {"bool": {"should": [# 向量搜索部分{"script_score": {"query": {"match_all": {}},"script": {"source": similarity_script,"params": {"query_vector": query_vector}}}},# 文本搜索部分{"match": {"content": {"query": query,"boost":?0.5??# 調整文本搜索的權重}}}]}},"size":?5}# 執行搜索response = es_client.search(index=index_name, body=hybrid_query)# 處理結果results = []for?hit?in?response["hits"]["hits"]:results.append({"score": hit["_score"],"title": hit["_source"]["title"],"content": hit["_source"]["content"],"source": hit["_source"]["source"]})return?results

3.2 實現自適應相似度選擇
def?adaptive_similarity_search(query, es_client, embedding_model):# 分析查詢特征,決定使用哪種相似度方法query_length =?len(query.split())# 短查詢(1-3個詞)可能更適合關鍵詞搜索if?query_length <=?3:# 使用混合搜索,但給文本搜索更高權重results = enhanced_hybrid_search(query,?es_client,?"rag-knowledge-cosine",?embedding_model,similarity_type="cosine")# 中等長度查詢(4-10個詞)elif?query_length <=?10:# 使用余弦相似度,適合一般語義搜索results = enhanced_hybrid_search(query,?es_client,?"rag-knowledge-cosine",?embedding_model,similarity_type="cosine")# 長查詢(>10個詞)else:# 對于長查詢,點積可能更適合捕捉更多語義信息results = enhanced_hybrid_search(query,?es_client,?"rag-knowledge-dot-product",?embedding_model,similarity_type="dot_product")return?results

3.3 實現多步檢索策略
def?multi_step_retrieval(query, es_client, embedding_model):# 第一步:使用文本搜索獲取初步結果text_query = {"query": {"match": {"content": query}},"size":?20}text_response = es_client.search(index="rag-knowledge-cosine", body=text_query)# 提取文檔ID和內容candidate_docs = []for?hit?in?text_response["hits"]["hits"]:candidate_docs.append({"id": hit["_id"],"content": hit["_source"]["content"]})# 如果文本搜索沒有足夠結果,添加向量搜索if?len(candidate_docs) <?10:# 生成查詢向量query_vector = embedding_model.embed_query(query)# 向量搜索vector_query = {"query": {"script_score": {"query": {"match_all": {}},"script": {"source":?"cosineSimilarity(params.query_vector, 'content_vector') + 1.0","params": {"query_vector": query_vector}}}},"size":?20?-?len(candidate_docs)}vector_response = es_client.search(index="rag-knowledge-cosine", body=vector_query)# 添加到候選文檔for?hit?in?vector_response["hits"]["hits"]:# 避免重復if?not?any(doc["id"] == hit["_id"]?for?doc?in?candidate_docs):candidate_docs.append({"id": hit["_id"],"content": hit["_source"]["content"]})# 第二步:對候選文檔進行重新排序# 生成查詢向量query_vector = embedding_model.embed_query(query)# 為每個候選文檔計算相似度分數for?doc?in?candidate_docs:# 生成文檔向量doc_vector = embedding_model.embed_query(doc["content"])# 計算余弦相似度similarity = cosine_similarity([query_vector],[doc_vector])[0][0]doc["similarity_score"] = similarity# 按相似度排序ranked_docs =?sorted(candidate_docs, key=lambda?x: x["similarity_score"], reverse=True)# 返回前5個最相關文檔return?ranked_docs[:5]

3.4 實現查詢擴展和改寫
def?query_expansion(original_query, llm):# 使用大模型擴展查詢expansion_prompt =?f"""請基于以下原始查詢,生成3個不同的擴展查詢,以便更全面地搜索相關信息。每個擴展查詢應該保留原始查詢的核心意圖,但可以添加相關術語、同義詞或上下文。原始查詢:?{original_query}擴展查詢(每行一個):"""# 獲取擴展查詢response = llm.invoke(expansion_prompt)# 解析響應expanded_queries = [q.strip()?for?q?in?response.split("\n")?if?q.strip()]# 過濾掉可能的空行或無關行expanded_queries = [q?for?q?in?expanded_queries?if?len(q) >?5]# 確保至少有一個查詢(原始查詢)if?not?expanded_queries:expanded_queries = [original_query]else:# 添加原始查詢expanded_queries.append(original_query)return?expanded_queriesdef?multi_query_retrieval(original_query, es_client, embedding_model, llm):# 擴展查詢expanded_queries = query_expansion(original_query, llm)# 對每個擴展查詢執行搜索all_results = []for?query?in?expanded_queries:results = enhanced_hybrid_search(query,?es_client,?"rag-knowledge-cosine",?embedding_model)all_results.extend(results)# 去重unique_results = []seen_contents =?set()for?result?in?all_results:if?result["content"]?not?in?seen_contents:unique_results.append(result)seen_contents.add(result["content"])# 重新排序(可以基于原始查詢的相似度)query_vector = embedding_model.embed_query(original_query)# 為每個結果計算與原始查詢的相似度for?result?in?unique_results:# 假設我們可以從ES獲取內容的向量content_vector_query = {"query": {"term": {"_id": result["id"]}},"_source": ["content_vector"]}vector_response = es_client.search(index="rag-knowledge-cosine", body=content_vector_query)content_vector = vector_response["hits"]["hits"][0]["_source"]["content_vector"]# 計算相似度similarity = cosine_similarity([query_vector],[content_vector])[0][0]result["final_score"] = similarity# 按最終分數排序ranked_results =?sorted(unique_results, key=lambda?x: x["final_score"], reverse=True)# 返回前5個最相關結果return?ranked_results[:5]

六、總結與結論

1. Elasticsearch 作為 RAG 向量數據庫的優勢總結

  1. 1.?全棧解決方案:Elasticsearch 提供了從數據索引到檢索的完整解決方案,無需集成多個系統。

  2. 2.?混合檢索能力:結合傳統文本搜索和向量搜索的能力是其最大優勢,能夠顯著提高檢索質量。

  3. 3.?成熟的生態系統:作為成熟的搜索引擎,擁有豐富的文檔、工具和社區支持。

  4. 4.?多模態支持:能夠存儲和檢索文本、圖像、音頻和視頻的向量表示,支持多模態 RAG 應用。

  5. 5.?靈活的相似度計算:支持多種相似度計算方法(余弦、點積、L2 范數),適應不同應用場景。

2. 實施建議

  1. 1.?選擇合適的相似度計算方法:

    • 文本語義搜索:優先使用余弦相似度
    • 推薦系統:考慮使用點積
    • 圖像或地理位置搜索:考慮使用 L2 范數
  2. 2.?優化索引配置:

    • 根據數據量和查詢頻率調整分片數量
    • 為頻繁查詢的索引配置足夠的副本
    • 合理設置 HNSW 參數,平衡搜索精度和性能
  3. 3.?實現混合檢索策略:

    • 結合向量搜索和關鍵詞搜索
    • 根據查詢特征動態調整搜索策略
    • 考慮使用查詢擴展和多步檢索提高召回率
  4. 4.?性能優化:

    • 對于大規模部署,考慮使用專用節點
    • 監控和調整 JVM 堆大小
    • 定期優化索引

3. 未來發展方向

  1. 1.?與專用向量數據庫的集成:

    • 考慮 Elasticsearch 與專用向量數據庫(如 FAISS、Milvus)的混合架構
    • 利用 ES 的文本處理和混合查詢能力,結合專用向量數據庫的高性能向量搜索
  2. 2.?知識圖譜增強:

    • 將向量搜索與知識圖譜結合,實現 GraphRAG
    • 利用實體關系增強檢索結果的相關性和可解釋性
  3. 3.?多模態 RAG 應用:

    • 擴展到圖像、音頻和視頻內容的檢索增強生成
    • 實現跨模態檢索,如以文搜圖、以圖搜文
  4. 4.?自適應檢索策略:

    • 開發能夠根據查詢特征和上下文自動選擇最佳檢索策略的系統
    • 利用強化學習優化檢索參數

4. 結論

Elasticsearch 作為 RAG 系統的向量數據庫具有顯著優勢,特別是在需要混合檢索、多模態支持和成熟生態系統的場景下。雖然在純向量搜索性能上可能不如專用向量數據庫,但其全面的功能和靈活性使其成為構建企業級 RAG 系統的有力選擇。

通過合理配置和優化,結合本報告提供的實現方案,可以充分發揮 Elasticsearch 在 RAG 系統中的潛力,為大模型應用提供高質量的知識檢索支持。

對于需要構建 RAG 系統的團隊,建議根據具體需求和現有技術棧選擇合適的向量存儲解決方案,Elasticsearch 特別適合已有 ES 基礎設施、需要混合檢索能力以及處理多模態數據的場景。

?


【大模型介紹電子書】

快速揭秘DeepSeek背后的AI工作原理

要獲取本書全文PDF內容,請在VX后臺留言:“AI大模型基礎” 或者 “大模型基礎” 就會獲得電子書的PDF。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72820.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72820.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72820.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

分享下web3j 常見用法

轉賬 fun sendEthTransaction(privateKey: String,toAddress: String,amount: BigDecimal) {//chainIdval chainId:Long 1//url 可以從https://chainlist.org/里面獲取可用節點//eth轉賬&#xff0c;bnb同理&#xff0c;但需發送到bnb對應節點val url "https://xxx"…

《真·滕王閣序》

《滕工閣序》 西二旗故地&#xff0c;后廠新府。 星分百度網易&#xff0c;地接騰訊阿里。 襟PRD而帶OKR&#xff0c;控需求以引撕逼。 物華天寶&#xff0c;龍光射工卡芯片&#xff1b;人杰地靈&#xff0c;徐孺坐產品經理之榻。 工位霧列&#xff0c;碼農星馳。 臺積電…

云盤搭建筆記

報錯問題&#xff1a; No input file specified. 偽靜態 location / {if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last;break;} } location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; break; } } 設…

如何打造安全穩定的亞馬遜采購測評自養號下單系統?

在當今的電商領域&#xff0c;亞馬遜作為全球領先的在線購物平臺&#xff0c;其商品種類繁多&#xff0c;用戶基數龐大&#xff0c;成為了眾多商家和消費者的首選。而對于一些需要進行商品測評或市場調研的用戶來說&#xff0c;擁有一個穩定、安全的亞馬遜賬號體系顯得尤為重要…

c語言數據結構 單循環鏈表設計(完整代碼)

單鏈表的增刪查改代碼&#xff1a; 1.創建結構體 // 結構體類型的創建 struct node {int data; // 數據域struct node *next; // 指針域 };2.創建節點&#xff0c;節點的存儲在malloc申請的空間內&#xff0c;也就是堆空間。 // 創建節點 struct node *create_node…

筆記本電腦關不了機是怎么回事 這有解決方法

在快節奏的現代生活中&#xff0c;筆記本電腦已成為我們工作、學習和娛樂的得力助手。在使用電腦的過程中&#xff0c;筆記本電腦突然關不了機了&#xff0c;怎么回事&#xff1f;下面驅動人生就來講一講筆記本電腦不能正常關機的解決方法&#xff0c;有需要的可以來看看。 一、…

Pytest基礎使用

概述 Pytest是Python里的一個強大的測試框架,靈活易用,可以進行功能,自動化測試使用,可以與Requests,Selenium等進行結合使用,同時可以生成Html的報告。 一、Pytest的基本使用 在未指定Pytest的配置文件時,會對以下文件進行執行: test_*.py,如:test_1.py*_test.py…

服務的拆分數據的遷移

參考&#xff1a; 數據遷移調研

【動態規劃篇】91. 解碼方法

91. 解碼方法 題目鏈接&#xff1a; 91. 解碼方法 題目敘述&#xff1a; 一條包含字母 A-Z 的消息通過以下映射進行了 編碼 &#xff1a; “1” -> ‘A’ “2” -> ‘B’ … “25” -> ‘Y’ “26” -> ‘Z’ 然而&#xff0c;在解碼已編碼的消息時&#xff0c;你…

使用【docker】+【shell】腳本半自動化部署微服務項目

一.前言 以下是一個基于 ?Docker Shell腳本? 的半自動化部署方案&#xff0c;包含鏡像構建、容器管理、網絡配置和日志監控等核心功能&#xff0c;適用于大多數Web應用或微服務項目。 二?.目錄結構 三.腳本代碼實現 1.?Shell腳本實現 (deploy.sh) #!/bin/bash# 設置顏…

每天一道算法題-兩數相加

給你兩個 非空 的鏈表&#xff0c;表示兩個非負的整數。它們每位數字都是按照 逆序 的方式存儲的&#xff0c;并且每個節點只能存儲 一位 數字。 請你將兩個數相加&#xff0c;并以相同形式返回一個表示和的鏈表。 你可以假設除了數字 0 之外&#xff0c;這兩個數都不會以 0 …

win10搭建opengl環境搭建并測試--輸出立方體球體和碗型并在球體上貼圖

參照本文檔可以完成環境搭建和測試&#xff0c;如果想要快速完成環境的搭建可以獲取本人的工程&#xff0c;包括所用到的工具鏈和測試工程源碼獲取&#xff08;非免費介意務下載&#xff09;&#xff1a;鏈接: https://pan.baidu.com/s/1H2ejbT7kLM9ore5MqyomgA 提取碼: 8s1b …

CIR-Net:用于 RGB-D 顯著性目標檢測的跨模態交互與優化(問題)

摘要 問題一&#xff1a;自模態注意力優化單元和跨模態加權優化單元什么意思&#xff1f; 1 優化中間件結構的作用 位置&#xff1a;位于編碼器和解碼器之間 輸入&#xff1a;編碼器提取的RGB特征&#xff0c;深度特征以及RGB-D特征。 輸出&#xff1a;經過優化的RGB&…

LS-NET-004-簡單二層環路解決(華為銳捷思科)

LS-NET-004-簡單二層環路解決&#xff08;華為銳捷思科&#xff09; 以下是為您準備的二層環路示意圖及解決方案&#xff0c;包含四大廠商配置對比&#xff1a; 一、Mermaid 二層環路示意圖 graph TD SW1 -->|Gi0/1| SW2 SW2 -->|Gi0/2| SW3 SW3 -->|Gi0/3| SW1 SW1…

【正點原子K210連載】第七十六章 音頻FFT實驗 摘自【正點原子】DNK210使用指南-CanMV版指南

第七十六章 音頻FFT實驗 本章將介紹CanMV下FFT的應用&#xff0c;通過將時域采集到的音頻數據通過FFT為頻域。通過本章的學習&#xff0c;讀者將學習到CanMV下控制FFT加速器進行FFT的使用。 本章分為如下幾個小節&#xff1a; 32.1 maix.FFT模塊介紹 32.2 硬件設計 32.3 程序設…

火絨終端安全管理系統V2.0——行為管理(軟件禁用+違規外聯)

火絨終端安全管理系統V2.0&#xff1a;行為管理策略分為軟件禁用和違規外聯兩部分&#xff0c;能夠管理終端用戶軟件的使用&#xff0c;以及終端用戶違規連接外部網絡的問題。 l 軟件禁用 軟件禁用策略可以選擇軟件名單的屬性、添加軟件名單以及設置發現終端使用禁用軟件時的…

FastJson:JSON JSONObject JSONArray詳解以及SimplePropertyPreFilter 的介紹

FastJson&#xff1a;JSON JSONObject JSONArray詳解以及SimplePropertyPreFilter 的介紹 FastJson是阿里巴巴開發的一款專門用于Java開發的包&#xff0c;實現Json對象&#xff0c;JavaBean對&#xff0c;Json字符串之間的轉換。 文章目錄 FastJson&#xff1a;JSON JSONObje…

DEFI幣生態重構加速,XBIT去中心化交易所引領DEX安全新范式

2025年3月18日&#xff0c;全球加密市場在監管與技術共振下迎來結構性變革。去中心化金融&#xff08;DeFi&#xff09;代幣DEFI幣因跨鏈流動性協議升級引發社區熱議&#xff0c;而幣應XBIT去中心化交易所&#xff08;以下簡稱XBIT&#xff09;憑借其鏈上透明驗證機制、無需下載…

解析漏洞總結

首先說下為什么要寫著篇文章&#xff0c;之前學習倒是學過&#xff0c;學完就忘啊&#xff0c;tmd iis 5.x/6.0 這個版本有兩種解析姿勢  一.兩種解析漏洞 1.目錄解析 2./xxx.asp/xx.jpg 簡單說一下是什么意思&#xff0c;這里是先在他服務器跟目錄創建一個名為 xxx.…

前端小食堂 | Day18 - 身份認證の八卦陣

&#x1f510; 今日秘術&#xff1a;JWT/OAuth2 攻防奧義 1. JWT 安全の六合陣法 // &#x1f6ab; 危險操作&#xff1a;未驗證簽名 const decodeUnsafe (token) > JSON.parse(atob(token.split(.)[1])); // ? 安全姿勢一&#xff1a;嚴格簽名驗證 import jwt fro…